Vue3.0 beta源码学习笔记(三)
今天继续总结学习Vue3.0的基本原理。computed(), 计算属性,在vue3.0中computed可以传入一个getter函数也可以传入getter与setter两个函数。
在computed模块中,首先处理处理用户传入的对象,在接收对象时分为一个参数与两个参数的情况,最终返回一个computed对象,在处理传入的对象时其实是调用effect模块,让其成为响应式的数据,所以computed也是另一种形式的effect。因此,在effect模块中要加入对computed类型的处理,分而治之,并且computed优先于一般的effect执行。大概思路就是这样,直接上代码:
export
function
computed(getterOrOptions) {
let getter; //接收传入的参数
let setter;
if (isFunction(getterOrOptions)) { //isFunction是自定义的工具函数
getter = getterOrOptions;
setter = ()=>{}
} else {
getter = getterOrOptions.get;
setter = getterOrOptions.set;
}
let dirty = true;//缓存机制的标志 控制是否触发依赖,达到缓存效果
let computed;
let runner = effect(getter, { //调用effect
lazy: true, //首次不执行
computed: true,//计算属性标识
scheduler: ()=>{ //在有新的依赖触发时effect负责执行
if (!dirty) {
dirty = true;//依赖值变化后 没有缓存数据了
trigger(computed,TriggerOpTypes.SET,'value') //触发依赖
}
}
})
let value;
computed = {
get value() {
if (dirty) { //多次取值 不会重复执行effect
value = runner();
dirty = false;
track(computed,TriggerOpTypes.GET,'value')//收集计算结果的依赖,使其成为响应式数据
}
return value;
},
set value(newValue) {
setter(newValue)
}
}
return computed;
}
effect中的配合
export
function
trigger(target, type, key, value, oldValue) {
//获取当前对应的map
const depsMap = targetMap.get(target);
if (!depsMap) {
return; //说明没有被收集过依赖
}
//计算属性优先于effect执行
const effects = new
Set(); //装普通effect
const computedRunners = new
Set(); //装计算属性的effect
//具体执行effect集合的方法
// const run = (effect) => {
// if (effect) {
// effect.forEach(effect => effect())
// }
// }
const run = (effect) => {
if (effect.options.scheduler) {
effect.options.scheduler()
} else {
effect();
}
}
let add = (effectsToAdd)=>{
if (effectsToAdd) {
effectsToAdd.forEach(effect => {
if (effect.options.computed) {
computedRunners.add(effect)
} else {
effects.add(effect)
}
})
}
}
if (key !== null) {
add(depsMap.get(key));
}
if (type === TriggerOpTypes.ADD) {
add(depsMap.get(Array.isArray(target) ? 'length' : ''))
}
computedRunners.forEach(run)
effects.forEach(run)
}
在触发effect中,增加了两个存储computed和effect的集合,通过add方法所有的依赖map中的effect分类,最后分开执行;
computed的实现基础还是effect,可以理解为effect的一种变形。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- jQuery点击click()事件
- 大点干!早点散----------深入剖析LVS负载均衡群集原理
- javascript中元素的scrollLeft和scrollTop属性说明
- 大点干!早点散----------LVS负载均衡之LVS-NAT部署实战
- 大点干!早点散----------负载均衡LVS-DR群集部署
- 大点干!早点散----------群集负载均衡LVS DR+keepalived部署实战
- Java字符串所占字节数的小总结
- Java类加载机制详解
- 详解Java注解(Annotation)
- 你不知道的Synchronized
- 从Java并发集合看锁优化策略
- Java常用并发容器总结(二)
- Java常用并发容器总结(一)
- Java常用并发容器总结(三)
- Java常用并发容器总结(四)