近期的项目中屡次用到了Vuex,感受对Vuex不太熟悉,趁着周末学习了一波,如今来总结一下。javascript
官网Vuex 是什么? | Vuex (vuejs.org)的描述vue
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。java
我的理解vuex就是一个用来共享数据的,在Vuex里存的数据全部的组件均可以访问到,而没必要进行复杂的组件通信。git
vuex的核心就是state,getters,mutations,actions,modules这5个核心概念。github
安装vuex
# yarn $ yarn add vuex # or npm $ npm i vuex
在store/index.js中代码shell
import Vue from 'vue' import Vuex from 'vuex' import moduleA from './module/a' Vue.use(Vuex) export default new Vuex.Store({ state: { msg: 'goodnight everyone!!' }, mutations: { }, actions: { }, getters: { }, modules: { moduleA, } })
在main.js中npm
import Vue from 'vue' import App from './App.vue' import store from './store' Vue.config.productionTip = false new Vue({ // 给Vue实例注入store,在组件中能够经过this.$store访问到Vuex的数据 store, render: h => h(App) }).$mount('#app')
最后在任意组件中,均可以经过this.$store来访问Vuex中的store数组
如:在App.vue中promise
<template> <div id="app"> {{ $store.state.msg }} </div> </template> <script> export default { name: 'App' } </script>
当咱们想要修改state中的数据时,须要提交mutation来修改
mutations: { SET_MSG: (state, value) => { state.msg = value } }, // 在vue文件中 this.$store.commit('SET_MSG', 'xxxxx')
若是须要进行一些异步的操做,则mutation就不行了,须要在action中来提交mutation
actions: { setMsg: ({commit}, value) => { commit('SET_MSG', value) // 还能够返回commit的结果,这是一个promise对象 return commit('SET_MSG', value) // Promise } } // 在vue文件中 this.$store.dispatch('setMsg', 'xxxxx') // 若是action中return了mutation的commit,那么就能够进行.then 或者await操做 this.$store.dispatch('setMsg', 'xxxxx').then(() => { // ... }) // 或者在一个async 修饰的异步函数中使用await await this.$store.dispatch('setMsg', 'xxxxx')
当一个组件须要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,咱们能够使用 mapState
辅助函数帮助咱们生成计算属性
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from 'vuex' export default { // ... computed: mapState({ // 箭头函数可以使代码更简练 count: state => state.count, // 传字符串参数 'count' 等同于 `state => state.count` countAlias: 'count', // 为了可以使用 `this` 获取局部状态,必须使用常规函数 countPlusLocalState (state) { return state.count + this.localCount } }) }
当映射的计算属性的名称与 state 的子节点名称相同时,咱们也能够给 mapState
传一个字符串数组
computed: mapState([ // 映射 this.count 为 store.state.count 'count' ])
利用展开运算符与局部计算属性混合使用
computed: { localComputed () { /* ... */ }, // 使用对象展开运算符将此对象混入到外部对象中 ...mapState({ // ... }) }
和mapState使用方法同样
和mapState用法相似,只不过是将mutations或actions映射成methods
methods: { ...mapActions([ // 映射 this.setMsg('xxx') 为 store.$dispatch('setMsg', 'xxx') 'setMsg' ]), ...mapMutations([ // 映射this.SET_MSG('xxx') 为store.commit('SET_MSG', 'xxx') 'SET_MSG' ]) }
缘由:
store里的数据是保存在运行内存中的,当页面刷新时,页面会从新加载vue实例,store里面的数据就会被从新赋值初始化
解决方法一:
利用sessionStorage或localStorage或者或cookie进行缓存,beforeunload事件能够在页面刷新前触发,监听beforeunload事件,在app.vue的生命周期中进行store中数据的存储和初始化,这里以存在sessionStorage中为例
export default { name: 'App', created () { // 在页面加载时读取sessionStorage里的状态信息 if (sessionStorage.getItem('vuex')) { this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('vuex')))) } // 在页面刷新时将vuex里的信息保存到sessionStorage里 window.addEventListener('beforeunload', () => { sessionStorage.setItem('vuex', JSON.stringify(this.$store.state)) }) } }
解决方法二:
利用第三方库,vuex-persistedstate进行Vuex数据的持久化。
安装
$ yarn add vuex-persistedstate
在vuex初始化时候,做为组件引入。
import persistedState from 'vuex-persistedstate' export default new Vuex.Store({ // ... plugins: [persistedState()] })
默认是持久化全部的state,也能够自行配置
能够参考这两个连接:vuex持久化 vuex-persistedstate - 简书 (jianshu.com)
假设store/index.js中代码以下
import Vue from 'vue' import Vuex from 'vuex' import persistedState from 'vuex-persistedstate' export default new Vuex.Store({ state: { msg: 'hello vuex', userInfo: { username: '', password: '' } }, mutations: { SET_MSG: (state, value) => { state.msg = value }, SET_USER_INFO(state, value) => { state.userInfo = value } }, actions: { setUserInfo: ({commit}, value) { commit("SET_USER_INFO", value) } } plugins: [persistedState()] })
<script> import { mapState, mapActions, mapMutations } from 'vuex' export default { computed: { ...mapState(['userInfo']), // 和简单数据类型进行绑定,须要提供setter,在setter中(分发actions)提交mutation修改state msg: { get() { return this.$store.state.msg } set(value) { this.SET_MSG(value) } } }, // 和复杂数据类型进行绑定,须要深度监听,在handler中(分发actions—)提交mutation修改state watch: { userInfo: { handler(userInfo) { this.setUserInfo(userInfo) }, deep: true } }, methods: { ...mapActions(['setUserInfo']), ...mapMutations['SET_MSG'] } </script>