前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1x0 Vuex 核心 - State & Mutations

1x0 Vuex 核心 - State & Mutations

作者头像
玖柒的小窝
修改2021-11-04 09:17:13
1.1K0
修改2021-11-04 09:17:13
举报
文章被收录于专栏:各类技术文章~

Store

单一状态树与唯一数据源

单一状态树指的是用一个对象来包含整个应用中所有层级的状态(Vuex 的 store 对象就是一个典型的单一状态树)。

状态等价于数据、因此单一状态树的架构模型也非常符合与 ”唯一数据源(SSOT)“的标准。

SSOT (Signle Source Of Truth) 唯一数据源(单一事实来源),它属于信息系统的范畴。强调的是数据与信息的高度统一和集成(存在一个主系统来管理跨系统共享的数据,例如增、删、改、链接关系等),它不是具体的工具或方法,而是一种标准或者架构。 基于 SSOT 实现的系统其目的在于提供真实、相关和可参考的数据。其解决的痛点在一般企业管理系统中非常常见,比如通常对于一个企业而言,它会在不同的供应商除购买多种不同且相互独立的系统,这些系统很可能会存储同一个实体有关的重复数据,并且这些相关的数据不会被共享,当数据发生变更时其它系统也不会进行相应的自动更新。 具体案例的中,例如 ERP(企业资源规划)、CRM(客户管理系统)、物流仓储调度系统等它们都会需要客户这一实体的相关数据,例如客户的姓名、行业、联系方式、收获地址等等。如果每个系统都存储着自己的公共数据或实体相关数据的副本,那么当实体的数据发生变更时,便不能保证数据来源的唯一、可靠与真实。再比如,对于像电子健康档案中的记录更需要基于 SSOT 架构来存储以及返回患者的信息,以保证数据与信息的准确唯一。

单一状态树的优势表现于对状态的定位、获取和调试都会变得更加的简单。

在 Vue 组件中获取 Vuex 状态的几种方式

  1. 通过模块化导入然后直接读取 [store.state](http://store.state.xxx) 状态的值,或者将其转换为组件的计算属性。 import store from '@/store' export default { computed: { count() { return store.state.count } }, created() { this.$watch(() => store.state.count, (newValue) => { console.log(newValue) }) } } 复制代码
  2. 使用 Vuex 通过根组件向所有子组件注入的 $store 选项 export default { template:`<div>{{$store.state.count}}</div>`, watch:{ '$store.state.count': (val) => { console.log(val)} } } 复制代码
  3. 使用 Vuex 提供的 mapState 工具方法可以将状态映射为组件实例的计算属性 (computed)。

mapState 工具方法

mapState 方法可以看做是对(方法一)的便捷操作,它可以批量的将 Vuex 状态映射为 Vue 组件的计算属性。

代码语言:javascript
复制
//对象取值
export default {
    computed: Vuex.mapState({
        count: 'count', //若计算属性名称与状态名称相同,则可以直接使用字符串的形式。
        foor: () => state.foor, //支持一个回调函数,且参数便是状态对象。
        bar: (state) => state.count + state.foor
    })
};

//数组取值
export default {
    computed: Vuex.mapState(['count', 'foor'])
}
复制代码

如果计算属性成员的名称与 Vuex 中状态的名称相同,那么数组取值的方式将会更加的简单方便。

展开运算符

mapState 函数返回值是一个对象,为了更方便的引用这些状态,我们可以使用 ES6 的展开运算符将对象混入到 computed 选项中作为其直接的属性成员。

代码语言:javascript
复制
import { mapState } from "vuex";

export default {
    computed: {
				foor: 'foor',
				bar : 'bar',
        //使用对象展开运算符将 mapState 的值混入到 computed 选项中。
        ...mapState(['count'])
    }
}
复制代码

在不支持 ES6 展开运算符的环境下则需要开发者自己编写对象的合并函数。

Mutations

提交与载荷

更改 Vuex 状态的唯一方式便是提交 Mutation,它非常类似于事件的概念,每个 Mutations 成员的 key 便是事件的类型(type),成员方法便是事件的处理方法 (handler),最后通过 store.commit(type) 的方式来触发事件处理方法的执行,从而进行状态的更改。

代码语言:javascript
复制
export default {
    state: { count: 0 },
    mutations: {
        increment(state) {
            ++state.count
        }
    }
}

store.commit('increment')
复制代码

通过 store.commit 触发事件的同时你还可以传入一个额外的参数,即 Mutation 的载荷(payload)。载荷的形式有多种,可以是基本类型值,也可以是对象类型值。

代码语言:javascript
复制
store.commit('increment', 1); //基本类型的值
store.commit('increment', { count: 1 }) //对象类型值
复制代码

对象形式的载荷还可以用一个 type 字段来替代 store.commit 中所要提交的事件类型。

代码语言:javascript
复制
store.commit({type:'increment',count:1})
复制代码

在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读。

不论载荷的风格是何种形式,Mutation 接收载荷的格式都是固定的。

代码语言:javascript
复制
{
    mutations: {
        increment(state, payload){
            state.state = typeof payload === 'object' ? payload.count : payload;
        }
    }
}
复制代码

mapMutations 工具方法

mapMutations 方法可以批量的将需要通过 store.commit 进行事件触发的操作映射为组件私有的 methods,以达到更方便调用的目的。

代码语言:javascript
复制
//对象取值
export default {
		template:'<button @click="incrementAlis">add</button>'
    methods: Vuex.mapMutations(
        {
            incrementAlis: 'increment',
            increment: 'increment'
        }
    ),
}

//数组取值
export default {
    methods: Vuex.mapMutations(['increment']),
}
复制代码

Mutation 的相关规则

  1. 与状态变更相关的规则 由于 Vuex 存储的状态实际上就是普通 Vue 组件实例上的响应式数据,所以再使用 Mutation 进行状态变更时必须要遵守与 Vue 相同的注意事项:
    1. 状态最好要在创建 Vuex 应用时就已经手动声明好。
    2. 对于后期需要动态添加的状态,请使用 Vue.set(obj, 'count', 1) 方法,或使用 ES6 展开运算符扩展原有的响应式对象。 state.obj = { ...state.obj, newProp: 123 }
  2. 使用常量替代 Mutation 事件类型 在 Flux 架构中使用常量来替代事件类型名称是一种很常见的模式,其优点主要有两个方面:
    1. 对 Linter 之类的工具更加友好。
    2. 可以将这些常量统一抽离到一个公共文件中以使代码结构更加清晰,对合作的开发者更加友好,也让这个应用所包含的 Mutation 一目了然。

    // mutation-types.js export const SOME_MUTATION = 'SOME_MUTATION' // store.js import Vuex from 'vuex' import { SOME_MUTATION } from './mutation-types' const store = new Vuex.Store({ state: { ... }, mutations: { // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名 [SOME_MUTATION] (state) { // mutate state } } }); 复制代码

  3. 必须要保证 Mutation 的成员方法必须是一个同步函数。 只有满足了同步变更的前提,我们才能追踪状态变更的前后顺序,保证记录的准确性,因此 Mutation 的成员方法一定不能是一个异步方法。 对于异步的事务变更我们可以使用 —— Action。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单一状态树与唯一数据源
  • 在 Vue 组件中获取 Vuex 状态的几种方式
  • mapState 工具方法
  • 展开运算符
  • Mutations
    • 提交与载荷
      • mapMutations 工具方法
        • Mutation 的相关规则
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档