一,前言
上篇,主要介绍了 Vuex 中 State 状态的实现,主要涉及以下几个点:
创建 Store 类中的 State 状态;
借助 Vue 实现 State 状态的响应式;
本篇,继续介绍 Vuex 中 getters 的实现;
二,前文回顾
在上一篇中,实现了 Vuex 中的 State 状态:
创建了 Store 类,实例化时传入 options 选项;
借助 Vue 实现 State 对象的响应式数据;
通过属性访问器get state
,提供外部访问 this._vm._data._$$state
;
本篇继续处理 options 选项中的 getters 属性;
三,保存 options 选项中的 getters 属性
Object.defineProperty 将 options.getters
中用户定义的方法,保存到 Store 实例中this.getters
:
// src/vuex/store.js
import applyMixin from "./mixin";
export let Vue;
export class Store {
constructor(options) { // options:{state, mutation, actions}
// 处理 getters...
// options.getters;// 外部传入选项中的 getters:内部包含多个方法
this.getters = {};// 声明 store 实例中的 getters 对象
// 页面通过“{{this.$store.getters.getPrice}}”取值,取的是 getters 对象中的属性
// 所以,需要将将用户传入的 options.getters 属性中的方法,转变成为 store 实例中的 getters 对象上对应的属性
Object.keys(options.getters).forEach(key=>{
Object.defineProperty(this.getters, key, {
// 取值操作时,执行 options 中对应的 getters 方法
get: () => options.getters[key](this.state)
})
});
}
}
复制代码
此时,当页面通过{{this.$store.getters.getPrice}}
访问 store 实例中 getters 对象中的 getPrice 属性时,实际访问的是 options.getters
中的 getPrice 方法;
四,Vuex 中 getters 缓存效果实现
我们说,vuex 中的 getters 属性是具有缓存效果的;
修改 App.vue,尝试多次调用 store 实例 getters 对象中的属性:
<template>
<div id="app">
商品数量: {{this.$store.state.num}} 个<br>
订单金额: {{this.$store.getters.getPrice}} 元<br>
订单金额: {{this.$store.getters.getPrice}} 元<br>
订单金额: {{this.$store.getters.getPrice}} 元<br>
</div>
</template>
复制代码
打印 getters 方法执行 log:
// src/store/index.js
import Vue from 'vue';
import Vuex from '@/vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
num: 10
},
getters: {
getPrice(state) {
console.log("进入 getters - getPrice")
return state.num * 10
}
}
});
export default store;
复制代码
执行结果:
页面中三次访问 store 实例中 getters 属性中的 getPrice 方法,控制台会打印三次 log,这说明了每次访问都会真正调用一次 getters 中定义的方法,目前 Vuex 的 getters 是不具备缓存效果的;
如何实现 Vuex 中 getters 缓存功能?
可以利用 Vue 中原生的 computed 计算属性:
// src/vuex/store.js
import applyMixin from "./mixin";
export let Vue;
export class Store {
constructor(options) { // options:{state, mutation, actions}
// 获取 options 选项中的 state 对象
const state = options.state;
// 获取 options 选项中的 getters 对象:内部包含多个方法
const getters = options.getters;
// 声明 store 实例中的 getters 对象
this.getters = {};
// 将 options.getters 中的方法定义到计算属性中
const computed = {}
// 页面通过“{{this.$store.getters.getPrice}}”取值,取的是 getters 对象中的属性
// 所以,需要将将用户传入的 options.getters 属性中的方法,转变成为 store 实例中的 getters 对象上对应的属性
Object.keys(getters).forEach(key => {
// 将 options.getters 中定义的方法,放入计算属性 computed 中,即定义在 Vue 的实例 _vm 上
computed[key] = () => {
return getters[key](this.state)
}
// 将 options.getters 中定义的方法,放入store 实例中的 getters 对象中
Object.defineProperty(this.getters, key, {
// 取值操作时,执行计算属性逻辑
get: () => this._vm[key]
})
});
this._vm = new Vue({
data: {
$$state: state
},
computed // 将 options.getters 定义到 computed 实现数据缓存
})
}
}
复制代码
运行查看效果:
多次访问 store 实例中 getters 属性中的 getPrice 方法,控制台仅输出 1 次 log,说明已成功实现 Vuex 的 getters 缓存效果;
五,结尾
本篇,介绍了 Vuex 中 getters 的实现,主要涉及以下几个点:
下一篇,Vuex 中 Mutation 的实现;
评论