export default { middleware () {}, //服务端 validate () {}, // 服务端 asyncData () {}, //服务端 fetch () {}, // store数据加载 beforeCreate () { // 服务端和客户端都会执行}, created () { // 服务端和客户端都会执行 }, beforeMount () {}, mounted () {} // 客户端 }
asyncData
该方法是Nuxt最大的一个卖点,服务端渲染的能力就在这里,首次渲染时务必使用该方法。 asyncData会传进一个context参数,通过该参数可以获得一些信息,如:
export default { asyncData (ctx) { ctx.app // 根实例 ctx.route // 路由实例 ctx.params //路由参数 ctx.query // 路由问号后面的参数 ctx.error // 错误处理方法 } }
渲染出错和ajax请求出错的处理
asyncData渲染出错
使用 asyncData 钩子时可能会由于服务器错误或api错误导致无法渲染,此时页面还未渲染出来,需要针对这种情况做一些处理,当遇到asyncData错误时,跳转到错误页面,nuxt提供了 context.error 方法用于错误处理,在asyncData中调用该方法即可跳转到错误页面。
export default { async asyncData (ctx) { // 尽量使用try catch的写法,将所有异常都捕捉到 try { throw new Error() } catch { ctx.error({statusCode: 500, message: '服务器开小差了~' }) } } }
这样,当出现异常时会跳转到,错误页面可以通过 /layout/error.vue 自定义。
这里会遇到一个问题, context.error 的参数必须是类似 { statusCode: 500, message: '服务器开小差了~' } , statusCode 必须是http状态码, 而我们服务端返回的错误往往有一些其他的自定义代码,如 {resultCode: 10005, resultInfo: '服务器内部错误' } ,此时需要对返回的api错误进行转换一下。
为了方便,我引入了 /plugins/ctx-inject.js 为context注册一个全局的错误处理方法: context.$errorHandler(err) 。注入方法可以参考: , ctx-inject.js :
// 为context注册全局的错误处理事件 export default (ctx, inject) => { ctx.$errorHandler = err => { try { const res = err.data if (res) { // 由于nuxt的错误页面只能识别http的状态码,因此statusCode统一传500,表示服务器异常。 ctx.error({ statusCode: 500, message: res.resultInfo }) } else { ctx.error({ statusCode: 500, message: '服务器开小差了~' }) } } catch { ctx.error({ statusCode: 500, message: '服务器开小差了~' }) } } }
然后在 nuxt.config.js 使用该插件:
export default { plugins: [ '~/plugins/ctx-inject.js' ] }
注入完毕,我们就可以在 asyncData 介个样子使用了:
export default { async asyncData (ctx) { // 尽量使用try catch的写法,将所有异常都捕捉到 try { throw new Error() } catch(err) { ctx.$errorHandler(err) } } }
ajax请求出错
对于ajax的异常,此时页面已经渲染,出现错误时不必跳转到错误页,可以通过 this.$toast.error(res.message) toast出来即可。
loading方法
nuxt内置了页面顶部推荐使用,提供页面跳转体验。 打开: this.$nuxt.$loading.start() 完成: this.$nuxt.$loading.finish()
打包部署
一般来说,部署前可以先在本地打包,本地跑一下确认无误后再上传到服务器部署。命令:
// 打包 npm run build // 本地跑 npm start
除node_modules,.git,.env,将其他的文件都上传到服务器,然后通过 pm2 进行管理,可以在项目根目录建一个 pm2.json 方便维护:
{ "name": "nuxt-test", "script": "./server/index.js", "instances": 2, "cwd": "." }
然后配置生产环境的环境变量,一般是直接用 .env.prod 的配置: cp ./.env.prod ./.env 。 首次部署或有新的依赖包,需要在服务器上 npm install 一次,然后就可以用 pm2 启动进程啦:
// 项目根目录下运行 pm2 start ./pm2.json
需要的话,可以设置开机自动启动pm2: pm2 save && pm2 startup 。 需要注意的是,每次部署都得重启一下进程: pm2 reload nuxt-test 。
五、最后
Nuxt.js引入了Node,同时nuxt.config.js替代了main.js的一些作用,目录结构和vue项目都稍有不同,增加了很多的约定,对于初次接触的同学可能会觉得非常陌生,更多的内容还是得看一遍官方的文档。