Vue2 - computed 和 method 的原理区别

目录

  • 1,简单对比
  • 2,原理的不同
    • 1,method 的处理
    • 2,computed 的处理
      • 实现缓存
      • 触发更新
  • 3,触发更新时的问题

1,简单对比

  1. computed 当做属性使用,method 当做方法使用。
  2. computed 可以提供 getter 和 setter 来赋值。
  3. computed 无法接收多个参数。
  4. computed 有缓存。

2,原理的不同

1,method 的处理

处理比较简单,只需要遍历 methods 配置的每个属性,将其对应的函数通过 bind 绑定到当前实例。之后复制其引用到组件实例即可(为了通过 this 可访问)。

// 伪代码
function Vue(options) {// ...// 其他代码// ...Object.entries(options.methods).forEach(([methodName, fn]) => {this[methodName] = fn.bind(this);});
}new Vue(vnode.componentOptions);

2,computed 的处理

在触发组件的生命周期函数 beforeCreate后,会做一系列的事情,其中包括对 computed 的处理:

  1. 遍历 computed 配置中的所有属性,对每个属性都创建一个 Watcher 对象,并传入一个函数。该函数本质上就是 computed 的 getter。之后 getter 触发时就会收集依赖。

数据响应式中 Watcher 原理参考。
简单来说,为了监听响应式数据的变化来触发更新,Vue 会将使用了响应式数据的函数(模板对应 render 函数)通过 Watcher 记录下来(收集依赖)。之后响应式数据发生变化,就会通知对应的 Watcher 来执行对应的函数触发更新。

  1. Watcher 创建好之后,vue 会使用代理模式,将计算属性挂载到组件实例上(为了通过 this 访问)。

  2. 不同于渲染函数 render 的 Watcher,为计算属性创建的 Watcher 不会立即执行。因为要考虑该计算属性是否被使用(渲染函数或其他方法中),没使用就不会执行。所以在创建 Watcher 时配置了一个 lazy 属性,lazy === true 时 Watcher 不会立即执行。

实现缓存

  1. 受到 lazy 的影响,Watcher 内部还会配置2个属性:value 和 dirty

    • value,保存 Watcher 运行时的结果,一开始(Watcher 还没有执行时)为 undefined。
    • dirty,标记当前 value 是否过期,一开始为 true。
  2. 当读取计算属性时,会先检查 dirty,

    • 为 true 时则运行之前传入 Watcher 的函数(也就是计算属性的 getter),将计算依赖得到的值保存在 Watcher 的 value 中,同时设置 dirty = false。
    • 为 false,则直接返回 Watcher.value,也就是缓存的值。

触发更新

  1. 为了实现更新,在收集依赖时,被依赖的数据不仅会收集计算属性的 Watcher,还会收集组件的 Watcher。

  2. 当计算属性变化时,会先触发计算属性的 Watcher,但只会将 dirty = true,其他不做处理。之后触发组件的 Watcher 重新渲染。render 函数(或模板)又读取了计算属性,因为dirty === true,所以会重新运行 getter 计算。

  3. 设置计算属性时比较简单,直接运行 setter 即可。

3,触发更新时的问题

注意到上面触发更新时,如果计算属性的依赖发生变化,但计算属性没有在模板(或render函数)中使用时(其他方法或watch场景同理),虽然会触发计算属性的 Watcher,但不会触发同时收集到的组件的 Watcher。

举例:

