Vuex 是一个专门为Vue.js应用程序开发的状态管理模式;也其实就是一个仓库管理着应用里面所有组件的状态。
有的时候项目较大时,组件嵌套过多的时候,多组件共享同一个State会在数据传递时出现很多问题,而vuex就可以解决这些问题;
场景有:
(1)单页面应用
(2)组件之间的状态
(3)音乐播放
(4)登录状态
(5)加入购物车
vuex由一下几部分组成:
// 创建一个 Counter 组件
const Counter = {
template: `{{ count }}`,
computed: {
count () {
return store.state.count
}
}
}
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
注意:不能直接调用一个 mutation hander,这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数”,如果要使用一个 mutation hander,需要以相应的 type 调用 store.commit 方法:
代码是:store.commit(‘increment’)
actions
1、 事件回调函数的对象,发送ajax请求与后台进行交互;
2、原理:负责处理 Vue Components接收到的所有交互行为。包含同步和异步操作,支持多个同名方法,按照注册的顺序依次触发。想后台API请求的操作就在这个模块中机芯,包括触发其他 action 以及提交 mutation 的操作。该模块提供了 Promise 的封装,以支持 action 的链式触发。
3、使用 action来分发(dispatch)事件通知 store 去改变,这样约定的好处是,我们能够记录所有store 中发生的 state 改变,同时实现能做到记录变更(mutation)、保存状态快照、历史回滚、时光旅行的先进的调试工具。
Action 类似于 mutation,不同在于以下两个方面:
(1)Action 提交的是 mutation,而不是直接变更状态;
(2)Action 可以包含任意的异步操作;
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此可以调用 context.commit提交一个 mutation,或者通过context.state和context.getters来获取 state 和 getters;
用处:
(1)如果需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
(2)如果有多个组件需要用到此属性,我们复制这个函数,或者抽取到一个共享函数然后在多处导入它,但是哪种方式都不是很可以,而Getter 解决了这个问题。
Getter 接受 state 作为第一个参数:
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)
}
}
})
Getter 会暴露为 store.getter 对象,可以用属性的形式来进行访问这些值;
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
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 的状态
流程:Vue组件接收交互行为,调用 dispatch 方法触发 action 相关处理,如果页面状态需要改变,则调用 commit 方法提交 mutation 修改 state,通过 getters 获取 state 新值,重新渲染 Vue Components,界面会随之更新。
1、可维护性会下降,如果想要修改数据,要维护三个地方;
2、可读性会下降,因为一个组件里的数据,根本看不出来是从哪来的;
3、增加耦合,大量的上传会派发,会让耦合性大大的增加,本来Vue 用Component就是为了减少耦合,如果不用Vuex的话,就会和组件化的初衷相反;
请多多指教~!