17章 前端之全局存储:Vuex=Store
Store用于对数据进行存储,并共享以为所有需要的Vue页面中的调用提供数据及其方法支撑;Vuex是Store的内置引用包,即如果想要前端Vue程序支撑Store必须在新建Vue程序;如果Vue程序没有引用Vuex包则,在Vue程序引用Vuex包。
1 定义src\store\index.js
import {
createStore
} from 'vuex'
export default createStore({
state: {
token: null,//实例化“TokenJwt”字符串。
tokenExpire: null,//实例化“TokenJwt”字符串的过期时间。
},
getters: {},
mutations: {
//通过该方法把“TokenJwt”字符串,进行全局存储。
saveToken: function(state, data) {
state.token = data;
window.localStorage.setItem("Token", data);
},
//通过该方法把“TokenJwt”字符串的过期时间,进行全局存储。
saveTokenExpire: function(state, data) {
state.tokenExpire = data;
window.localStorage.setItem("TokenExpire", data);
},
},
actions: {},
modules: {}
})
2 重构 src\api\api.js中的守卫拦截
else if (error.response) {
if (error.response.status == 401) {
var curTime = new Date()
var refreshtime = new Date(Date.parse(window.localStorage.refreshtime))
// 在用户操作的活跃期内
if (window.localStorage.refreshtime && (curTime <= refreshtime)) {
return refreshToken({token: window.localStorage.Token}).then((res) => {
if (res.success) {
createApp.prototype.$message({
message: '成功获取“TokenJwt”字符串,数据载入中...',
type: 'success'
});
//把“TokenJwt”字符串,进行全局存储。
this.$store.commit("saveToken", res.response.token);
//把“TokenJwt”字符串的过期时间,进行全局存储。
let curTime = new Date();
let expiredate = new Date(curTime.setSeconds(curTime.getSeconds() + res.response.expires_in));
this.$store.commit("saveTokenExpire", expiredate);
error.config.__isRetryRequest = true;
error.config.headers.Authorization = 'Bearer ' + res.response.token;
return axios(error.config);
} else {
// 刷新token失败 清除token信息并跳转到登录页面
//ToLogin()
}
});
} else {
// 返回 401,并且不知用户操作活跃期内 清除token信息并跳转到登录页面
//ToLogin()
}
}
3 重构src\views\LoginView.vue
async submitLogin() {
this.$refs.refRuleLogin.validate(async (valid) => {
if (valid) {
this.logining = true;
this.loginStr = "登录中...";
let loginParams = {
name: this.formLogin.account,
pass: this.formLogin.checkPass
};
let res = await requestLogin(loginParams);
//console.log(res);
if (res.status == 200) {
//把“TokenJwt”字符串,进行全局存储。
console.log(this.$store.state.token);
let token = res.response.token;
this.$store.commit("saveToken", token);
console.log(this.$store.state.token);
//把“TokenJwt”字符串的过期时间,进行全局存储。
console.log(this.$store.state.tokenExpire);
let curTime = new Date();
let expiredate = new Date(curTime.setSeconds(curTime.getSeconds() + res.response.expires_in));
this.$store.commit("saveTokenExpire", expiredate);
console.log(this.$store.state.tokenExpire);
this.$message.success("成功登录");
//通过定时器,3秒钟后跳转。
await setInterval(
async () => {
await this.$router.replace(this.$route.query.redirect ? this
.$route.query.redirect : "/");
}, 3000);
} else {
this.$message.error(res.msg);
this.logining = false;
this.loginStr = "重新登录";
}
} else {
console.log('输入不能通过验证 !');
return false;
}
});
},
4 重构src\views\ LoginCompositionView.vue
<script setup>
import {
ref,
reactive,
getCurrentInstance
} from "vue";
import { useStore } from "vuex";
import {
requestLogin
} from "../api/api.js";
const formLogin = reactive({
account: 'test',
checkPass: 'test',
});
const ruleLogin = reactive({
account: [{
required: true,
message: '请输入账号',
trigger: 'blur'
}, ],
checkPass: [{
required: true,
message: '请输入密码',
trigger: 'blur'
}, ],
});
const checked = ref(true);
const loginStr = ref('登录');
const logining = ref(false);
//实例化表单“ref”属性所对应的值。
const refRuleLogin = ref('');
const {
$router,
$route,
$message
} = getCurrentInstance().root.ctx.$root;
//注意:由于“store”需要“retrun{}”出去,所以必须在提交事件之外进行实例化。否则会出现异常。
const store = useStore();
//表单单击提交事件。
const submitLogin = (formEl) => {
if (!formEl) return;
formEl.validate(async (valid) => {
if (valid) {
logining.value = true;
loginStr.value = "登录中...";
let loginParams = {
name: formLogin.account,
pass: formLogin.checkPass
};
let res = await requestLogin(loginParams);
//console.log(res);
if (res.status == 200) {
//把“TokenJwt”字符串,进行全局存储。
console.log(store.state.token);
let token = res.response.token;
store.commit("saveToken", token);
console.log(store.state.token);
//把“TokenJwt”字符串的过期时间,进行全局存储。
console.log(store.state.tokenExpire);
let curTime = new Date();
let expiredate = new Date(curTime.setSeconds(curTime.getSeconds() + res.response.expires_in));
store.commit("saveTokenExpire", expiredate);
console.log(store.state.tokenExpire);
$message.success("成功登录");
//通过定时器,3秒钟后跳转。
await setInterval(
async () => {
$router.replace($route.query.redirect ? $route.query.redirect : "/WelcomeComposition");
}, 3000);
}
else {
$message.error(res.msg);
logining.value = false;
loginStr.value = "重新登录";
}
} else {
console.log('输入不能通过验证 !');
return false;
}
});
}
</script>
5 重构src\views\WelcomeView.vue
<template>
<h1>Welcome</h1>
</template>
<script>
export default {
data() {
return {};
},
methods: {
},
mounted() {
/* console.log(this.$store.state.tokenExpire);
this.$store.commit("saveTokenExpire", null);
console.log(this.$store.state.tokenExpire); */
var curTime = new Date();
if (this.$store.state.tokenExpire) {
var expiretime = new Date(Date.parse(this.$store.state.tokenExpire));
if (curTime >= expiretime) {
this.$router.push("/login");
}
} else {
this.$router.push("/login");
}
},
}
</script>
6 定义src\views\WelcomeCompositionView.vue
<template>
<h1>WelcomeComposition</h1>
</template>
<script setup>
import {
getCurrentInstance
} from "vue";
import { useStore } from "vuex";
//注意:由于“store”需要“retrun{}”出去,所以必须在提交事件之外进行实例化。否则会出现异常。
const store = useStore();
/* console.log(store.state.tokenExpire);
store.commit("saveTokenExpire", null);
console.log(store.state.tokenExpire); */
const {
$router,
} = getCurrentInstance().root.ctx.$root;
var curTime = new Date();
if (store.state.tokenExpire) {
var expiretime = new Date(Date.parse(store.state.tokenExpire));
if (curTime >= expiretime) {
$router.push("/LoginComposition");
}
} else {
$router.push("/LoginComposition");
}
</script>
对以上功能更为具体实现和注释见:221217_003_admin(前端之全局存储:Vuex=Store)。