vue 服务器端衬着 nuxt.js初探

开首照样来一段空话: 年关快要,给人人拜个从前,愿人人年会都能抽大奖,来年行大运。

空话不多说,直接进正文

项目环境:

前端vue项目, 须要将新增的几个路由页面做seo处置惩罚。

在调研 插件 prerender-spa-plugin后,发明没法满足 vuex 以及 plugins 等要求时,坚决选用了 nuxt.js做服务器衬着。

下面是在项目中整顿的 文档 和 题目

nuxt.js 是一个基于 Vue.js 的通用运用框架


它预设了应用 Vue.js 开辟 服务端衬着(SSR, Server Side Render) 的运用所须要的种种设置,同时也可以一键天生静态站点。
值得一提的是,nuxt是基于node.js的,后端假如是其他言语时,是不是考虑到再加一层node.js的合理性

链接地点: https://zh.nuxtjs.org/guide/installation

应用npx脚手架建立项目

链接地点: https://zh.nuxtjs.org/guide/installation

会供应以下选项

  1. 在集成的服务器端框架之间举行挑选:   Express / Koa ...

  2. 挑选您喜好的UI框架:   Bootstrap /  Element UI ...

  3. 挑选你想要的Nuxt情势  (Universal or SPA)    平常范例 / 单页运用

  4. 增添 axios module 以轻松地将HTTP要求发送到您的运用程序中。

  5. 增添 EsLint 以在保存时代码范例和毛病检查您的代码。

  6. 增添 Prettier 以在保存时格式化/美化您的代码。

注重:
      1. 假如项目自带分支等git信息时, 须要将npx临盆的目次内里隐蔽的git 文件删除
              由于npx天生文件时,默以为master 分支,相似于 gitmodule 子分支性子
      
      2. 个中第3点,挑选 Universal 时 才会默许输出静态页,也就是可以seo的,当挑选spa时,则没法seo
              可修正 nuxt.config.js 中的设置项 mode: 'Universal' 来定义范例
              
              
              
              

启动项目

敕令: npm run dev 默许敕令

这时刻会报错,说未指定ip 什么的,

需设置项:

      nuxt.config.js 中

      server: {
        // port: '3000',     // 定义 输出端口 ,默以为3000 
        host:'0.0.0.0'      // 定义 输出 ip 
      },


      注重: 
      
      在server 目次中的index.js中 会读取 nuxt.config.js 中的设置项,当不存在时会赋值默许值

      const {
        host = process.env.HOST || '127.0.0.1',
        port = process.env.PORT || 3000   // 默许设置条件下,修正此处无效 依旧为3000端口
      } = nuxt.options.server

      页面上的注重点有:

      css 都默许加载到 页面上了;

      处置惩罚方式有2种

          1. 在 nuxt.config.js 文件 header 设置 link 外链这些大众款式 (下面有详细申明)

          2. 在 nuxt.config.js 文件 build 设置 中 自定义文件途径 以及hash值 (下面有详细申明)
          
          

项目目次构造

1. 资本目次 (assets)

        用于构造未编译的静态资本如 LESS、SASS 或 JavaScript。

2. 组件目次 (components)

        用于构造运用的 Vue.js 组件。Nuxt.js 不会扩大加强该目次下 Vue.js 组件,
          即这些组件不会像页面组件那样有 asyncData 要领的特征。

3. 规划目次 (layouts) 该目次名为Nuxt.js保存的,不可变动。

        用于构造运用的规划组件。 

4. 中间件目次 (middleware)

        目次用于寄存运用的中间件
        
            文件名的称号将成为中间件称号(middleware/auth.js将成为 auth 中间件)。
            一个中间件吸收 context 作为第一个参数:
        
        详细参考: https://zh.nuxtjs.org/guide/routing#中间件

5. 页面目次 (page) 该目次名为Nuxt.js保存的,不可变动。

        用于构造运用的路由及视图。Nuxt.js 框架读取该目次下一切的 .vue 文件并自动天生对应的路由设置。

        nuxt 会依据文件夹称号以及目次构造动态临盆 router, 无需分外设置。

