目录
1.3.1、Vuex 和 LocalStorage 实现动态维持登录状态
一、Vuex
前言
Vuex 就是一个统一管理状态的工具.
以往如果需要将一个组件的中的数据分享到其他组件上,就需要使用 props ,并且只能单向传递,并且一旦修改某一个共享数据的状态,还需要通知其他组件更新,非常不便于操作. 有了 Vuex 之后,就相当于有了一个共享数据的中心,并且共享的数据是动态更新的.
1.1、下载和配置 Vuex
1.1.1、下载 Vuex
输入如下指令安装(Vue2 适合的版本):
npm install vuex@3.1.0
1.1.2、配置 Vuex
a)在脚手架项目的 src 目录中创建 store 文件夹,里面创建 index.js 文件表示入口,配置以下内容:
import Vue from "vue";
import Vuex from "vuex"
Vue.use(Vuex); //配置 vue 注册 vuex
export default new Vuex.Store({
});
Ps;将来的共享数据状态,就是在 Vuex.Store 中配置的
b)在 main.js 中注册状态管理
import Vue from 'vue'
import App from './App'
import router from './router'
//vuex
import store from './store'
Vue.prototype.$store = store;
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, //注册 vuex
components: { App },
template: '<App/>'
})
1.2、Vuex 的使用
1.2.1、state 属性
state 用来定义一系列共享数据.
例如 有一个 count 数据,需要在多个组件中共享,操作如下:
a)Vuex.Store 中定义 state
export default new Vuex.Store({
state: { //定义公共数据. 使用共享组件:this.$store.state.count
count: 1
}
});
b)在需要共享的组件中使用
使用共享组件:this.$store.state.count 也可以简写为 $store.state.count
<h1>人工管理列表 --- {{ this.$store.state.count }}</h1>
1.2.2、mutations 属性
mutations 用来定义对共享数据的修改方法.
例如对 共享数据 count 进行 + 1 和 - 1.
a)Vuex.Store 中定义 mutations
export default new Vuex.Store({
state: { //定义公共数据. 使用共享组件:this.$store.state.count 也可以简写为 $store.state.count
count: 1
},
mutations: { //这里定义的方法,都有一个默认参数,这个参数就是在上面 state,通过 state 就可以拿到里面的参数
incrCount(state) {
state.count++;
},
decrCount(state) {
state.count--;
}
}
})
b)在需要共享的组件中使用
使用方式:this.$store.commit('方法名')
<h1>人工管理列表 --- {{ this.$store.state.count }}</h1>
<button @click="incr()"> 点我增加共享数据中的 count </button>
-------------------------------------------------------
methods: {
incr() {
this.$store.commit('incrCount');
},
1.2.3、getters 属性
getters 用来写对共享数据进行计算的方法,相当于组件中的 computed .
好处:效率高,只计算一次(计算结果缓存).
a)Vuex.Store 中定义 getters
export default new Vuex.Store({
state: { //定义公共数据. 使用共享组件:this.$store.state.count 也可以简写为 $store.state.count
count: 1
},
mutations: { //这里定义的方法,都有一个默认参数,这个参数就是在上面 state,通过 state 就可以拿到里面的参数
incrCount(state) {
state.count++;
},
decrCount(state) {
state.count--;
}
},
getters: { //用来定义对共享数据的一系列计算方法(这里定义的方法,都有一个默认参数,这个参数就是在上面 state,通过 state 就可以拿到里面的参数)
countSqrt(state) {
return state.count * state.count;
}
}
})
b)在需要共享的组件中使用
使用方式:this.$store.getters.countSqrt
<h1>人工管理列表 --- {{ this.$store.getters.countSqrt }}</h1>
1.3、实际开发应用
1.3.1、Vuex 和 LocalStorage 实现动态维持登录状态
先来看一下两者的区别:
- vuex存的是状态,存储在内存;localStorage是浏览器提供的接口,让你存的是接口,以文件的形式存到本地.
- vuex用于组件之间传值,localStorage主要用于页面间传值
- 当刷新页面时,vuex存储的值会丢失,localStorage不会
localStorage可以代替vuex,对于不变的数据确实可以,但是当两个组件共同用以数据源,如果其中一个组件中的数据源改变,希望另一个组件响应变化,这时候就要选择用vuex。
例如动态维持登录状态:
Vuex 的 store 如下
Vue.use(Vuex); //配置 vue 注册 vuex
export default new Vuex.Store({
//定义全局数据
state: {
//维持用户登录状态
user: {
id: localStorage.getItem("id"),
username: localStorage.getItem("username"),
isAdmin: localStorage.getItem("isAdmin"),
state: localStorage.getItem("state") //0正常(默认) 1禁言
}
},
mutations: {
//更新登录状态
login(state, user) {
state.user.id = user.id;
state.user.username = user.username;
state.user.isAdmin = user.isAdmin;
state.user.state = user.state;
//保存到 localStorage 中, 防止刷新页面,丢失 vuex 数据
localStorage.setItem("id", user.id);
localStorage.setItem("username", user.username);
localStorage.setItem("isAdmin", user.isAdmin);
localStorage.setItem("state", user.state);
},
//删除所有登录状态
logout(state) {
state.user = {};
localStorage.clear();
}
},
});
登录请求如下:
/**
* 登录
*/
login() {
//1.非空校验
if (this.user.username == null || this.user.username == '') {
Message.warning("用户名不能为空!");
this.$refs.username.focus();//获取焦点(提升用户体验)
return;
}
if (this.user.password == null || this.user.password == '') {
Message.warning("密码不能为空!");
this.$refs.password.focus();
return;
}
//2.发送请求
instance.post('/user/login', this.user).then(success => {
if (success.data.code == 1000) { //这里根据后端定义状态码(1000 表示 "操作成功")
//登录成功
//1.将 Token 保存到 localStorage 中
const token = success.data.data.token;
localStorage.setItem("token", token);
//2.将用户登录信息状态通过 vux 和 localStorage 进行保存
this.$store.commit("login", success.data.data);
//3.提示跳转
Message.success("登录成功,为您跳转到主页~");
this.$router.push({ name: "Index" });
} else {
//登录失败
console.log(success.data.msg);//从后端得到失败的信息(前端在控制台看即可)
Message.error("账号或密码错误,请重试!");
}
}).catch(error => {
Message.error("服务器异常,请稍后重试!");
console.log(error);
});
}