介绍
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
技术选型
这里我在纠结是采用VUEX还是传统的session,查阅了一下资料:
详见:https://www.jianshu.com/p/bc2d2429a693
vuex 与 (sessionStorage 、localStorage)区别
首先,理解vuex的作用
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
Vuex 和单纯的全局对象有以下两点不同:
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
通过对上面的理解,至少可以区分vuex与全局对象的区别,正如此,全局对象一般存储在session中,所以这就是vuex与session的区别。
注:官方文档进行查看 vuex
通过存储方式及类型区别
存储位置 : vuex存储在内存,而session则以文件的方式存储在本地;
应用场景 : vuex用于组件间的传值,而session则用于页面间的传值;
时效性 : vuex存储的值刷新时会丢失,而localstorage不会清除,除非手动删除;
还可以换种说法:
当 vuex 与 storage 关联的数据不变时,两者是等同的;但当是其中一个组件改变该数据时,同时另一个组件用到此数据,vuex是可以实现的,但storage是不可以的。
或者这个版本的理解也可以
详见:https://www.cnblogs.com/DZzzz/p/9201583.html
1.最重要的区别:vuex存储在内存,localstorage则以文件的方式存储在本地
2.应用场景:vuex用于组件之间的传值,(响应式的),localstorage则主要用于不同页面之间的传值(其他页面更新数据了,当前页面要刷新才能相应更新,非响应式的)
(响应式跟非响应式简直是说到点子上了)
3.永久性:当刷新页面时vuex存储的值会丢失(存在内存里的,刷新了,当然会丢失),localstorage不会。
注:很多同学觉得用localstorage可以代替vuex, 对于不变的数据确实可以,
但是当两个组件共用一个数据源(对象或数组)时,如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,local torage无法做到.
针对第3点,vuex就是一个“提升变量”的一个工具,它是将state当做全局变量存储。F5刷新页面之后自然随着页面的刷新重新初始化state。
目前想让浏览器记住数据,一般都会采用cookie或者localStorage、sessionStorage等方法。
结论
简而言之,对于需要存储业务量较少的,建议使用session即可;对于数据量较多且杂的场景,建议使用VUEX。
session存储的实现
概述
Storage 接口用于脚本在浏览器保存数据。两个对象部署了这个接口:window.sessionStorage 和window.localStorage。
sessionStorage保存的数据用于浏览器的一次会话(session),当会话结束(通常是窗口关闭),数据被清空;localStorage保存的数据长期存在,下一次访问该网站的时候,网页可以直接读取以前保存的数据。 除了保存期限的长短不同,这两个对象的其他方面都一致。
保存的数据都以“键值对”的形式存在。也就是说,每一项数据都有一个键名和对应的值。所有的数据都是以文本格式保存。它们也受同域限制,某个网页存入的数据,只有同域下的网页才能读取,如果跨域操作会报错。它们都仅在客户端使用,不和服务端进行通信。
setItem()
Storage.setItem() 方法用于存入数据。它接受两个参数,第一个是键名,第二个是保存的数据。如果键名已经存在,该方法会更新已有的键值。该方法没有返回值。两个参数都是字符串。如果不是字符串,会自动转成字符串,再存入浏览器。
window.sessionStorage.setItem('key', 'value');
window.localStorage.setItem('key', 'value');
getItem()
window.sessionStorage.getItem('key')
window.localStorage.getItem('key')
项目中的具体实现
登录场景
登录成功则返回一个token令牌,并且把用户信息保存在本地中:
axios({
url: '/api/core/login',
method: 'POST',
data: {
label: label,
account: this.ruleForm.username,
password: this.ruleForm.password,
}
}).then(resp => {
if (resp.data.label) { // 登录成功
window.sessionStorage.setItem('token', 'true');
window.sessionStorage.setItem('userId', resp.data.account);
// 保存这次登录的用户账号
window.localStorage.setItem("userId", resp.data.account);
// 根据checked判断是否记住密码
if (this.checked) {
const pwdAccess = {
remember: this.checked,
password: this.ruleForm.password,
};
window.localStorage.setItem("pwdAccess", JSON.stringify(pwdAccess));
}
else {
const pwdAccess = {
remember: this.checked,
password: '',
};
window.localStorage.setItem("pwdAccess", JSON.stringify(pwdAccess));
}
// 跳转到主页
this.$router.push("/MainPage");
ElMessage({
showClose: true,
message: resp.data.result,
type: 'success',
})
} else { // 登录失败
ElMessage({
showClose: true,
message: resp.data.result,
type: 'error',
})
}
})
训练场景
把当前用户正在训练的任务的ID等信息存储起来,便于区分:
// 人数达标,可以开始训练
startTrain() {
window.sessionStorage.setItem("taskId", this.taskId);
this.$router.push('/Training')
},
// 根据用户的不同类型,定制不同类型的离开方法
leaveRoom() {
this.websocket.close()
},
refresh() {
this.websocket.send(
JSON.stringify({
account: window.sessionStorage.getItem("userId"),
task_id: this.taskId,
label: 1,
})
);
},