手把手带你撸nuxtjs(三)--登录篇

想要拥有一个可以互动的网页 vuex 是必不可少的!

nuxtjs已经为我们把vuex 封装了,我们只需要创建 store 目录即可,目录下的每个 .js 文件会被转换成为状态树



image.png


一、获取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
}


相关内容

发表评论

验证码:
点击我更换图片

最新评论