vuex 状态管理
终于还是要开始学习这个了,痛苦面具。
安装
bash
npm install vuex --save
创建 Store
在 src
路径下创建 store
文件夹,然后往里添加一个 index.js
文件
文件内容如下:
javascript
import Vue from 'vue';
import Vuex from 'vuex';
import user from './user'; // 引入user模块
Vue.use(Vuex);
const store = new Vuex.Store({
...
});
export default store;
引入 Store
在 main.js
文件中,引入导出的store对象
javascript
import store from './store'; // 引入我们前面导出的store对象
new Vue({
el: '#app',
router,
store, // 把store对象添加到vue实例上
...
});
Module (模块)
这里先做一个模块的拆分,从最难的开始吧,痛苦面具。 因为很多时候,如果功能多了,就不能再把所有东西都写到总的store文件里。
在 store
文件夹里,添加一个 user.js
文件,作为一个新的模块
路径:store/user.js
创建模块
javascript
//user.js
const user = {
namespaced: true, // 避免重名混淆
state: {
// 定义一个 username,以供全局使用
username: sessionStorage.getItem('username') || '默认用户名',
// 存储token
token: localStorage.getItem('token') ? localStorage.getItem('token') : ''
},
mutations: {
// 修改token,并将token存入localStorage
// 这里的 user 是对象
changeLogin (state, user) {
state.token = user.token;
state.username = user.username;
localStorage.setItem('token', user.token);
sessionStorage.setItem('username',user.username);
}
},
getters: {},
actions: {},
};
export default user;
TIP
这里需要注意的是,store 里的状态,页面刷新就会消失。所以在进行对象存储的时候,会把获取的值存储在 localStorage
|| sessionStorage
里,避免值在页面刷新时,直接消失。
引入模块
路径:store/index.js
javascript
import user from './user'; // 引入user模块
状态存储
由于练习的时候,是想通过 store
来存储 token
,来保存登录状态。这里就先模拟一下
文件:login.vue (登录页面)
javascript
import { mapMutations } from 'vuex'; // 从vuex中导入mapMutations
export default {
methods: {
...mapMutations('user',['changeLogin']), // 引入 user模块 mutation 里的方法
handleLogin() {
// 这里的this.changeLogin,就会指代user模块里的方法,如果上面不定义,会指向总store/index.js里的方法。
// 往方法里传入参数(对象属性)
// 写法一:
this.changeLogin({ token: token, username: this.params.username });
//写法二:
this.$store.commit('user/changeLogin',{ token: token, username: this.params.username })
}
}
}
获取状态(打印输出)
文件:login.vue (登录页面)
state
引入的时候,需要放在 computed
计算属性中
javascript
export default {
computed: {
...mapState(['user']), // 这里的user 指代的是模块名 / 如果是没有单独分开模块,则直接放state里的变量名
},
mounted() {
console.log(this.user.username,'----来自vuex存储的用户名');
console.log(this.user.token,'----来自vuex存储的token');
},
}
在页面组件中,与 data
使用相同
html
<div>{{user.username}}</div>
不拆分模块
如果功能少的话,可以直接写在 store / index.js
文件中
javascript
import Vue from 'vue';
import Vuex from 'vuex';
import user from './user'; // 引入user模块
Vue.use(Vuex);
const store = new Vuex.Store({
modules: { user }, // 把 user 模块挂载到store里面
state: {
name: sessionStorage.getItem('username') || '默认用户名'
},
mutations: {
setUserInfo (state, user) {
state.name = user.username;
sessionStorage.setItem('username',user.username);
}
},
});
export default store;
状态存储
javascript
import { mapMutations } from 'vuex'; // 从vuex中导入mapMutations
export default {
methods: {
...mapMutations(['setUserInfo']),
handleLogin() {
// 调用vuex中的commit方法更新vuex中的状态
// 写法一
this.setUserInfo({ username: this.params.username })
// 写法二
this.$store.commit('setUserInfo', { username: this.params.username })
}
}
}
📖 参考文档
- vuex页面刷新数据丢失问题的四种解决方式
- Vue进阶使用(四)---Vuex 状态管理模式(附模拟用户登录和动态编辑tag页demo)
- 手把手教你使用Vuex 重点1 更简化地描述
- vuex + axios拦截器 + 导航守卫实现登录/注销功能
- Vue 项目中用户登录及 token 验证的思路
- Vue配置路由导航守卫实现用户登录和退出(Vue2.x)
- vue页面控制权限,vuex刷新保存状态、登录状态保存(推荐阅读)
- vuex实现简单的登录功能
- Vuex进阶使用之modules模块化划分、mapState、mapActions辅助函数的使用
- vuex系列之modules用法
- vuex模块化(module) 重点2 涉及不同写法
- Vuex使用和v-model语法详细教程