通过一个多月的时间我将公司的一个项目用nuxt改造,在这当中踩过一些坑,我也在这进行一下总结,帮助大家快速认识一下nuxt
nuxt简单来说就是基于vue的服务器渲染框架,它相比较于单页面应用,它做SEO更加好的,项目需要考虑SEO我更建议它。之前的项目是采用打包多页面形式来处理SEO,但这种形式体验还是差了很多,比如说页面跳转时候闪烁感非常强烈,还有当接口请求时间过长时中间未采用骨架屏,页面显示就不友好。
在两端都可能会执行的当中可以使用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
}
},
}