<template><div><h1 v-if="showName">{{ fullName }}</h1><button @click="handleClick">隐藏 fullName</button></div>
</template><script>
export default {data() {return {firstName: '渣渣',lastName: '辉',showName: true}},computed: {fullName: {get() {return this.firstName + ' ' + this.lastName},set(newValue) {;[this.firstName, this.lastName] = newValue.split(' ')}}},methods: {handleClick() {this.firstName = '123' // 计算属性依赖发生变化this.showName = !this.showName}},updated() {console.log(this)}
}
</script>

showName === false 所以不渲染 h1,所以render 函数不会读取计算属性 fullName。

所以只会执行:

计算属性的依赖:
firstName: [计算属性的 Watcher,组件的 Watcher(对应render函数 )]
lastName: [计算属性的 Watcher,组件的 Watcher(对应render函数)]
showName: [组件的 Watcher]

动图展示


以上。

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

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

相关文章

Java研学-web操作crud

一 思路 1 组件 页面显示&#xff1a;JSP   接受用户请求&#xff1a;Servlet   和数据库交互&#xff1a;MyBatis 2 基础准备 ① 创建 web 项目&#xff0c;导入需要依赖的 jar 包,放入 web/WEB-INF/lib目录中 ② 创建数据库表 CREATE TABLE employee( id bigint(11)…

P12 音视频复合流——TS流讲解

前言 从本章开始我们将要学习嵌入式音视频的学习了 &#xff0c;使用的瑞芯微的开发板 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Linux C应用编程&#xff08;概念类&#xff09;_C…

限制选中指定个数CheckBox控件(1/2)

限制选中指定个数CheckBox控件&#xff08;1/2&#xff09; 实例需求&#xff1a;工作表中有8个CheckBox控件&#xff08;下文中简称为控件&#xff09;&#xff0c;现在需要实现限制用户最多只能勾选4个控件。 Dim OnDic As Object Sub CheckboxeEvent()Dim oCB As CheckBox…

OpenSource - File Preview 文件预览组件

文章目录 file-preview-spring-boot-starterkkFileView file-preview-spring-boot-starter https://github.com/wb04307201/file-preview-spring-boot-starter https://gitee.com/wb04307201/file-preview-spring-boot-starter 一个文档在线预览的中间件&#xff0c;可通过简…

hyperf 十九 数据库 二 模型

教程&#xff1a;Hyperf 一、命令行 symfony/console-CSDN博客 hypery 十一、命令行-CSDN博客 hyperf console 执行-CSDN博客 根据之前应该能了解到命令行的基本实现&#xff0c;和hyperf中命令行的定义。 1.1 命令初始化 hyperf.php中系统初始化中通过ApplicationFacto…

乐理燥废笔记

乐理燥废笔记 文章目录 终止式小调音阶转调不协和和弦进行大小转调1251 1451转调我的霹雳猫阿诺三全音代理五声音阶又怎样和弦附录&#xff1a;压缩字符串、大小端格式转换压缩字符串浮点数压缩Packed-ASCII字符串 大小端转换什么是大端和小端数据传输中的大小端总结大小端转换…

Golang高质量编程与性能调优实战

1.1 简介 高质量&#xff1a;编写的代码能否达到正确可靠、简洁清晰的目标 各种边界条件是否考虑完备异常情况处理&#xff0c;稳定性保证易读易维护 编程原则 简单性 消除多余的重复性&#xff0c;以简单清晰的逻辑编写代码不理解的代码无法修复改进 可读性 代码是写给人看…

Copilot在IDEA中的应用:提升编码效率的得力助手

Copilot在IDEA中的应用&#xff1a;提升编码效率的得力助手 前言: 欢迎来到本篇博客&#xff0c;今天我们将深入探讨 GitHub Copilot 在 IntelliJ IDEA 中的应用。GitHub Copilot 是一款由 GitHub 与 OpenAI 共同开发的人工智能代码生成工具&#xff0c;它能够根据上下文提示…

vue 异步加载组件

当页面引入多个组件并且有默认不展示的组件则可以进行异步加载&#xff08;引入的组件不进行初步渲染&#xff0c;只有需要的时候才加载&#xff09; 首先引入 defineAsyncComponent import { defineAsyncComponent } from "vue"; 然后引入组件 组件名自定义&…

【MybatisPlus Docker】

文章目录 MyBatisPlusMyBatisPlus 注解WrapperMybatisPlus批量插入(saveBatch)MyBatisPlus 分页插件 DockerDockerfileDocker网络Docker部署项目 黑马微服务文档 MyBatisPlus MyBatisPlus 注解 TableName TableId TableField MyBatisPlus也支持手写SQL的 mybatis-plus:map…

金山云升级全栈云计算体系,做人工智能时代云上“助力者”

随着云原生、AIGC、大模型等新兴技术的迅速发展&#xff0c;智能化时代开启。云计算也正全面步入3.0时代&#xff0c;即云计算和人工智能深度融合的阶段。在这个阶段&#xff0c;人工智能技术成为云计算进一步释放潜力的核心推动力。 2024年1月4日&#xff0c;金山云举办了「云…

水母目标检测数据集VOC格式500张

水母&#xff0c;一种美丽而神秘的海洋生物&#xff0c;以其独特的形态和生态习性而备受瞩目。 水母的体型呈伞状&#xff0c;身体透明&#xff0c;有各种颜色和花纹。它们没有骨骼&#xff0c;身体由胶状物质组成&#xff0c;非常柔软和脆弱。水母通过触手上的刺细胞释放毒素…

从零学Java Object类

Java Object类 文章目录 Java Object类Object类Object类中的方法1 getClass()方法2 hashCode()方法3 toString()方法4 equals()方法面试题: 和 equals 方法的区别? 5 finalize()方法&#xff08;JDK1.9放弃 了解即可&#xff09; Object类 所有类的直接或间接继承Object&…

TypeScript 从入门到进阶之基础篇(四) symbol类型篇

系列文章目录 TypeScript 从入门到进阶系列 TypeScript 从入门到进阶之基础篇(一) ts基础类型篇TypeScript 从入门到进阶之基础篇(二) ts进阶类型篇TypeScript 从入门到进阶之基础篇(三) 元组类型篇TypeScript 从入门到进阶之基础篇(四) symbol类型篇 持续更新中… 文章目录 …

win10关闭打开文件安全警告

1.使用场景 在流水线上&#xff0c;因车间刷软件的程序不能下发到每一台电脑上&#xff0c;会使用共享文件夹的形式来共享程序。每次打开会弹出一下窗口&#xff0c;影响员工生产。 需要将安全警告关闭。2.解决步骤 1.winR键打开运行窗口&#xff0c;输入gpedit.msc&#xff…

云原生学习系列之基础环境准备(单节点安装kubernetes)

一、环境要求 操作系统CentOS 7.x-86_x64 硬件配置&#xff1a;内存2GB或2G&#xff0c;CPU 2核或CPU 2核&#xff0c;需要在虚拟机中提前设置好&#xff0c;不然后续会报错 二、系统初始化 1、设置主机名 # 在master节点执行 hostnamectl set-hostname master01 2、配置主…

HTML的简单介绍

文章目录 1. HTML1.1 HTML 基础认识1.2 快速生成代码框架1.3 HTML 基础标签 1. HTML 1.1 HTML 基础认识 什么是HTML呢&#xff1f; HTML叫做超文本标记语言。超文本&#xff1a;例如图片&#xff0c;视频&#xff0c;文本&#xff0c;声音&#xff0c;表格&#xff0c;链接等…

C++的一点知识记录

时间记录&#xff1a;2024/1/6 类定义&#xff0c;一般在头文件中进行定义不进行实现&#xff0c;在源文件中进行实现 class Person{ public://公共属性和方法定义区Person();//构造函数定义~Person(){};//析构函数加实现int age;//定义属性void printAge();//定义方法 protec…

计算机环境安全

操作系统安全----比如windows,linux 安全标识--实体唯一性 windows---主体&#xff1a;账户&#xff0c;计算机&#xff0c;服务 安全标识符SID-Security Identifier 普通用户SID是1000&#xff0c;管理用SID是500 linux---主体&#xff1a;用户&#xff0c;用户组&#xf…

【前端】[vue3] vue-router使用

提示&#xff1a;我这边用的是typeScript语法&#xff0c;所以js文件的后缀都是ts。 安装vue-router&#xff1a; &#xff08;注意&#xff1a;vue2引用vue-router3 vue3才引用vue-router4&#xff09; npm install vue-router4src文件夹下面创建 router/index.ts&#xff08;…