为什么使用vuex管理token:vuex作为全局store,对token进行统一管理。
优点:获取数据方便,可以做到 响应式 ,还可以把有关token存取的操作都封装在vuex中做处理,组件就可以只负责触发action函数。但是为了数据的 持久化 ,还需要把token放到本地存储中。
vuex管理数据一般模式:
state(放置响应式数据) -> mutation(放置修改state的方法 且只有这里的方法可以修改数据) -> action(异步的方法 接口调用)
import { login } from "@/api/user"
export default {
//开启namespace:true,该模块就成为命名空间模块了
namespaced: true,
state: {
token: ''
},
mutations: {
setToken (state, token) {
state.token = token
}
},
actions: {
async fetchLogin (ctx, data) {
const res = await login(data)
ctx.commit('setToken', res)
}
}
}
最后,三步完成后就是在组件的某个位置触发一下action函数就OK。
handleLogin() {
// 1. 表单兜底校验 看文档 获取到form实例对象 调用校验方法 validate
this.$refs.loginForm.validate(async(valid) => {
// valid:只有在所有需要校验的表单都通过校验是才为true
if (valid) {
// 接口调用
console.log('login')
// loading展示
this.loading = true
try {
// 触发action函数 这里容易出错的地方 一个是参数传递 一个是await
// 保证action函数中的异步执行完毕 才能执行后续的提示和跳转
await this.$store.dispatch('user/fetchLogin', this.loginForm)
// 3. 跳转
// 4. 提示用户
this.$router.push('/')
this.$message.success('登录成功')
} catch (error) {
console.log(error)
this.loading = false
}
}
})
}
try catch: 可参考:try...catch - JavaScript | MDN
如果 try 语句块中发生异常,那么一个相应的异常对象就会被拋出,然后 catch 语句就会依据所拋出异常对象的类型进行捕获,并处理。处理之后,程序会跳过 try 语句块中剩余的语句,转到 catch 语句块后面的第一条语句开始执行。
如果 try 语句块中没有异常发生,那么 try 块正常结束,后面的 catch 语句块被跳过,程序将从 catch 语句块后的第一条语句开始执行。
Vuex 命名空间 namespaced :
组件中如何获取带有命名空间中的state数据?
1、基本方式:
this.$store.state.模块名.模块属性
2、mapState辅助函数方式:
...mapState({
count:state=>state.模块名.模块属性
})
组件中调用命名空间模块中的Actions
handleLogin((){ this.$store.dispatch('user/fetchLogin') }, ...mapActions('user',['fetchLogin']), //别名状态下 ...mapActions({ changeNameAction:'user/fetchLogin' })
更多可参看:Vuex 命名空间 namespaced 介绍
为什么要做持久化token?
Vuex 基于内存的管理方式 js引擎里,存取速度特别快,vue中使用起来也方便。缺点,刷新浏览器会重置 token会丢失。localstorage/cookie 基于本地磁盘的 存取速度稍慢 不和vue绑定 持久化刷新不丢失,除非手动清除。所以可以结合二者优势,实现持久化token。
手动实现方式:在获取到token之后 一式俩分,在vuex存一分,在本地存一份。vuex state中初始化的位置,优先从本地取,取到就直接用本地,取不到在初始化。
// 专门用来操作cookie的方法包
// 内部封装了繁琐的操作方法 参数处理 暴露三个函数 get,set,remove
import Cookies from 'js-cookie'
const TokenKey = 'hr_token'
// 获取token的方法
export function getToken() {
return Cookies.get(TokenKey)
}
// 设置方法
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
// 删除方法
export function removeToken() {
return Cookies.remove(TokenKey)
}
import { getToken, setToken, removeToken } from '@/utils/auth'
export default {
namespaced: true,
state: {
token: getToken() || ''
},
mutations: {
setToken(state, token) {
// 存入vuex
state.token = token
// 存入cookie
setToken(token)
}
}
}
token特性:一定时间内会失效,所以使用vuex配合cookie,既可以在应用运行的时候,方便存储使用token,又可以在用户刷新浏览器的时不丢失。