在vue中tokn持久化与统一注入

一、手动存储token

1、将token保存到vuex中

1、项目中,已经用了modules,直接在store/modules/user.js中定义token

  • 在vuex中将token存到state中
const state = {
  token: '' // 共享token
}

const mutations = {
  // 对token进行赋值
  setToken(state, newToken) {
    state.token = newToken
  },

  // 移除token
  removeToken(state) {
    state.token = ''
  }
}

2、在登录页面调用 mutation 方法,将后端返回的 token 存到 vuex 的 state 中

通过实例方式调用 mutation 方法

handleLogin() {
      // 1、兜底验证
      // 在回调函数中,有一个形参 valid 就是指验证是否通过
      this.$refs.loginForm.validate(async valid => {
        if (valid) {
          // 登录时禁用登录按钮
          this.loading = true
          // 2、验证成功,发起请求
          const res = await login(this.loginForm)
          // console.log(res.data)   这是返回的 token

          // 通过实例方式调用 mutation 方法
          // this.$store.commit('vuex中的模块名/模块里面的方法', 传入的数据)
          this.$store.commit('user/setToken', res.data)

          // 3、请求成功以后,跳转
          this.$router.push('/')

          this.loading = false
        }
      })
    }

通过借助辅助函数方式

// 先引入
import { mapMutations } from 'vuex'

export default {
  methods: {
    // 第二个参数是数组,数组中放置方法名
    ...mapMutations('user', ['setToken']),

    handleLogin() {
      // 1、兜底验证
      // 在回调函数中,有一个形参 valid 就是指验证是否通过
      this.$refs.loginForm.validate(async valid => {
        if (valid) {
          // 登录时禁用登录按钮
          this.loading = true
          // 2、验证成功,发起请求
          const res = await login(this.loginForm)
          // console.log(res.data)  这是获取到的 token

          // 借助辅助函数方式
          this.setToken(res.data)

          // 3、请求成功以后,跳转
          this.$router.push('/')

          this.loading = false
        }
      })
    }
  }
}

  3、将登陆获取到的token统一注入到接口的请求头中 。

请求拦截器代码在文件src/utils/request.js

  • 引入 store

  • 补充请求拦截器,代码逻辑是:

    • 如果当前 vuex中有 token,就在请求头中设置上

    • 因为后端返回的 token 没有添加上 Bearer 字符串,因此我们需要手动添加

    • authorization 和 Bearer 是本项目的后端接口要求的写法。 

import store from '@/store'
// 请求拦截器
service.interceptors.request.use(
  config => {
    console.log(config)
    // 先获取token
    const token = store.state.user.token

    // 判断是否存在token,如果存在,需要设置请求头
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

4、永久保存token

在`utils/auth.js`中,基础模板已经为我们提供了`获取token``设置token`,`删除token`这三个方法,可以直接使用

只需要将存储的key放置成特定值即可

// 导入 js-cookie,用来将数据存储到本地
import Cookies from 'js-cookie'

// 统一的 key
const TokenKey = 'vue_token'

// 获取 token
export function getToken() {
  return Cookies.get(TokenKey)
}

// 设置 token
export function setToken(token) {
  // key -- 名
  // token -- 值
  return Cookies.set(TokenKey, token)
}

// 删除本地存储的 token
export function removeToken() {
  return Cookies.remove(TokenKey)
}

2、在vuex中引入方法,并调用

store/modules/user.js文件中

import { getToken, setToken, removeToken } from '@/utils/auth'

// 共享的数据
const state = {
  token: getToken() || ''// 用户 Token,默认为 空
}

// 操作数据的方法
const mutations = {
  // 对token进行赋值
  setToken(staye, newToken) {
    // 设置token
    state.token = newToken
    // 将token持久化存储到本地
    setToken(newToken)
  },
  // 移除token
  removeToken(state) {
    // 删除vuex的token
    state.token = ''
    // 删除本地token
    removeToken()
  }
}

二、使用插件自动存储vuex

实现步骤

  1. 安装vuex-persistedstate 插件

  2. vuex中准备user模块cart模块

  3. 将插件配置到vuex的plugins选项中,配置user模块和cart模块进行状态持久化

  4. 修改state数据就会触发自动同步机制,修改一下数据检测是否同步成功

代码落地

1)安装一个vuex的插件vuex-persistedstate来支持vuex的状态持久化

npm i vuex-persistedstate

2)在src/store 文件夹下新建 modules 文件,在 modules 下新建 user.jscart.js

