写点什么

【Vuex 源码学习】第四篇 - Vuex 中 Getters 的实现

用户头像
Brave
关注
发布于: 3 小时前
【Vuex 源码学习】第四篇 - Vuex 中 Getters 的实现

一,前言


上篇,主要介绍了 Vuex 中 State 状态的实现,主要涉及以下几个点:


  • 创建 Store 类中的 State 状态;

  • 借助 Vue 实现 State 状态的响应式;


本篇,继续介绍 Vuex 中 getters 的实现;


二,前文回顾


在上一篇中,实现了 Vuex 中的 State 状态:

  • 创建了 Store 类,实例化时传入 options 选项;

  • 借助 Vue 实现 State 对象的响应式数据;

  • 通过属性访问器get state,提供外部访问 this._vm._data._$$state;


本篇继续处理 options 选项中的 getters 属性;

  • getters 属性是具有缓存效果的,相当于 Vue 中的 computed 属性;

  • 多次取值时,若值不变化就不会更新视图,即不会调用get state方法;


三,保存 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 的实现,主要涉及以下几个点:


  • 将选项中的 getters 方法,保存到 store 实例中的 getters 对象中;

  • 借助 Vue 原生 computed,实现 Vuex 中 getters 的数据缓存功能;


下一篇,Vuex 中 Mutation 的实现;

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Vuex 源码学习】第四篇 - Vuex 中 Getters 的实现