Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。vuex的出现是为了解决web组件化开发的过程中,各组件之间传值的复杂和混乱的问题。
Vuex核心属性
● State
页面状态管理容器对象
集中存储Vue Components中data对象的零散数据,全局唯一,以进行统一的状态管理,页面显示所需的数据从该对象中进行读取。
Vue 实例中的 data 遵循相同的规则。
● Mutation
状态改变操作方法
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,类似于事件,只能包含同步的操作,通过store.commit 方法触发。在组件里面调用的方式 this.$store.commit(‘xxx’)。
- commit∶ 状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。
● Action
操作行为处理模块
类似于 mutation,不同在于action 提交的是 mutation,而不是直接变更状态,action 可以包含任意异步操作。在组件中的调用方式 this.$store.dispatch(‘xxx’)。
- dispatch∶ 操作行为触发方法,是唯一能执行action的方法。
- HTML页面上,vue组件负责接收用户操作等交互行为,执行dispatch方法触发action进行回应
● Module
模块
当应用变得非常复杂时,Vuex可以用module将 store 分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
● Getter
state对象读取方法
Vue组件通过该方法读取全局state对象。可以认为是 store 的计算属性,要获取或格式化数据需要使用getters,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
actions和mutations的区别
- mutations专注于修改state,理论上是修改state的唯一途径;actions 用来处理业务代码、异步请求。
- mutations:只能进行同步操作,且方法名只能全局唯一;actions :包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。
- 在视图更新时,先触发actions,actions再触发mutations。
- mutations的参数是state,它包含store中的数据;actions的参数是context,它是 state 的父级,包含 state、getters。
const store = new Vuex.store({
state:{
count:1
},
mutations:{
add(state){
state.count++;
}
},
actions:{
add(context){
context.commit('add');
}
}
})
为什么mutations中不能包含异步操作
- Vuex中所有的状态更新的唯一途径都是mutations,异步操作通过 actions 来提交 mutations实现,这样可以方便地跟踪每一个状态的变化,从而能够实现一些工具(devtools)帮助更好地了解我们的应用。
- 每个mutations执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutations支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。
Vuex数据传递流程
- 当vue组件进行数据修改的时候,我们需要调用dispatch触发actions中的方法;
- actions里的每个方法都有一个commit触发mutations中的方法,从而进行数据修改;
- mutations里的每个函数都有一个state参数,我们就可以在函数中修改数据;
- 当数据修改完毕后会传导给页面,页面的数据也会发生改变。
Vuex的辅助函数
mapState
mapGetters
mapMutations
mapActios
- mapState与mapGetters都用computed来进行映射。在组件中映射完成后,通过 this.映射属性名 进行使用
- mapMutations与mapActios都在methods中进行映射。映射之后变成一个方法
mapState
当一个组件需要获取多个状态的时候,将这些状态都设置为计算属性会有重复和冗余。这时可以使用mapState辅助函数帮助我们生成计算属性(定义的属性名与state中的名称相同时,可以传入一个数组)
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.countAlias
}
})
}
}
mapGetters
使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中 (当属性名与getters中定义的相同时,可以传入一个数组)
computed:{
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
}
mapMutations
methods:{
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
//当属性名与mapMutatios中定义的相同时,可以传入一个数组
methods:{
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
}
mapActions
mathods:{
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
//当属性名与mapActios中定义的相同时,可以传入一个数组
methods:{
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
}
Vuex和LocalStorage的区别
- vuex存储在内存中;localstorage 则以文件的方式存储在本地浏览器(读取内存比读取硬盘速度要快)
- localstorage只能存储字符串类型的数据,存储对象需要 JSON 的 stringify 和 parse 方法进行处理
- 刷新页面时vuex存储的值会丢失,localstorage不会。
- Vuex能做到数据的响应式,localstorage不能。
- 应用场景:
- vuex用于组件之间的传值。
- localstorage一般是在跨页面传递数据时使用 。
用sessionstorage 或者 localstorage 存储数据
- 存储: sessionStorage.setItem( ‘名’, JSON.stringify(值) )
- 使用: sessionStorage.getItem(‘名’) —得到的值为字符串类型,用JSON.parse()去引号