Vuex小结

  • A+
所属分类:Web前端
摘要

​ 近期的项目中多次用到了Vuex,感觉对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,也可以自行配置

可以参考这两个链接:vuex持久化 vuex-persistedstate - 简书 (jianshu.com)

robinvdvleuten/vuex-persistedstate: ? Persist and rehydrate your Vuex state between page reloads. (github.com)

5、v-model如何与Vuex中的数据进行双向绑定

假设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>