想要拥有一个可以互动的网页 vuex 是必不可少的!
nuxtjs已经为我们把vuex 封装了,我们只需要创建 store
目录即可,目录下的每个 .js
文件会被转换成为状态树
一、获取token
第一章就写过了,在utils/auth.js里面新建获取token,和缓存用户信息方法
import Cookies from 'js-cookie' const TokenKey = 'abcom_vms_token' export function getToken() { return Cookies.get(TokenKey) } export function setToken(token) { return Cookies.set(TokenKey, token) } export function removeToken() { return Cookies.remove(TokenKey) }
二、plugins里面新建permission.js
需要注意得是,nuxt路由默认会根据页面的路径规则自动生成,所以乍一看根本没有配置的地方,所以当我们想要使用类似beforeEach功能的时候,我们就需要自己定义一个小插件啦。
import store from 'vuex' import { getToken } from '@/utils/auth' // get token from cookie export default ({ app }) => { console.log(app.router) app.router.beforeEach(async (to, from, next) => { const hasToken = getToken() if (hasToken) { // 如果有token,还在往login里面进去,则直接跳首页去 if (to.path === '/login') { next({ path: '/' }) } else { // 随便取一个不在缓存里面的值,用于判断是否是刷新后加载,每次刷新后,都要强制去获取用户的最新信息 const hasGetUserInfo = store.user.avatar if (hasGetUserInfo) { next() } else { try { const userinfo = await store.dispatch('user/getInfo') // 获取信息后,把用户中心的路由加载进来 const addRoutes = await store.dispatch( 'permission/generateRoutes', userinfo ) router.addRoutes(addRoutes) // hack method to ensure that addRoutes is complete // set the replace: true, so the navigation will not leave a history record next({ ...to, replace: true }) } catch (error) { // 错误清除token await store.dispatch('user/resetToken') next() } } } } else { // 没token 就正常走咯!具体没登录的逻辑自行在页面判断,或者也可以在这里判断, // 比如如果去往的页面是user ,则在这里直接判断没有token就跳转登录 next() } }) app.router.afterEach(() => { }) }
nuxt.config.js 内引入该方法
plugins: [ // ssr: true表示这个插件只在服务端起作用 { src: '~/plugins/element', ssr: true }, { src: '~/plugins/permission', ssr: false} //只客户端运行 ],
二、处理登录
这里有个坑
getToken() 是无法获取到token得,因为服务器端,并没有Cookies,这时候,我们就要
nuxtServerInit 页面渲染前的store处理
但是这个方法无法试用于纯静态,
注意:使用 nuxt generate 静态化应用的时候, 传给 asyncData() 和 fetch() 方法的上下文对象 不会包含 req 和 res 两个属性。
所以nuxtServerInit是拿不到 req这个属性的!所以纯静态并不试用,只能伪静态
// store/index.js import { parse } from 'cookie-parse' const state = () => ({ bs: 5 }) const mutations = { } const actions = { // 在服务器端得时候,把请求携带得token,存入vuex nuxtServerInit({ commit }, { req }) { console.log('服务器步骤') console.log(req.headers) const cookie = parse(req.headers.cookie) // 主要这里提交的是user模块,abcom_token 为你携带得token头 console.log(cookie.abcom_token) commit('user/SET_TOKEN', cookie.abcom_token) } } export default { namespaced: true, state, mutations, actions }
第二个,标准的登录流程,先获取token,在拿token换用户信息,根据自己的流程处理
import { login, getInfo } from '@/api/user' import { getToken, setToken, removeToken, } from '@/utils/auth' const state = () => ({ token: getToken(), user: null, }) const mutations = { SET_TOKEN: (state, token) => { state.token = token }, SET_USER: (state, user) => { state.user = user }, } const actions = { // user login login ({ commit }, userInfo) { return new Promise((resolve, reject) => { login(userInfo) .then(response => { const { data } = response commit('SET_TOKEN', data.token) setToken(data.token) resolve(data) }) .catch(error => { reject(error) }) }) }, // get user info getInfo ({ commit, state }) { return new Promise((resolve, reject) => { getInfo(state.userId) .then(response => { console.log(response) const { user, userReferrer, user_extend } = response.data console.log(user) commit('SET_USER', user) if (!user) { reject('验证失败, 请重新登录') } resolve(user) }) .catch(error => { reject(error) }) }) }, // user logout logout ({ commit, state }) { return new Promise((resolve, reject) => { commit('SET_TOKEN', '') commit('SET_USER', '') removeToken() resolve() }) }, resetToken ({ commit }) { return new Promise(resolve => { commit('SET_TOKEN', '') commit('SET_USER', '') removeToken() resolve() }) } } export default { namespaced: true, state, mutations, actions }