Vue3 之 computed 计算属性的使用与源码分析详细注释
计算属性的基本用法
computed 一般有两种常见的用法:
一:传入一个对象,内部有 set 和 get 方法,属于ComputedOptions
形式。在内部会有getter / setter
两个变量来进行保存.
const age = ref(18);
const myAge = computed({
get() {},
set() {},
});
二:传入一个 function,在内部会有getter
来进行保存.
const age = ref(18);
const myAge = computed(() => {
return age.value + 10;
});
计算属性的源码
计算属性的源码大部分是依赖 effect 的实现。基于上一篇文章对 effect 源码的理解,effect 可以传递一个函数和一个对象 options。
而计算属性的本质就是一个 effect,在之前 effect 的源码中预先声明了 lazy
和scheduler
属性,就是用于计算属性,因为计算属性默认不会被执行,
lazy 表示 effect 不会立即被执行,scheduler 会在 trigger 中判断是否传入了 scheduler,传入就执行 scheduler 方法。
scheduler 中,判断当前的_dirty 是否为 false,会把_dirty 置为 true,且执行 trigger 触发响应。
computed 也是基于类实现 ComputedRefImpl
其中 share.ts、effect.ts 文件中的方法,不在赘述,详见上一篇 响应式原理的文章
// computed.ts
import { isFunction, TrackOpTypes, TriggerOrTypes } from "./shared";
import { effect, track, trigger } from "./effect";
class ComputedRefImpl {
public _dirty = true; // 默认取值时不要用缓存
public _value;
public effect;
constructor(getter, public setter) {
this.effect = effect(getter, {
// 1. 计算属性本身就是一个effect
lazy: true, // 2. 默认不执行
scheduler: () => {
if (!this._dirty) {
this._dirty = true;
trigger(this, TriggerOrTypes.SET, "value");
}
},
});
}
get value() {
// 3.计算属性也要收集依赖,vue2中计算属性不具备收集依赖的,
if (this._dirty) {
this._value = this.effect(); // 4. 会将用户的返回值返回 也就是computed中 return
this._dirty = false; // 5. 设置缓存
}
track(this, TrackOpTypes.GET, "value"); // 6. 依赖收集: 因为可能会在effect中使用计算属性
/**
* const age = ref(18)
const myAge = computed(() => { // 此方法默认不会被执行
return age.value + 10;
})
// 当访问属性的时候执行
console.log(myAge.value)
console.log(myAge.value) // 多次取值,只取第一次执行结果走缓存
age.value = 100; // 更新age,myAge不会立刻重新计算
console.log(myAge.value) // 取值时才会重新计算
effect(() => { // 此effect中没有age 但是用到了计算属性,因此也需要依赖收集
console.log(myAge.value)
})
age.value = 500 // 收集依赖后,属性值更新,需要在scheduler中触发trigger执行,
*/
return this._value; // 7. 多次取值,只取第一次执行结果走缓存
}
set value(newValue) {
this.setter(newValue);
}
}
// 1. 如果getterOrOptions是函数,会直接赋值给getter。并在用户进行复制操作时 给出只读提示
// 2. 否则getterOrOptions为对象,会将set和get分别赋值给setter,getter。
export function computed(getterOrOptions) {
let getter;
let setter;
// 1. 如果getterOrOptions是函数,会直接赋值给getter。并在用户进行复制操作时 给出只读提示
if (isFunction(getterOrOptions)) {
getter = getterOrOptions;
setter = () => {
console.warn("computed value must be readonly");
};
} else {
// 2. 否则getterOrOptions为对象,会将set和get分别赋值给setter,getter。
getter = getterOrOptions.get;
setter = getterOrOptions.set;
}
return new ComputedRefImpl(getter, setter); // 3. 创建一个计算属性实例
}
shared 工具方法抽离
// share.ts
export const isFunction = (value) => typeof value == "function";
Vue3 之 computed 计算属性的使用与源码分析详细注释的更多相关文章
- vue computed计算属性和watch监听属性解疑答惑
computed计算属性 计算属性类似于方法,用于输出data中定义的属性数据的结果,data数据变化时,计算属性的结果会同步变化,需要注意的是计算属性不可与data定义的属性同名. 相比于方 ...
- Vue之computed计算属性
demo.html <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/19 ...
- 深入理解 Vue Computed 计算属性
Computed 计算属性是 Vue 中常用的一个功能,我们今天来说一下他的执行过长 拿官网简单的例子来看一下: <div id="example"> <p> ...
- Vue(七):computed计算属性
简介 计算属性关键词: computed. 计算属性在处理一些复杂逻辑时是很有用的. 实例1 可以看下以下反转字符串的例子: <div id="app"> {{ mes ...
- Vue的computed计算属性是如何实现的
一个开始 有如下代码,full是一个计算属性,开始,他的值是'hello world',1s后,msg变成了‘I like’, full的值同步变成了'I like world';其原理解析来看一下. ...
- 043——VUE中组件之使用.sync修饰符与computed计算属性实现购物车原理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- computed 计算属性
wepyjs - 小程序组件化开发框架 https://tencent.github.io/wepy/document.html#/?id=wepy%e9%a1%b9%e7%9b%ae%e7%9a%8 ...
- vue computed计算属性 watch监听
计算属性 computed:{ 变量:function(){ return 计算好的值 } } 这时候计算好的值 就付给了你的变量 在实例中可以this.使用 注意 声明的变量的data中不可以重复声 ...
- Vue.js 源码分析(六) 基础篇 计算属性 computed 属性详解
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护,比如: <div id="example">{{ messag ...
- vue-methods方法与computed计算属性的差别
好吧,我就是单纯的举个例子:实现显示变量 message 的翻转字符串 第一种:methods:我们可以通过在表达式中调用方法来达到同样的效果: 第二种:computed:计算属性 上面的2中方法都实 ...
随机推荐
- k8s证书相关
1.cfssl 字签证书 查看证书 可以使用以下命令查询CFSSL证书是否过期: 复制代码 cfssl certinfo -cert <certificate_file> 其中,< ...
- 一文了解npm install -g和npm install --save-dev的关系
本文分享自华为云社区<npm install -g 和 npm install --save-dev 的关系>,作者: SHQ5785. 一.npm install 本地安装 将安装包放在 ...
- Qt内存回收机制
参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=16 Qt中内存的回收是自己完成的,实验中,我们自定义一个按钮,通过重写析构函数来观察现象. 新建 ...
- 原来Stable Diffusion是这样工作的
stable diffusion是一种潜在扩散模型,可以从文本生成人工智能图像.为什么叫做潜在扩散模型呢?这是因为与在高维图像空间中操作不同,它首先将图像压缩到潜在空间中,然后再进行操作. 在这篇文章 ...
- 任意树遍历,可以使用 goto 跳记号标注的
先顺序进入到最后一个根的根部,完后扫描同级 同级扫描完用 goto跳代码改层数到倒数地二层 之后操作就是倒着往上搜索的,有难度,但是还是能做到的嘛 用 lisit 好像不需要别的,全用 list 连接 ...
- windows server 2016 远程桌面连接,发生身份验证错误。 要求的函数不受支持
远程桌面连接,发生身份验证错误. 要求的函数不受支持 客户端:WIN7 服务端:windows server 2016 在被远程的机器上-远程设置中-取消"仅允许运行使用网络级别身份验证的远 ...
- redis自动化安装
1.ruby脚本自动化安装 1.安装ruby开发环境 yum install rubygems -y 2.通过ruby包管理工具,安装操作redis的模块 gem sources --remove h ...
- zabbix分布式proxy
1.为什么要学zabbix-proxy https://www.zabbix.com/documentation/4.0/zh/manual/distributed_monitoring/proxie ...
- Mac 上切换 node 版本总结
Mac 上切换 node 版本总结 背景 在做项目的时候,往往会遇到老项目没有升级的问题,node环境版本比较低,自己电脑安装或者新项目安装了最新版本的 node 环境,那么既要支持老版本的使用也要支 ...
- 向web服务器下载文件
web服务器向客户端发送文件 Web服务器读取一个文件的二进制数据,把这组二进制数据发送个客户端,服务器发送给客户端的HTML文档的本质也是二进制.客户端使用以下代码读文件 response = ur ...