【手写 Vuex 源码】第四篇 - Vuex 中 Getters 的实现

news2025/1/17 14:01:18

一,前言

上篇,主要介绍了 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;

执行结果:

image.png

页面中三次访问 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 实现数据缓存
    })
  }
}

运行查看效果:

image.png

多次访问 store 实例中 getters 属性中的 getPrice 方法,控制台仅输出 1 次 log,说明已成功实现 Vuex 的 getters缓存效果;


五,结尾

本篇,介绍了 Vuex 中 getters 的实现,主要涉及以下几个点:

  • 将选项中的 getters 方法,保存到 store 实例中的 getters 对象中;
  • 借助 Vue 原生 computed,实现 Vuex 中 getters 的数据缓存功能;

下一篇,Vuex 中 Mutation 的实现;


维护日志

  • 20210831
    • 修改部分错别字

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/335328.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VHDL语言基础-时序逻辑电路-寄存器

目录 寄存器的设计&#xff1a; 多位寄存器&#xff1a; 多位寄存器的VHDL描述: 移位寄存器&#xff1a; 串进并出的移位寄存器的VHDL描述: 寄存器的设计&#xff1a; 多位寄存器&#xff1a; 一个D触发器就是一位寄存器&#xff0c;如果需要多位寄存器&…

飞凌嵌入式RK3568J核心板助力工业机器人产业迈向高质量发展新阶段

工业机器人是能够代替人工完成高强度重复工作的多自由度机器装置&#xff0c;不仅可以确保产品质量&#xff0c;还可以大幅提高生产效率。据工信部数据显示&#xff0c;“十三五”期间我国工业机器人产量从7.2万套增长到了21.2万套&#xff0c;年均增长31%&#xff0c;预计2023…

切换分支报错:Untracked Files Prevent Checkout

切换分支报错&#xff1a;Untracked Files Prevent Checkoutgit分支切换 Untracked Files Prevent Checkout本人解决办法&#xff1a;git分支切换 Untracked Files Prevent Checkout 新起的项目在切换master分支到工作分支时&#xff0c;出现下图的问题&#xff1a; Untracked…

【机器学习】过拟合与正则化

上一章——逻辑回归 文章目录三种拟合状态解决过拟合的三种方法什么是正则化正则化的数学原理线性回归恭喜三种拟合状态 在之前的课程中&#xff0c;我们说过机器学习的中极为重要的一步&#xff0c;就是给训练集找到一条合适的拟合曲线。 还是以房价问题这个回归问题为例&…

【微服务】微服务架构超强讲解,通俗易懂

微服务架构目录一、微服务架构介绍二、出现和发展三、传统开发模式和微服务的区别四、微服务的具体特征五、面向服务的架构SOA&#xff08;service oriented architecture&#xff09;和微服务的区别1、SOA喜欢重用&#xff0c;微服务喜欢重写2、SOA喜欢水平服务&#xff0c;微…

Linux教程:MQTT入门基础概念与学习介绍及服务部署搭建并使用桌面工具进行测试开发

前言&#xff1a; ----在2023年的今天&#xff0c;智能家居与智能家电的兴起犹如滚滚长江迅速袭来&#xff0c;智能终端设备也不断出现在人们的视野当中&#xff0c;实现远程控制&#xff0c;其中必然不能缺少终端与终端&#xff0c;终端与服务之间的交互&#xff0c;如何来解…

ag-Grid Enterprise

ag-Grid Enterprise Ag-Grid被描述为一种商业产品&#xff0c;已在EULA下分发&#xff0c;它非常先进&#xff0c;性能就像Row分组一样&#xff0c;还有范围选择、master和case、行的服务器端模型等等。 ag Grid Enterprise的巨大特点&#xff1a; 它具有以下功能和属性&#x…

Docker调用Intel集显实现FFmpeg硬解码

文章目录Docker调用Intel集显实现FFmpeg硬解码参考FFmpeg 集成qsv方式一 容器完成所有步骤方式二 容器完成部分步骤方式三 dockerfile部署Docker调用Intel集显实现FFmpeg硬解码 参考 ffmpeg_qsv_docker拉取该镜像可以实现FFmpeg集成vaapi的硬加速&#xff0c;通过dockerfile文…

什么是特权访问管理(PAM)

特权访问管理 &#xff08;PAM&#xff09; 是指一组 IT 安全管理原则&#xff0c;可帮助企业隔离和管理特权访问、管理特权帐户和凭据、控制谁可以获得对哪些端点的管理访问权限级别&#xff0c;并监视用户对该访问权限执行的操作。 什么是特权访问 特权访问是一种 IT 系统访…

