内容简介:为Vue.js应用程序开发的状态管理模式由 多个组件共享状态 引起的
Vuex
为Vue.js应用程序开发的状态管理模式
解决的问题
由 多个组件共享状态 引起的
1. 多个视图依赖于统一状态 2. 不同视图的行为需要变更统一状态
Store
每个应用只包含一个Store实例
- Vuex 的状态存储是响应式的。store 中的state状态更新立即触发组件更新
-
不能直接修改state。
-
两种方式:
- 可以通过 this.$store.state.变量 = xxx; 进行修改
-
显式地提交 (commit) mutation
- this.$store.dispatch(actionType, payload) => mapActions 使用action进行更改,异步
- this.$store.commit(commitType, payload) => mapMutations 使用mutation进行更改,同步
- 可以通过 this.$store.state.变量 = xxx; 进行修改
- strict模式使用第一种方法vue会throw error : [vuex] Do not mutate vuex store state outside mutation handlers。
-
异同点
- 共同点:都能触发视图更新(响应式修改)
-
不同点:
- strict模式下,使用第一种方法vue会throw error : [vuex] Do not mutate vuex store state outside mutation handlers。
-
使用commit的优点:
- vuex能够记录每一次state的变化记录,保存状态快照,实现时间漫游/回滚之类的操作。
-
核心概念
State 单一状态树
- 全局的应用层级状态 -- 唯一数据源
- 通过this.$store.state可以访问
- mapState 辅助函数:帮助在组件中引入state相关属性,作为组件的计算属性
Getter state派生状态
可以认为是 store的计算属性 : getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
getters: { // 可以通过第二个参数getters来使用其他getter getterA: (state, getters) => { return getters.getterB.length }, getterB: (state) => { return state.todoList; }, getterC: (state) => (id) => { return state.todoList[id]; } }
-
通过属性访问:this.$store.getters.getterA
- getter作为Vue的响应式系统的一部分缓存其中
-
通过方法访问:this.$store.getters.getterC(1)
- 每次都会去进行调用,而不会缓存结果
- mapGetters: 将getters数据映射到局部(组件)计算属性
Mutation 类似于事件
同步事务
用来更改Vuex的store中的状态
每个mutation包含
- 事件类型(type)
-
回调函数 (handler): 进行状态更改的地方,接收state作为第一个参数
- 通过store.commit方法 调用mutation handler
- (state, payload)=> {}
- payload: 向store.commit传入的额外的参数
需遵守Vue的响应规则
- store中初始化所有所需属性
- 添加新属性用 Vue.set(obj, 'newProp', 123); 或者 state.obj = { ...state.obj, newProp: 123}
Mutation必须是同步函数
devtools 不知道什么时候回调函数实际上被调用:在回调函数中进行的状态的改变都是不可追踪的
Action 异步事务
类似Mutation,不同在于:
- Action 提交的是mutation,而不是直接变更状态
- 可包含任意异步操作
Action函数接收与store实例具有相同方法和属性的context对象
actions: { // 常见用法,用es6的参数解构来简化代码 actionA({state, commit, getters, dispatch}) { } } // 使用action store.dispatch('actionA').then(() => { })
Module 模块
解决的问题:应用复杂时(有很多的状态和逻辑),store对象会很臃肿
每个模块拥有自己的state、getter、mutation、action、嵌套子模块module
命名空间
- 默认注册在
全局命名空间
,通过设置namespaced:true
可以使其成为带命名空间的模块(局部化
) -
带命名空间的模块内访问全局内容:
-
state & getters
getters: { // 局部化后 getterA: (state, getters, rootState, rootGetters) => { } } actions: { actionA: ({dispatch, commit, getters, rootGetters, state, rootState}) => { } }
- action & mutation: 第三参数设为{root: true}
action: () => { dispatch('actionA', null, { root:true }); committ('mutationA', null, { root:true }); }
-
-
在带命名空间的模块内注册全局action
actions: { actionA: { root: true, handler(namespacedContext, payload) { ... } } }
模块动态注册: store.registerModule('moduleName', {})
- Vue插件可以在store中附加新模块,从而使用vuex来管理状态。例如:vuex-router-sync
模块卸载:store.unregisterModule(moduleName)
保留state: store.registerModule('a', module, { preserveState: true })
模块重用:
const MyReusableModule = { state () { return { foo: 'bar' } }, // mutation, action 和 getter 等等... }
插件
在插件中不允许直接修改状态——类似于组件,只能通过提交 mutation 来触发变化。
const myPlugin = store => { // 当 store 初始化后调用 store.subscribe((mutation, state) => { // 每次 mutation 之后调用 // mutation 的格式为 { type, payload } }) } const store = new Vuex.Store({ // ... plugins: [myPlugin] })
严格模式
开启严格模式,仅需在创建 store 的时候传入 strict: true
const store = new Vuex.Store({ // ... strict: true })
在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试 工具 跟踪到
不要在发布环境下启用严格模式: 严格模式会深度监测状态树来检测不合规的状态变更,会有性能损失
表单处理
严格模式下,不要用v-model绑定state数据
** 这样会不使用mutation对state数据进行更改
两种方法
- v-model绑定value,监听value变化然后在事件回调中使用mutation去修改state数据
-
双向绑定的计算属性
computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } } }
测试
热重载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Nginx 学习书单整理
- Java虚拟机学习笔记整理
- iOS开发学习路线 +技巧整理
- [机器学习]机器学习笔记整理09- 基于SVM图像识别
- [译] 精心整理,机器学习的 3 大学习资源
- kafka学习笔记:知识点整理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。