Nuxt.js全局路由守卫

发布于2/19/2020 来自:「前端知否」微信公众号

Nuxt应用中,有时候会遇到需要身份验证的路由模块。比如,有些模块页面,需要登录后才能访问。

如果读者熟悉Vue Router,那么实现起来就简单多了。和Vue Router一样,也是使用before_each路由守卫。具体实现代码如下:

plugins/check-before-each.js

export default function({ store, app }) {

app.router.beforeEach((to, from, next) => {

// 如果是账号设置,或者我的钱包页面模块,就判断用户是否登录了
if (to.path.indexOf('setting') !== -1 || to.path.indexOf('wallet') !== -1) {
// console.log('[store]', store.state.userId) 用户id
// console.log('[app]', app.$cookies.get('token')) 登录后返回的token

if (!(store.state.userId || app.$cookies.get('token'))) {
return next('/account/login')
}
}

// 其他页面模块,放行
next()
})
}

nuxt.config.js:

...

/*
** 在应用启动完成之前,先加载插件
*/
plugins: [
'~plugins/check-before-each.js', // 全局路由守卫插件
'~plugins/axios.js',
'~plugins/global.js',
{ src: '~/plugins/swiper.js', ssr: false },
{ src: '~/plugins/classList.js', ssr: false },
{ src: '~/plugins/vue-lazyload.js', ssr: false }
],

...

现在,全局路由守卫已经实现了。下边再介绍Nuxt.js中插件的一些知识点。

1. 插件执行时机

Nuxt.js允许您在运行Vue.js应用程序之前执行js插件。这在您需要使用自己的库或第三方模块时特别有用。

需要注意的是,在任何 Vue 组件的生命周期内, 只有 beforeCreate 和 created 这两个方法会在 客户端和服务端被调用。其他生命周期函数仅在客户端被调用。

2. 指定插件运行环境

不支持ssr的系统,插件只在浏览器里使用,这种情况下下,你可以用ssr: false,使得插件只会在客户端运行。

举个例子:

nuxt.config.js:

module.exports = {
plugins: [
{ src: '~/plugins/vue-notifications', ssr: false }
]
}

plugins/vue-notifications.js:

import Vue from 'vue'
import VueNotifications from 'vue-notifications'

Vue.use(VueNotifications)

您可以通过检测process.server这个变量来控制插件中的某些脚本库只在服务端使用。当值为 true 表示是当前执行环境为服务器中。

此外,可以通过检查process.static是否为true来判断应用是否通过nuxt generator生成。您也可以组合process.serverprocess.static这两个选项,确定当前状态为服务器端渲染且使用nuxt generate命令运行。

注意:由于Nuxt.js 2.4,模式已被引入作为插件的选项来指定插件类型,可能的值是:clientserver, ssr:false 在下一个主要版本中弃用,将过渡为 mode: 'client'

例子:

nuxt.config.js:

export default {
plugins: [
{ src: '~/plugins/both-sides.js' },
{ src: '~/plugins/client-only.js', mode: 'client' },
{ src: '~/plugins/server-only.js', mode: 'server' }
]
}

3. 插件命名惯例

如果假设插件仅在 客户端服务器端 运行,则 .client.js.server.js可以作为插件文件的扩展名应用,该文件将自动包含在相应客户端或者服务端上。

例子:

nuxt.config.js:

export default {
plugins: [
'~/plugins/foo.client.js', // 只在客户端使用
'~/plugins/bar.server.js', // 只在服务端使用
'~/plugins/baz.js' // 客户端 & 服务端
]
}