2023.2.10学习记录Docker容器

Docker 必须跑在Linux内核上 镜像是一个轻量级可执行的独立软件包 新建一个docker容器只需要几秒钟 Docker常用命令 启动类命令 镜像命令 容器命令 docker images docker search --limit 5 redis docker pull redis:6.0.8 docker system df 查看镜像/容器/…

使用QT中的绘画工具与定时器工具实现简易时钟

需求&#xff1a;使用QT中的绘画工具与定时器工具实现简易时钟代码实现过程&#xff1a;widget.h#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QPainter> //引入画家类 #include<QPaintEvent> //引入绘制事件类 #include&l…

vue-router 源码解析(三)-实现路由守卫

文章目录基本使用导语初始化路由守卫useCallbacks 发布订阅模式管理路由守卫push 开始导航resolve返回路由记录匹配结果navigate 开始守卫抽取路由记录guardToPromiseFn 用Promise包装守卫方法extractComponentsGuards 从组件中抽取守卫beforeRouteLeave 守卫收集composition 守…

error: failed to push some refs to ... 就这篇,一定帮你解决

目录 一、问题产生原因 二、解决办法 三、如果还是出问题&#xff0c;怎么办&#xff1f;&#xff08;必杀&#xff09; 一、问题产生原因 当你直接在github上在线修改了代码&#xff0c;或者是直接向某个库中添加文件&#xff0c;但是没有对本地库同步&#xff0c;接着你想…

【数据结构初阶】第三节.顺序表详讲

文章目录 前言 一、顺序表的概念 二、顺序表功能接口概览 三、顺序表基本功能的实现 四、四大功能 1、增加数据 1.1 头插法&#xff1a; 1.2 尾插法 1.3 指定下标插入 2、删除数据 2.1 头删 2.2 尾删 2.3 指定下标删除 2.4 删除首次出现的指定元素 3、查找数据…

JAVA-线程池技术

目录 概念 什么是线程&#xff1f; 什么是线程池&#xff1f; 线程池出现背景 线程池原理图 JAVA提供线程池 线程池参数 如果本篇博客对您有一定的帮助&#xff0c;大家记得留言点赞收藏哦。 概念 什么是线程&#xff1f; 是操作系统能够进行运算调度的最小单位。&am…

ChatGPT的解释

概念 ChatGPT&#xff0c;美国OpenAI研发的聊天机器人程序,于2022年11月30日发布。ChatGPT是人工智能技术驱动的自然 语言处理工具&#xff0c;它能够通过学习和理解人类的语言来进行对话&#xff0c;还能根据聊天的上下文进行互动&#xff0c;真正像人 类一样来聊天交流&am…

干货 | PCB拼板,那几条很讲究的规则!

拼板指的是将一张张小的PCB板让厂家直接给拼做成一整块。一、为什么要拼板呢&#xff0c;也就是说拼板的好处是什么&#xff1f;1.为了满足生产的需求。有些PCB板太小&#xff0c;不满足做夹具的要求&#xff0c;所以需要拼在一起进行生产。2.提高SMT贴片的焊接效率。只需要过一…

如何使用python画一个爱心

1 问题 如何使用python画一个爱心。 2 方法 桌面新建一个文本文档&#xff0c;文件后缀改为.py&#xff0c;输入相关代码ctrls保存&#xff0c;关闭&#xff0c;最后双击运行。 代码清单 1 from turtle import * def curvemove(): for i in range(200): right(1) …

Vue2笔记03 脚手架(项目结构),常用属性配置,ToDoList(本地存储,组件通信)

Vue脚手架 vue-cli 向下兼容可以选择较高版本 初始化 全局安装脚手架 npm install -g vue/cli 创建项目&#xff1a;切换到项目所在目录 vue create xxx 按照指引选择vue版本 创建成功 根据指引依次输入上面指令即可运行项目 也可使用vue ui在界面上完成创建&…

Python学习-----无序序列2.0(集合的创建、添加、删除以及运算)

目录 前言&#xff1a; 什么是集合 集合的三大特性 1.集合的创建 &#xff08;1&#xff09;直接创建 &#xff08;2&#xff09;强制转换 2.集合的添加 &#xff08;1&#xff09;add&#xff08;&#xff09;函数 &#xff08;2&#xff09;update() 函数 3.集合元…