Vue SSR 项目 Nuxt.js 框架之《vuex如何实现状
2022-03-10 本文已影响0人
酷酷的凯先生
# 前言
在项目开发中肯定会用到数据存储,而数据存储一般会选择Vuex
。那么怎么在nuxt
中实现Vuex
的使用及持久化
呢?
nuxt
是以模块的方式加载store
文件夹下所有的.js
文件的,并将其转换为状态树。其中index.js
是根模块,其余命名都是子模块。
# 创建根模块 index.js
store / index.js
// 定义 state
export const state = () => ({
token: 'token'
});
// 定义 actions
export const mutations = {
M_UPDATE_TOKEN(state, data) {
state.token = data
}
};
// 定义 actions
export const actions = {
A_TOKEN_INFO({ commit, state }, data) {
commit('M_UPDATE_TOKEN', '获得的token')
}
};
// 定义 getters
export const getters= {
getToken(state) {
return state.token || '';
}
}
# 创建子模块 user.js
store / user.js
// 定义 state
export const state = () => ({
uName: ''
});
// 定义 actions
export const mutations = {
M_UPDATE_UNAME(state, data) {
state.uName = data
}
};
// 定义 actions
export const actions = {
A_UPDATE_UNAME({ commit, state }, data) {
commit('M_UPDATE_UNAME', '张三');
}
};
// 定义 getters
export const getters= {
getUName(state) {
return uName.token || '';
}
}
在控制台打印出我们的状态树可以看到子模块user
已经加载到根模块
上,如下:
其他操作和使用和普通Vue
项目一样使用并无差别,比如:
某页面
export default{
computed:{
// 获取根模块下的 getters 返回的 token
...mapGetters(['getToken']),
// 拿取子模块的 state 数据
...mapState('user', ['uName']),
// 或者
...mapState({uName:state=>state.user.uName}),
},
mounted(){
this.M_UPDATE_UNAME('张三');
// 或者
this.A_UPDATE_UNAME('张三');
},
methods:{
...mapMutations('user', ['M_UPDATE_UNAME']),
...mapActions('user', ['A_UPDATE_UNAME'])
}
}
# 状态持久化与校验Token
在nuxt
中实现状态持久化
需要借助cookie-universal-nuxt
模块,整体思路就是:
- 在登录时将用户的
token
的同时存入Vuex
和cookie
里。 - 页面刷新后会触发
store
文件夹下的根目录的index.js
文件里的nuxtServerInit
钩子函数,在这个函数里将cookie
的信息重新注册到Vuex状态
里。 - 在
$axios
的请求拦截器onRequest
里每次请求时都从状态里取用户token
,取不到则说明用户没有登录,即跳转至登录页,让用户登录。
第一步:安装 cookie-universal-nuxt
npm i cookie-universal-nuxt --save-dev
第二步:在 nuxt.config.js 中引入 cookie-universal-nuxt
export default {
modules:['@nuxtjs/axios', 'cookie-universal-nuxt']
}
第三步:将用户token同时保存到 Vuex 和 cookie 中
// 模拟用户登录接口
this.$axios.post('/login', {uName: 'admin', pwd: '123456'}).then(res => {
// 将用户信息同步到 Vuex 和 cookie
this.$cookies .set('user_token', res.token);
this.$store.commit('M_UPDATE_TOKEN', res.token);
})
第四步:页面强刷时将cookie中的信息取出赋值给 Vuex
store / index.js
// 定义actions
export const actions = {
nuxtServerInit(store, { app: { $cookies } }){
let token = $cookies.get('user_token') ? $cookies.get('user_token') : '' ;
store.commit('M_UPDATE_TOKEN', token );
}
}
这时登录拿到
token
后同步到Vuex
和cookie
,强刷页面后会从cookie
里取出信息在赋值回Vuex
里,所以保证了Vuex
里的数据也不会丢失。
第五步:请求拦截器里校验 token
export default function({ $axios, redirect, router, store }) {
// 请求拦截器
$axios.onRequest(config => {
config.headers.token = store.state.token;
return config;
})
// 响应拦截器
$axios.onResponse(res => {
const resDate = res.data;
// 如果返回错误信息为 token 类似的,则跳转至登录页
if (resDate.msg == 'token无效') {
redirect('/login');
}
return resDate;
})
}