Vuex小结
Vuex小结
前言
近期的项目中多次用到了Vuex,感觉对Vuex不太熟悉,趁着周末学习了一波,现在来总结一下。
1、Vuex是什么
官网Vuex 是什么? | Vuex (vuejs.org)的描述
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
个人理解vuex就是一个用来共享数据的,在Vuex里存的数据所有的组件都可以访问到,而不必进行复杂的组件通讯。
vuex的核心就是state,getters,mutations,actions,modules这5个核心概念。
- state,Vuex中共享的数据
- getters,可以理解为Vuex中的计算属性
- mutations,用来修改state的,更改 Vuex 的 state中的状态的唯一方法是提交 mutation,只能是同步的操作
- actions,类似于mutation,可以进行异步的操作
- modules,Vuex中数据模块化
2、vuex如何使用
安装
# yarn
$ yarn add vuex
# or npm
$ npm i vuex
在store/index.js中代码
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中
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中
<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')
3、Vuex中的辅助函数
mapState
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 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({
// ...
})
}
mapGetters
和mapState使用方法一样
mapMutations和mapActions
和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'
])
}
4、Vuex页面刷新后数据丢失
原因:
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,也可以自行配置