6. 静态文件目次 (static)

        用于寄存运用的静态文件,此类文件不会被 Nuxt.js 挪用 Webpack 举行构建编译处置惩罚。 
        服务器启动的时刻,该目次下的文件会映照至运用的根途径 / 下。
        
        平常用于 安排大众css,以及 js 文件, 然则假如不想这些css和js走根目次的话,
        须要将这些css安排到 assets中,然后在 nuxt.config.js中 设置 build 选项 下面会详细申明

7. Store 目次

        用于构造运用的 Vuex 状况树 文件
        
        注重: 平常的spa 项目中抛出一个实例对象即可, store为
        
        export default new Vuex.Store({
          actions,
          getters,
        })
        
          这里则须要抛出一个 实例函数对象
        
          const store = () => {
            return new Vuex.Store({
              state,
              getters,
              mutations,
              actions
            })
          }
        
          export default store

8. nuxt.config.js 

      用于构造Nuxt.js 运用的个性化设置,以便掩盖默许设置

9. package.json

      省略...
      

别号

    ~ 或 @           // src目次
    
    ~~ 或 @@         // 根目次
    
    默许情况下,src目次和根目次雷同
    
    
    

页面间路由的跳转

    要在页面之间运用路由,发起运用<nuxt-link> 标签。
    
    js 中依然可以运用 $router.push 等要领
    

路由跳转时的页面间过渡结果

    Nuxt.js 默许运用的过渡结果称号为 page
    
    须要在 assets/目次下建立 main.css 增添全局款式
    
      .page-enter-active, .page-leave-active {
        transition: opacity .5s;
      }
      .page-enter, .page-leave-active {
        opacity: 0;
      }
    
    然后增添到 nuxt.config.js 文件中:
    
      module.exports = {
        css: [
          'assets/main.css'
        ],
        loading: { color: '#2152F3' },
      }
    
    更多过渡结果: https://zh.nuxtjs.org/guide/routing#过渡动效
    
    

头部信息 (Meta 标签 ,全局款式)

    nuxt.config.js 里定义运用所需的一切默许 meta 标签
    
    head: {
      meta: [
        { charset: 'utf-8' },
        { name: 'viewport', content: 'width=device-width, initial-scale=1' }
        { hid: 'description', name: 'description', content: '' }
      ],
      link: [   // 这里可以援用全局的款式,然则会默许走根目次
        { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' }
    
        { rel: 'stylesheet', href: '~/static/common.js' }    // 文件平常都放在static目次下
      ]
    }
    
    详细参考:https://zh.nuxtjs.org/api/configuration-head

异步数据 (asyncData要领,限于page页面组件,components中不实用)

    这里包含  asyncData钩子  /  fetch 钩子 / 。。。
    
    【fetch】 用于在衬着页眼前添补运用的状况树(store)数据, 与 asyncData 要领相似,差别的是它不会设置组件的数据
    
    【asyncData】 重要用于要求ajax 添补data中的数据
    
    每次加载之前被挪用。它可以在服务端或路由更新之前被挪用。
    
    asyncData ({ params }) {
      return axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
    
        // 赋值给页面 data中的数据
        return { title: res.data.title }
      })
    }
    
    或许变换为同步要求
    
    async asyncData() {
        let formData = {}
    
        let ajaxData = await axios({
          method: "post",
          url: url,
          data: qs.stringify(formData),
          retryDelay : 1000,
          withCredentials : true,
          responseType : 'json',
          timeout : 60000,
          'Content-Type' : 'application/x-www-form-urlencoded'
        })
    }
    
    注重增添 catch
    
    
    注重: 
      
      这个异步要求函数, 第一次实行环境为node环境中,也就是服务器端,后续革新页面则实行环境为client 客户端
    
      当地开辟时,假如在客户端直接要求完全途径时会常常碰到跨域题目,所以须要在 asyncData 中辨别环境变量
    
      process.env.VUE_ENV 辨别 是server 照样 client
    
      然后依据差别的环境设置差别的 url , 而且在 client时, 须要做服务器端代办要求,须要给url增添一层代办标识
    
      比方:client环境中
    
        url =  '/api' + '/get-user-info';
    
        nuxt.config.js 中
    
        /*
        ** 处置惩罚代办跨域题目
        */
        axios: {
          proxy: true,
          prefix: '/api',       // 增添要求标识
          credentials: true,
        },
        proxy: {
          '/api': {
            // 代办地点
            target: (process.env.NODE_ENV == 'production') ?'http://test.' : 'http://www.' ,
            changeOrigin: true,
            pathRewrite: {
              '^/api': ''           // 将标识 替换为 ‘’
            },
          },
        }
    
    
        毛病处置惩罚 : 
    
            context中供应了一个 error(params) 要领,你可以经由过程挪用该要领来显现毛病信息页面。
            params.statusCode 可用于指定服务端返回的要求状况码。
    
        asyncData ({ params, error }) {
          return axios.get(`https://my-api/posts/${params.id}`)
          .then((res) => {
            return { title: res.data.title }
          })
          .catch((e) => {
            error({ statusCode: 404, message: 'Post not found' })
          })
        } 
        
        

