基于vue的服务端渲染框架Nuxt介绍与实践

Nuxt是什么

Nuxt.js 是一个基于 Vue.js 的通用应用框架,通过对客户端/服务端基础架构的抽象组织。
2016年10月发布,运行环境基于vue+webpack+babel,
预置了使用vue开发服务端渲染应用所需的基础配置,
并且集成了vue-router、vuex、vue-meta等vue生太圈常用的组件和框架,
使用webpack、vue-loader、babel-loader来处理自动化构建工作。

Nuxt用来做什么

vue框架由于是单页面SPA应用,故存在SEO、首屏渲染、路由切换时渲染慢,用户体验略差等问题。
所以基于vue的服务端渲染方案应运而生。

框架特性

基于vue.js,学习成本低
内置代码分层
服务端渲染
本地开发热更新
SEO及mete头标签管理
nuxt官网

开发过程及配置

1.安装
配置好node环境和npm以后,通过vue init nuxt/express **脚手架工具生成默认文件。
npm i && npm run dev后打开localhost:3000可看到官方提供的示例。
2 目录介绍
目前所用为1.4版本,所生成的目录如下:

  • pages:页面组件,Nuxt会根据结构生成对应的路由
  • componets:公共组件
  • layouts:宿主页面模板组件,可以让不同的页面使用不同的布局
  • assets: 用于webpack打包的静态资源
  • middleware:中间件,首屏加载和路由跳转前均会执行对应中间件,可以全局配置,也可以部分组件配置
  • plugins:插件,SPA中常用的三方组件(如axios、utils),或者引入自己编写的三方库
  • store:内置了vuex,在store目录下增加index.js,返回一个Vue.Store实例即可

3 配置
nuxt.config示例
nuxt以约束文件和nuxt.config.js的方式管理程序和组件之间的关系
nuxt.config.js对应用的扩展主要如下:

  • build:webpack配置,可以对默认的webpack配置进行扩展
  • cahe:配置组件缓存
  • css:全局css样式
  • dev or env:自定义环境变量,对应webpack.config.js中的变量
  • head:vue-mete配置,在nuxt.config.js中会应用于全局,在组件中调用则只会应用于组件
  • loading:nuxt内置的进度条组件,可自定义或引用三方组件
  • performance: nodejs服务器性能配置
  • plugins: 划重点,经常用,并且很重要。
    plugins会在Nuxt.js 应用实例生成之前加载,如 axios、filter。
    支持数组或者对象,ssr属性默认为ture。
    但是有部分组件依赖window或者docuemnt对象,须设置为false,即不打包到服务端
    脚本中,例如loadsh,依赖window对象,需如下配置

    plugins: [
             {src: '~plugins/lodash.js', ssr: false}
         ],

常用API

1.asyncData
页面组件加载前调用,可获取当前上下文对象,异步请求的数据会返回给当前组件的data。
注意:此时vue实例还未生成,拿不到this。

2.middleware
中间件,每次路由切换时调用,例如做登录判断

export default function ({ store, redirect }) {
          // If the user is not authenticated
          if (!store.state.authenticated) {
            return redirect('/login')
          }
        }

3.head
修改title和Meta标签
4.vendor
nuxt.config.js的vendor属性,可避免重复打包

开发中常见问题

1.资源引用
全局资源文件在nuxt.config.js中配置

module.exports = {
  head: {
    script: [
      { src: '                https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' }
    ],
    link: [
      { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?            family=Roboto' }
    ]
  }
}
局部配置
  
  ```
  <script>
    export default {
      head: {
      script: [
      {       src:'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' }
    ],
    link: [
  { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto'             }
    ]
        }
    }
  </script>
  ```

2.webpack配置扩展

module.exports = {
  build: {
     extend (config, { isDev, isClient }) {
       // ...
     }
  }
}

3.window/Document未定义
只兼容客户端的组件被打包进了服务端脚本中,单独抽出后,放后plugins中,配置时设置ssr为false。组件内引用时,通过process.BROWSER_BUILD判断导入

if (process.BROWSER_BUILD) {
      require('external_library')
    }

4.UI组件选择
目前支持服务端渲染的UI组件不是很多,已尝试过的有PC端element-ui,移动端vux,
详细配置见vux-plugins
和同目录下的vux-components.js

使用element-ui

vender:[
   'element-ui'
 ],
 babel:{
   "plugins": [["component", [
 {
   "libraryName": "element-ui",
   "styleLibraryName": "theme-default"
 },
 'transform-async-to-generator',
 'transform-runtime'
   ]]],
      comments: true
 },
 plugins: [
 { src: '~plugins/element-ui', ssr: true }
 ],
 css: [
 ]
  
~plugins/element-ui.js

      import Vue from 'vue'
      import { Button } from 'element-ui'
      Vue.component(Button.name, Button)

5.rem引入
将rem.js放入pluins中,在nuxt.config中配置ssr为false即可

6.部署
pm2提供了比较好的一套方案。默认服务器有node pm2 git 环境
进入项目目录后执行pm2 deploy production

ecosystem.config.js配置如下

deploy: {
       production: {
           user: '仓库用户名',
           host: '仓库地址',
           ref: 'origin/master 分支名称',
           repo: 'https://***.git 项目git地址',
           path: '/var/www/production 打包后代码目录',
           'post-setup': 'git pull origin develop && ls -la',
           'post-deploy': 'npm install && npm run build && pm2 reload    
            ecosystem.config.js --env production'
           },
       }

项目代码 代码地址,有疑问可以提issue。

相关推荐