src/store/modules/user.js

// 用户状态
export default {
  namespaced: true,
  state: () => ({
    // 个人用户信息
    profile:{
        id: '',
        nickname: '',
        avatar: '',
        token: '',
        mobile: '' 
    }
  })
}

src/store/modules/cart.js

// 购物车状态
export default {
  namespaced: true,
  state: () => ({
      list:[]
  })
}

3)在 src/store/index.js 中导入 user 和 cart 模块

import { createStore } from 'vuex'

import user from './modules/user'
import cart from './modules/cart'

export default createStore({
  modules: {
    user,
    cart
  }
})

4)使用vuex-persistedstate插件来进行持久化

import { createStore } from 'vuex'
import createPersistedstate from 'vuex-persistedstate'

import user from './modules/user'
import cart from './modules/cart'

export default createStore({
  modules: {
    user,
    cart
  },
  plugins: [
    createPersistedstate({
      key: 'erabbit-client-pc-store',
      paths: ['user', 'cart']
    })
  ]
})

插件说明

  1. 默认是存储在localStorage中,可以对存储的方法进行自定义

  2. key是存储数据的键名

  3. paths是存储state中的那些数据,如果是模块下具体的数据需要加上模块名称,如user.token

  4. 修改state中的数据即可触发同步机制,可以看到本地存储数据的的变化

测试效果

user模块定义一个mutation在main.js去调用下,观察浏览器application的localStorage下是否已经有了数据

src/store/modules/user.js

// 测试代码
mutations: {
    setUser (state) {
      state.profile.id = 10001
    }
}

src/main.js

store.commit('user/setUser')
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js Vuex 是一个专为 Vue 应用程序设计的状态管理模式,它主要用于管理应用的共享状态。Vuex 的核心概念是 store,它是一个单一的、可复用的数据源,所有的组件都可以从 store 获取状态和 dispatch(发送)动作。 关于 vuex 的持久存储,通常有以下几种方法: 1. **本地存储 (LocalStorage):**使用浏览器提供的 localStorage API,将 store 的数据序列后存储在客户端。当应用程序重新加载时,可以通过读取 localStorage 来恢复状态。例如,`store.commit('SET_DATA', JSON.stringify(state))` 保存,`store.commit('LOAD_DATA', JSON.parse(localStorage.getItem('myKey')))` 读取。 ```javascript import { mapState } from 'vuex'; export default { computed: { ...mapState(['data']), loadedData() { return JSON.parse(localStorage.getItem('data') || 'defaultData'); }, }, beforeCreate() { try { this.data = this.loadedData; } catch (error) { // 处理错误 } }, created() { localStorage.setItem('data', JSON.stringify(this.data)); }, beforeDestroy() { localStorage.removeItem('data'); }, }; ``` 2. **Cookie:**虽然 Cookie 的数据量限制较小(一般为4KB),但也可以用于简单的状态持久。 3. **IndexedDB 或 WebSQL:**对于更复杂的数据结构或需要离线支持的应用,可以考虑使用这些更强大的浏览器内置数据库技术。 4. **第三方插件:**比如 `vue-localstorage`、`vue-router-store` 等插件提供了更方便的接口和功能,比如自动同步状态等。 **相关问题--:** 1. 在Vuex,为什么要将状态存储在本地而非直接在组件里? 2. 使用 Vuex 的持久存储时,如何处理数据的同步和异步问题? 3. 如何在 Vuex 实现状态的清除,而不仅仅是禁用或重置?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值