第三方插件的运用

      比方:element-ui
    
      须要在 plugins/ 中 增添 element-ui.js
    
        import Vue from 'vue'
        import Element from 'element-ui/lib/element-ui.common'
        import locale from 'element-ui/lib/locale/lang/en'
    
        export default () => {
          Vue.use(Element, { locale })
        }
    
    
      在 nuxt.config.js 中
    
      plugins: [
        "~/plugins/element-ui",
        // {src : '~/plugins/ga.js' , ssr : false}  是不是做ssr处置惩罚, false时为在客户端才加载
      ],
      
    
      如许全局便可以运用了
    
      注重:
          在运用第三方插件时须要注重 插件内部许多处所都邑用到window对象,在服务端会报错,所以须要将ssr设置为false
          
          在临盆环境中, 有一些插件,在多个页面中援用,如许会形成屡次加载打包的征象
        
          所以: 在 build设置项中增添设置
        
            build: {
              vendor:['axios', 'qs'],        // 防备屡次打包
            }
            

page 函数钩子生命周期 以及window 对象

      常常会在 第三方组件或许挪用的时刻 碰到window对象报错题目
    
      asyncData() {
        console.log(window) // 服务端报错
        console.log(this)   // undefined
      },
      fetch() {    
        console.log(window) // 服务端报错
      },
      created () {
        console.log(window) // undefined
      },
      mounted () {
        console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
      }
      
      

《vue 服务器端衬着 nuxt.js初探》

css js 文件打包文件夹处置惩罚

  在 uuxt.config.js 中 , 只需设置临盆环境中

  build: {
    extractCSS: { allChunks: true },    // css 自力打包 link 的情势加载
    publicPath: '/sample/assets/', //sample/essays 打包的默许途径为 ‘_nuxt’ 或许可以指定cdn 域名
    filenames:{         // css 和 js  img 打包时指定文件夹 
      app: ({ isDev }) => isDev ? '[name].js' : '[chunkhash].js',
      chunk: ({ isDev }) => isDev ? '[name].js' : '[chunkhash].js',
      css: ({ isDev }) => isDev ? '[name].js' : '[contenthash].css',
      img: ({ isDev }) => isDev ? '[path][name].[ext]' : '[hash:7].[ext]'
    }
  },

  输出 css link 途径: /sample/essays/[contenthash].css

  注重: 静态资本文件途径名 不能和页面路由称号雷同  publicPath 默许设置 '/' 无效
  
  

布置

  先 npm run build 打包 client文件和 server 文件

  然后 npm runb start 启动服务器

  pm2 治理

  pm2 start npm --name "my-nuxt" -- run start


  布置时 须要注重 假如是 从其他处所重定向 到  nuxt 环境中的页面是, 须要分外设置一个 css / js 重定向路由,而且须要注重 header头部信息,防备涌现 css 文件返回头部信息为 Content-Type text/plain
  

现在项目中只运用到这么多,后续项目迁移时碰到更多的题目会做补充,假如人人碰到过其他的坑点可以在下面批评中总结出来以及解决方案

文章较长,谢谢人人赏光!谢谢列位!

    原文作者:小蜗牛
    原文地址: https://segmentfault.com/a/1190000017977959
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