最近一个老的项目需要重构,接触到
Vue
的SSR
框架Nuxt
,用法和vue
有些相同,但是又有个别情况下不相同,项目结束后对此进行一个记录,通过几个点来记录我在开发中遇到的一些问题进行总结.
1. 搭建运行
- 基础搭建
基础搭建可以直接使用nuxt官方的脚手架生成,选择适合自己项目的一些配置集成.
npx or yarn create-nuxt-app <项目名>
- 目录
Nuxt
的目录基本和vue
目录差别不大,不过Nuxt
的路由是通过pages
目录自动生成的,如果需要修改默认生成的路由需要在nuxt.config.js
中的router
配置中修改.
我们的重构项目因为url
需要适配之前的url
,所以我们所有的路由规则基本上都是动态的比如要访问xxx/动态参数/动态参数/动态参数.html需要将path
设置成/xxx/:param1/:param2/:param3.html这样.
当然如果没有这么复杂的参数,可以直接将vue
文件设置成_xx.vue
,这样会自动生成xxx/动态参数path
.
- 插件使用
nuxt
插件需要在nuxt.config.js
中注入,plugins
中写入插件路径,并且通过挂载到Vue
原型上.
- layouts
layouts
的使用方法和App.vue
类似,比如多个页面使用同一个头部底部等等的,可以在layout
添加layouts
文件夹中的vue
组件name,并且在内容区域使用<Nuxt>
标签作为路由出口.
2. 生命周期
nuxt生命周期分为服务端生命周期和客户端生命周期,可以使用一张图流程图来细化理解.
注意,只有在上面绿色的生命周期中才能使用window
,其它生命周期使用window
都会报错.
3. seo
使用nux
t当然是为了更好的seo啦,在nuxt
中设置seo的几个重要参数keywords
、都在head
函数中,包括一些需要在当前页引入的css
文件或者js
文件
head(){
return {
title:'',
meta:[{
hid: 'description',
name: 'description',
content: ''
},
{
hid: 'keywords',
name: 'keywords',
content: ''
},
],
script:[{src:'',type:''}],
link:[{rel:'',href:''}]
}
}
当然这里也可以动态设置,在asyncData
请求中获取到的数据赋值到这里即可.
4. 注意事项
- 公共js、css等
公共的css
、js
还有seo
标签可以在nuxt.config.js
中的head
中定义,如果页面没有定义head
,会使用这里的seo
标签信息和加载这里的css
与js
文件. - vuex
一般的登录信息我们使用vue
的时候会放在cookie
或者LocalStorage
中,每次获取通过vuex
来获取,在axios
中请求的时候放在header
请求头中,但是Nuxt
能不能这样做呢?答案是不能,因为服务端生命周期中访问不到window
,那就是说我们无法读取到cookie
或者LocalStorage中的
数据了.
怎么解决这个问题?我们使用了一个cookie
插件cookie-universal-nuxt
.
首先安装cookie-universal-nuxt
npm i cookie-universal-nuxt -S
将插件添加到nuxt.config.js
中的modules
中
modules: [
'cookie-universal-nuxt',
]
然后就可以在服务端的生命周期钩子中使用cookie
了.
context.$cookies.set('token')
context.$cookies.get('token')
context.$cookies.remove('token')
5. 遇到的问题
- 组件生成多次
遇到一个性能问题,Nuxt
在某种情况下会生成两个</Nuxt>
组件,导致出现多个页面html
,但是这个问题不会导致页面出现问题,只是在Vue devtools
插件中发现的,github
上提出了issuse
,暂时未解决.
更新,新版本已经解决了该问题.
- Axios的使用
正常情况下,我们会将每个模块的api
分成不同的api
文件,方便维护,但是在Nuxt
中我们怎样才能这样做呢?因为我们在独立的api/xxx.js文件中访问不到全局的$axios
插件. 这里我给出的解决方法是,在请求接口的时候通过context
将$axios
当做参数传递.
/**
* @description: 请求时调用的参数
* @param { this } context vue实例
* @param { xxx } data 请求需要的参数
* @return {*}
*/
export function xxxxx(context,data){
// const { phone, action, yzm_ticket, yzm_ticket }=data
return context.$axios.post(`你的接口url`,{...data})
}
async asyncData (content){
//请求接口,将vue实例和请求参数传递
xxxxx(content,data)
}
然后就可以继续按模块分类接口了.
- BUS的使用
在我们的业务场景中,需要在多个页面调用到layouts
组件的函数,vuex
明显不合适,所以我使用了Bus
来解决这个问题.
nuxt
中使用Bus
和vue
的区别不大,基本都是使用on()
监听,emit
触发事件即可.
首先我们需要在plugins
中新建一个js
文件,并且将$bus
添加到vue
的原型上,最后创建监听触发关闭三个事件.
import Vue from "vue";
const bus = new Vue();
Vue.prototype.$bus = {
on(...event) {
bus.$on(...event);
},
off(...event) {
bus.$off(...event);
},
emit(...event) {
bus.$emit(...event);
}
}
当然最后别忘了在nuxt.config.js
中添加插件,plugins:['~/plugins/bus']
6. 有哪些缺陷
- 启动时间过长
因为这次重构的项目东西比较多,大概在我们重构第二个模块的时候,启动速度慢了下来,最后所有模块重构的差不多的时候,每次启动都需要花费非常多的时候.
- 开发体验
和启动时间一样,模块多起来的时候,每次修改热更新都需要花费非常多的时间,基本上每次保存代码热更新的时候都可以喝上好几口水了,这个给我们的开发体验是非常差的.
- 错误页面
Nuxt
的报错会导致整个页面不可访问,比如有一个变量报了一个错误,会让整个页面无法渲染完成,导致页面出错.
7. 总结
- 什么样的框架
Nuxt
确实是一款非常不错的SSR
框架,如果是熟悉Vue
的人用来开发基本上可以一边看文档一边上手写代码,seo
优化非常的友好的,性能上也比传统的前后端不分离的要好很多,我们重构后的项目性能提升非常之大.
- 适合什么场景下使用
我个人觉得这个框架适合一些页面模块不是非常多的项目使用,因为页面模块多起来的话,开发体验会非常的不友好,比我前面提到的启动卡顿,开发也非常的卡顿.
- 建议
国内使用这个框架的确实很多,但是在开发途中会遇到一些问题找不到,建议多上Github
去了解一下,看看别人提出的问题有没有类似的,这样可以减少很多搜索问题的时间,也可以快速的解决问题,并且开发人员回馈速度也是很快的.
aaaa
呼噜呼噜呼噜厉害了