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中方法都实 ...
随机推荐
- AIRIOT物联网低代码平台如何配置欧姆龙omron驱动?
数据采集与控制是物联网的核心能力之一,AIRIOT物联网低代码平台提供了丰富的驱动,兼容了市面上95%以上的传感器.控制器及数据采集设备等,并且在持续增加中,能够快速.便捷地实现数据采集与控制功能. ...
- centos7下xfs文件系统的备份和恢复:完全备份,增量备份,差异备份
目录 一.关于xfs文件系统 二.xfsdump的备份级别和注意事项 三.完全备份整个目录/分区,然后恢复数据 四.完全备份分区中某个目录,然后恢复某个文件/文件夹 五.增量备份 一.关于xfs文件系 ...
- SQL KEEP 窗口函数等价改写案例
一哥们出条sql题给我玩,将下面sql改成不使用keep分析函数的写法. select deptno, ename, sal, hiredate, min(sal) keep(dense_rank f ...
- 算法金 | 详解过拟合和欠拟合!性感妩媚 VS 大杀四方
大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今天我们来战 过拟合和欠拟合,特别是令江湖侠客闻风丧胆的 过拟合,简称过儿, Emmm ...
- 企业签名打包错误+[MICodeSigningVerifier _validateSignatureAndCopyInfoForURL:withOptions:error:]:
一.问题现象 debug连接真机情况下面,编译正常,调试也是正常的. 使用企业签名命令行编译打包 xcodebuild -target dailybuildipa -configuration Dai ...
- Qt内存回收机制
参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=16 Qt中内存的回收是自己完成的,实验中,我们自定义一个按钮,通过重写析构函数来观察现象. 新建 ...
- 自动化搭建专属 AI 绘图服务
通义万相AIGC技术已经比较成熟,结合阿里云的计算和存储产品可以方便的搭建自己专属的 AI 绘图服务.例如<创意加速器:AI 绘画创作>这个解决方案,利用阿里自研的通义万相AIGC技术在 ...
- kettle从入门到精通 第六十一课 ETL之kettle 任务调度器,轻松使用xxl-job调用kettle中的job和trans
1.大家都知道kettle设计的job流程文件有个缺点:只能设置简单的定时任务,无法设置复杂的如支持cron表达式的job. 今天给大家分享一个使用xxl-job调度carte的流程文件的示例.整个调 ...
- C++常用模板
常用模板: 数学: 1. 组合数 组合数 #include<bits/stdc++.h> using namespace std; #define ll long long const l ...
- 手动解压安装mysql8.0 on windows my.ini
1.解压"mysql-8.0.24-winx64.zip"到d:\Soft 2.在"D:\Soft\mysql-8.0.24-winx64"目录新建一个my.i ...