美文网首页
前端废物的自救之路(3)使用Cookie完成Nuxt.js中Vu

前端废物的自救之路(3)使用Cookie完成Nuxt.js中Vu

作者: NoelleMu | 来源:发表于2021-03-19 16:23 被阅读0次

    前端废物的自救之路(3)使用Cookie完成Nuxt.js中Vuex的持久化

    为什么需要Vuex持久化

    在开发的过程中,我们会使用Vuex来存储用户信息、Token等内容,但Vuex的信息是存储在内存中的,当页面刷新时,内容自然就丢失了。我们需要寻找其他的办法使得刷新页面时Vuex的信息能保存下来,也就是Vuex的持久化。

    Nuxt.js中的Vuex持久化方案及其可用性

    使用Vue.js时,我们一般用vuex-persistvuex-persistedstate等框架完成Vuex的持久化,也并不会出什么问题。但是在Nuxt中,情况就不一样了。

    在搜索引擎上搜索Nuxt Vuex持久化,可以找到以下解决方案:

    1. vuex-persistedstate配合js-cookie

      • 地址:nuxt中vuex数据持久化

      • 可用性:不可用,按照文中的方法配置仍然出现找不到window对象的情况。在配置插件的时候配置了ssr: false,仍然找不到window对象,推测可能是NuxtVuex的版本问题(注:这篇文章是19年12月的)。

    2. vuex-persist

    1. nuxtServerInit方法配合cookie-universal-nuxt

    终极解决方案:js-cookie配合nuxtServerInit实现Vuex持久化

    常见的解决方案都不可用,那么我们就需要终极解决方案:js-cookie配合nuxtServerInit

    实现起来也是很简单的。

    第一步:安装js-cookie

    npm install --save js-cookie
    

    第二步:设置Vuex时同时设置Cookie

    以登录为例,在拿到用户信息后使用js-cookie把用户信息设置到Cookie中。注意Cookie的过期时间要和服务端设置的Token的过期时间保持一致(服务端设置Token的过期时间是4小时),否则Token过期后再访问需要认证的页面会出现循环重定向的问题(我配置了根据Cookie判断用户是否登录的逻辑,并且登录后再访问登录页面会被重定向到后台管理,所以才会出现这样的问题,当然如果没有做这样的配置的话就无所谓了,或者你也可以配置在Token失效后清除Cookie的操作)。

    注意expires属性的单位是天,如果需要设置为小时的话可以传入小数。

    @/pages/login.vue

    import { mapMutations } from 'vuex'
    import * as Cookies from 'js-cookie'
    
    export default {
      // ...
      methods: {
        ...mapMutations(['setUserInfo']),
        login () {
          this.$refs.loginForm.validate((valid) => {
            if (valid) {
              // 表单校验通过,开始登录
              this.$axios.post('/login', {
                username: this.form.username,
                password: this.form.password
              }).then((res) => {
                // 登录成功,向Vuex中设置用户信息
                this.setUserInfo({
                  token: res.token,
                  userId: res.id,
                  username: res.username
                })
                // Cookie的过期时间与Token的过期时间一致,为4小时
                Cookies.set('token', res.token, { expires: 1 / 6 })
                Cookies.set('userId', res.user_id, { expires: 1 / 6 })
                Cookies.set('username', res.username, { expires: 1 / 6 })
                this.$router.push('/admin')
              }).catch((err) => {
                this.msg = err.response.data.message
              })
            } else {
              return false
            }
          })
        },
        // ...
      }
    }
    

    第三步:设置Vuex

    我们刚刚设置了保存Cookie的逻辑,接下来就需要把Cookie的信息取出来,设置在Vuex中,完成持久化操作。

    nuxtServerInit方法在每次发送请求且请求未到达页面的时候都会被调用,可以借助这个方法来设置Vuex。

    @/store/index.js

    export const state = () => ({
      token: '',
      userId: 0,
      username: ''
    })
    
    export const mutations = {
      // 用户登录时,需要设置用户信息
      setUserInfo (state, loginInfo) {
        state.token = loginInfo.token
        state.userId = loginInfo.userId
        state.username = loginInfo.username
      },
      // 用户登出时,需要删除用户信息
      removeUserInfo (state) {
        state.token = ''
        state.username = ''
        state.userId = 0
      }
    }
    
    export const actions = {
      nuxtServerInit ({ commit, store }, { req }) {
        // 切分Cookie
        const cookie = req.headers.cookie.split(';')
        // 定义字符常量:需要从cookie中取出的值的名称
        const tk = 'token='
        const un = 'username='
        const uid = 'userId='
    
        // 需要持久化的值
        let token = ''
        let username = ''
        let userId = 0
    
        // 遍历Cookie,取得需要的值
        cookie.forEach((e) => {
          if (e.includes(tk)) {
            token = e.split(tk)[1]
          } else if (e.includes(un)) {
            username = e.split(un)[1]
          } else if (e.includes(uid)) {
            userId = e.split(uid)[1]
          }
        })
    
        // 提交mutation
        commit('setUserInfo', {
          token,
          username,
          userId
        })
      }
    }
    
    

    注意这里我为了解决使用传统写法时控制台报Warn的问题而采用了Nuxt建议的写法。

    设置完成并重启应用之后,再次刷新页面就不会出现vuex数据被清空而需要重新登录的问题了。

    相关文章

      网友评论

          本文标题:前端废物的自救之路(3)使用Cookie完成Nuxt.js中Vu

          本文链接:https://www.haomeiwen.com/subject/ajtbcltx.html