通过一个多月的时间我将公司的一个项目用nuxt改造,在这当中踩过一些坑,我也在这进行一下总结,帮助大家快速认识一下nuxt

nuxt介绍

nuxt简单来说就是基于vue的服务器渲染框架,它相比较于单页面应用,它做SEO更加好的,项目需要考虑SEO我更建议它。之前的项目是采用打包多页面形式来处理SEO,但这种形式体验还是差了很多,比如说页面跳转时候闪烁感非常强烈,还有当接口请求时间过长时中间未采用骨架屏,页面显示就不友好。

nuxt生命周期

在这里插入图片描述
在两端都可能会执行的当中可以使用process.server和process.client去做对应端需要处理的业务

登录状态的处理及通用方案

当你登录状态要做持久化处理时你就需要借助cookie来实现,当项目采取的是cookie来处理你可以使用 cookie-universal-nuxt 插件来处理,当然如果是采用token,不管是放在请求头中还是请求体中,我在下面给出一个傻瓜式的解决方案
所需要使用的 cookie-universal-nuxt

// nuxt.config.js添加axios二次封装
plugins: [
    "~/plugins/axios"
 ],
 modules: [
    '@nuxtjs/axios',
    'cookie-universal-nuxt',
 ]

//plugs/axios.js
export default function ({ $axios, redirect, store,app,route ,error }, inject) {
  let axios = $axios; 
  axios.defaults.headers = {
  //设置token,cookie-universal-nuxt将对象绑定在app对象上了
    Authorization:store.state.token ||  app.$cookies.get('token') || ''
  }
  
  axios.baseUrl = '/api'
 // 基本配置

  // 请求回调
  axios.onRequest(config => {
    return config
  })

  // 返回回调
  axios.onResponse(async res => {
    return await res
  })

  // 错误回调
  axios.onError(err => {
    if(process.client){
      //处理浏览器端接口异常
      switch(err.response.status){
        case 500:break;
        case 404:break;
        default:break;
      }
      
    }else{
		//处理服务器端接口异常
      switch(err.response.status){
        case 404:
        //layout/error.vue
        //加载error页面
        //return error({statusCode:404});
        break;
      }
    }
    
  })
}

//store/index.js
const state = () => ({ 
  token: ''
});

const mutations = {
  setToken(state, token) {
    state.token = token
  }
};

const actions = {
  async nuxtServerInit({
    commit
  }, {
    req,
    app,
    store
  }) {
    let token = app.$cookies.get('token') || '';
    commit('setToken', token);
	//还可以获取一些通用信息,比如个人信息,通用配置什么的

  }
};
export default {
  state,
  actions,
  mutations
};

项目打包优化

1.类似element-ui这样的ui框架可以采取按需引入的方式来缩小打包后的代码体积

//nuxt.config.js
 plugins: [
    {
      src: "~/plugins/element-ui",
      ssr: true
    }
 ],
 build:{
 	babel: {
      plugins: [
        ["component",
          {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
          }
        ]
      ],
 }
 
//plugs/element-ui.js
import Vue from 'vue'
import locale from 'element-ui/lib/locale/lang/en'

// 全局引用
// import Element from 'element-ui'

// 按需引用
import { Message,Input, } from 'element-ui'

// 自定义主题样式(这里我们会在这个文件内引入我们所需的组件的样式)
import '~/assets/css/element-ui.scss'
// 按需使用
Vue.use(Input , { locale })
Vue.prototype.$message = Message;

//assets/css/element-ui.scss  (当中有不确定的可以去看element-ui的源码)
@import "~/node_modules/element-ui/packages/theme-chalk/src/message.scss";
@import "~/node_modules/element-ui/packages/theme-chalk/src/input.scss";

2.打包优化
我是使用compression-webpack-plugin对较大的文件进行分割

//nuxt.config.js
const CompressionPlugin = require('compression-webpack-plugin');
build:{
	 plugins: [
      new CompressionPlugin({
        test: /\.js$|\.html$|\.css/, // 匹配文件名
        threshold: 10240, // 对超过10kb的数据进行压缩
        deleteOriginalAssets: false // 是否删除原文件
      })

    ],
    optimization: {
      splitChunks: {
        minSize: 10000,
        maxSize: 250000
      }
    },
}
Logo

前往低代码交流专区

更多推荐