理解vue2中的computed计算属性与缓存机制

  1. vue实例组件初始化过程中,在执行initState(vm)方法初始化状态时,判断options.computed有值时会进行initComputed$1(vm,options.computed)处理
function initState(vm) {let options = vm.$options;// 省略props methods data的处理// 处理计算属性computedif (options.computed) {initComputed$1(vm, options.computed)}
}
  1. 执行initComputed$1方法,每个计算属性都会创建一个watcher观察者实例,用来依赖追踪。然后执行defineComputed方法,把每个计算属性都直接绑定在vm实例上
function initComputed$1(vm, computed) {let watchers = Object.create(null)vm._computedWatchers = watchersfor (let key in computed) {let userDef = computed[key]let getter = typeof userDef === 'function' ? userDef : userDef.get// 每个计算属性创建一个watcher观察者实例// lazy:true 默认不执行watchers[key] = new Watcher(vm, getter, null, { lazy: true })defineComputed(vm, key, userDef);}
}
  1. 执行defineComputed方法,使用Object.defineProperty()进行数据劫持
let sharedPropertyDefinition = {enumerable: true,configurable: true,get: function() {},set: function() {}
};function defineComputed(target,key,userDef) {if (typeof userDef === 'function') {sharedPropertyDefinition.get = createComputedGetter(key)sharedPropertyDefinition.set = function() {}} else {sharedPropertyDefinition.get = createComputedGetter(key)sharedPropertyDefinition.set = userDef.set}Object.defineProperty(target,key,sharedPropertyDefinition)
}
  1. createComputedGetter方法的返回函数是计算属性的get方法,当在模板编译挂载DOM时第一次读取了计算属性,就是触发计算属性的get方法。首先是拿到该计算属性的watcher观察者实例,执行watcher.evluate(),将dirty值置为false,触发计算属性对应watcher的getter方法。在此方法中访问响应式数据时会被响应式数据进行依赖收集,最后将计算属性计算结果进行缓存与返回。
function createComputedGetter(key) {return function() {let watcher = this._computedWatchers && this._computedWatchers[key]if (!watcher) returnif (watcher.dirty) {watcher.evaluate();}// 计算属性中的响应式数据依赖收集渲染watcher// 保证响应式数据变化时,触发渲染watcher的更新,再触发计算属性的读取get方法if (Dep.target) { watcher.depend();}return watcher.value}
}// 针对computed的简写
class Watcher {constructor(vm, expOrFn, cb, options) {// ....this.vm = vmthis.lazy = truethis.dirty = this.lazythis.getter = expOrFn// 首次不会执行this.value = this.lazy ? undefined : this.get();}evaluate() {this.value = this.get();this.dirty = false;}get() {pushTarget(this); // 赋值Deplet vm = this.vm;let value = this.getter.call(vm, vm);popTarget();this.cleanupDeps();return value}update() {if (this.lazy) {this.dirty = true;}}
}
  1. 当计算属性依赖追踪的响应式数据值有变化时,会执行该计算属性对应watcher的update方法,在该方法中会将dirty值置为true
class Watcher {......update() {if (this.lazy) {this.dirty = true;}}
}
  1. 下次再访问计算属性时,会判断该计算属性对应的watcher实例中的dirty值。如果值为false,表明计算属性依赖追踪的响应式数据未发生变化,则无需进行任何处理,直接拿上一次处理的缓存结果即可。如果值为true,表示追踪的响应式数据有变化,需重新执行watcher.evluate(),更新缓存结果并将新结果返回。

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

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

相关文章

蓝桥杯 【日期统计】【01串的熵】

日期统计 第一遍写的时候会错了题目的意思,我以为是一定要八个整数连在一起构成正确日期,后面发现逻辑明明没有问题但是答案怎么都是错的才发现理解错了题目的意思,题目的意思是按下标顺序组成,意思就是可以不连续,我…

JavaScript的函数基础

目录 前言: 1.函数是什么: 2.函数的基本使用: 2.1 定义函数: 2.2. 调用函数 2.3函数命名规范: 2.3.1由数字、字母、下划线组成: 2.3.2区分大小写: 2.3.3不能数字开头,也不能是关键字: 2.3.4自定义函数纯小写&#xff1a…

set feedback 和set define

set feedback set feedback有三种方式 set feedback on set feedback off set feedback n set feedback on: 打开反馈 默认情况下,当一条 sql 语句执行的时候,oracle 会给一个反馈,比如:创建表的时候,如果成功&#x…

PaddleOCR超大分辨率文本检测代码教程

PaddleOCR超大分辨率文本检测代码教程 目录 1.前提 2.PaddleOCR部署(win10下) 3.解决思路和代码 1.前提 这是我提的issue:https://github.com/PaddlePaddle/PaddleOCR/issues/11888 很多问题可以看:https://github.com/Paddle…

day22java学习打卡:自定义数组的工具类

//自定义数组的工具类: public class ArrayUtilTest { public static void main(String[] args) { ArrayUtil utilnew ArrayUtil(); int[] arrnew int[] {12,23,56,76,45,9,-98}; int maxutil.getMax(arr); System.…

【操作系统API系统调用】

原理 操作系统的API调用通常在应用程序进程的上下文中执行。当一个应用程序调用操作系统的API时,操作系统会在该应用程序进程的内存空间中分配资源(如内存、文件描述符等)并执行相应的操作。因此,在调用操作系统API时&#xff0c…

信阳附大医院-市民心中的健康守护者

信阳附大医院,一所集医疗、预防、保健、科研、教学、康复于一体的现代化综合医院,坐落于信阳市工区路600号,是市卫生部门批准成立的医疗机构,更是市民心中的健康守护者. 医院环境优雅,设施先进,服务周到,汇聚了一支技术精湛、经验丰富的医疗团队.医师们以患者为中心,用心倾听,精…

产品经理功法修炼(4)之产品管理

点击下载《产品经理功法修炼(4)之产品管理》 产品经理功法修炼(1)之自我管理 产品经理功法修炼(2)之专业技能 产品经理功法修炼(3)之产品设计 产品经理功法修炼(4)之产品管理 产品经理功法修炼(5)之团队管理 1. 前言 产品经理的能力修炼并非局限于某一技能的…

【UE 网络】DS框架学习路线

目录 0 引言1 如何学习DS框架1. 熟悉Unreal Engine基础2. 学习网络编程基础3. 掌握UE网络概念4. 实践和实验5. 加入社区和论坛6. 官方示例和案例研究7. 专业书籍和在线课程 2 DS框架重要知识点有哪些1. 网络复制2. 远程过程调用(RPC)3. 客户端服务器架构…

基于单片机16路多路抢答器仿真系统设计

**单片机设计介绍,基于单片机16路多路抢答器仿真系统设计 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机16路多路抢答器仿真系统的设计概要主要涵盖硬件设计、软件编程以及功能实现等方面。以下是针对该设计的详细概…

Mac系统Unity团结引擎打包OpenHomeny项目配置

1、团结引擎下载:直接百度下载即可 2、mac版本的DevEco4.0编辑器下载: widthdevice-width,initial-scale1.0https://docs.openharmony.cn/pages/v4.0/zh-cn/release-notes/OpenHarmony-v4.0-release.md/#%E9%85%8D%E5%A5%97%E5%85%B3%E7%B3%BB3、打开D…

实现RAG:使用LangChain实现图检索查询

你是不是有时会遇到这样的问题:你可能遇到的任何主题或问题,都有大量的文档,但是当尝试将某些内容应用于自己的用途时,突然发现很难找到所需的内容。 在这篇博文中,我们将看一下LangChain是如何实现RAG的,这…

2024年贵州省职业院校技能大赛云计算应用赛项赛题第2套

#需要资源(软件包及镜像)或有问题的,可私聊博主!!! #需要资源(软件包及镜像)或有问题的,可私聊博主!!! #需要资源(软件包…

一次部署,多处运行:Docker容器化开发

一、引言 Docker是一种流行的容器化技术,可用于在多个平台下保持软件运行的一致性、轻松地实现应用程序移植性,以及提高开发、测试、部署和管理过程的效率。Docker容器化开发可以改变传统软件运行、部署、管理与维护的方式,使其更加灵活和高…

产品经理和项目经理的区别

1. 前言 本文深入探讨了产品经理与项目经理在职责、关注点以及所需技能方面的显著区别。产品经理主要负责产品的规划、设计和市场定位,强调对用户需求的深刻理解和产品创新的推动;而项目经理则侧重于项目的执行、进度控制和资源管理,确保项目按时、按质、按预算完成。两者在…

在NBA我需要翻译--适配器模式

1.1 在NBA我需要翻译! "你说姚明去了几年,英语练出来了哦,我看教练在那里布置战术,他旁边也没有翻译的,不住点头,瞧样子听懂没什么问题了。" "要知道,最开始&#xff0c…

03-JAVA设计模式-原型模式

原型模式 什么是原型模式 Java原型模式(Prototype Pattern)是一种创建型设计模式,其核心理念在于通过复制(克隆)已有的对象来创建新的对象,而不是通过构造函数来创建。 该模式可以显著提高对象创建的效率…

vue的一些特性

Vue.js 是一个构建用户界面的渐进式框架,它有很多特性和优点使得开发者能够高效地构建复杂的Web应用。除了之前提到的组件化、轻量级、虚拟DOM和MVVM数据绑定等特性,Vue还有以下一些显著特性: 响应式数据绑定:Vue.js 的核心库只关…

LeetCode 9.回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数 是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文,…

图论基础入门

一、存图 存图方式一共有三种:邻接矩阵、邻接表、前向星 纯前向星还需要再加上排序的时间复杂度(当排序不是主要复杂度时适用),如果快排,时间复杂度是O(n log n),可以用别的排序方式优化,即基数…