Vue源码学习(十一):计算属性computed初步学习
好家伙,
1.Computed实现原理
if (opts.computed) {
initComputed(vm,opts.computed);
}
function initComputed(vm, computed) {
// 存放计算属性的watcher
const watchers = vm._computedWatchers = {};
for (const key in computed) {
const userDef = computed[key];
// 获取get方法
const getter = typeof userDef === 'function' ? userDef : userDef.get;
// 创建计算属性watcher
watchers[key] = new Watcher(vm, userDef, () => {}, { lazy: true });
defineComputed(vm, key, userDef)
}
}
computed依赖跟踪的处理逻辑与watcher相似
1.1.watcher
每个计算属性也都是一个watcher,计算属性需要表示lazy:true,这样在初始化watcher时不会立即调用计算属性方法
class Watcher {
constructor(vm, exprOrFn, callback, options) {
this.vm = vm;
this.dirty = this.lazy
// ...
this.value = this.lazy ? undefined : this.get(); // 调用get方法 会让渲染watcher执行
}
}
1.2.dirty属性
默认计算属性需要保存一个dirty属性,用来实现缓存功能
function defineComputed(target, key, userDef) {
if (typeof userDef === 'function') {
sharedPropertyDefinition.get = createComputedGetter(key)
} else {
sharedPropertyDefinition.get = createComputedGetter(userDef.get);
sharedPropertyDefinition.set = userDef.set;
}
// 使用defineProperty定义
Object.defineProperty(target, key, sharedPropertyDefinition)
}
function createComputedGetter(key) {
return function computedGetter() {
const watcher = this._computedWatchers[key];
if (watcher) {
if (watcher.dirty) { // 如果dirty为true
watcher.evaluate();// 计算出新值,并将dirty 更新为false
}
// 如果依赖的值不发生变化,则返回上次计算的结果
return watcher.value
}
}
}
为什么使用缓存?
1.减少不必要的计算开销:计算属性的值是根据依赖的响应式数据计算而来的。如果每次访问计算属性都重新计算一次,无论依赖数据有没有变化,都会导致不必要的计算开销。
通过使用 dirty 属性,可以标记计算属性是否需要重新计算,从而避免不必要的计算。
2.提高性能与响应速度:通过缓存计算属性的值,当访问计算属性时,如果依赖数据没有发生改变,可以直接返回之前的缓存值,而不必重新计算。
这样可以提高性能并且快速响应用户的数据访问请求。
3.依赖数据发生变化时再重新计算:当依赖的响应式数据发生变化时,计算属性才需要重新计算。
通过将 dirty 属性设置为 true,可以在下一次访问计算属性时触发重新计算,并将计算结果缓存起来。
1.3.watcher.evaluate()方法
evaluate() {
this.value = this.get()
this.dirty = false
}
update() {
if (this.lazy) {
this.dirty = true;
} else {
queueWatcher(this); //更新方法
}
}
当依赖的属性变化时,会通知watcher调用update方法,此时我们将dirty置换为true。这样再取值时会重新进行计算。
if (watcher) {
if (watcher.dirty) {
watcher.evaluate();
}
if (Dep.target) { // 计算属性在模板中使用 则存在Dep.target
watcher.depend()
}
return watcher.value
}
depend() {
let i = this.deps.length
while (i--) {
this.deps[i].depend()
}
}
如果计算属性在模板中使用,就让计算属性中依赖的数据也记录渲染watcher,这样依赖的属性发生变化也可以让视图进行刷新
Vue源码学习(十一):计算属性computed初步学习的更多相关文章
- 007——VUE中非常使用的计算属性computed实例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Vue.js学习 Item5 -- 计算属性computed与$watch
在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作.模板是为了描述视图的结构.在模板中放入太多的逻辑会让模板过重且难以维护.这就是为什么 Vue.js 将绑定表达式限制为一个表达式.如果需 ...
- VUE学习之计算属性computed
计算属性:computed 先看一下官网的说法 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="ex ...
- Vue学习3:计算属性computed与监听器
下面是计算属性相关代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- [Vue源码]一起来学Vue双向绑定原理-数据劫持和发布订阅
有一段时间没有更新技术博文了,因为这段时间埋下头来看Vue源码了.本文我们一起通过学习双向绑定原理来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫 ...
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- vue 源码解析computed
计算属性 VS 侦听属性 Vue 的组件对象支持了计算属性 computed 和侦听属性 watch 2 个选项,很多同学不了解什么时候该用 computed 什么时候该用 watch.先不回答这个问 ...
- Vue 源码学习(1)
概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...
- 一起学习vue源码 - Vue2.x的生命周期(初始化阶段)
作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e8 ...
- 浅谈Vue中计算属性computed的实现原理
虽然目前的技术栈已由Vue转到了React,但从之前使用Vue开发的多个项目实际经历来看还是非常愉悦的,Vue文档清晰规范,api设计简洁高效,对前端开发人员友好,上手快,甚至个人认为在很多场景使用V ...
随机推荐
- [转帖]shell删除文件前几行或后几行
https://www.cnblogs.com/1394htw/p/14852207.html shell删除文件前几行或后几行 #!/bin/bash #删除前两行 sed -i '1,2d' fi ...
- echarts去除坐标轴上的x和y轴
通过 show:false控制手否显示 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- 【学到了】golang的[]byte可以append string类型的数据
上代码: func Test_use_string(t *testing.T){ arr := make([]byte,0, 100) arr = append(arr, "abcd&quo ...
- webservice--WSDL文件生成本地的代理类
我们在对应第三方接口时常用:项目上右键---->服务引用---->WCF Web Service,如下图的页面----->填好url后---->转到,就可以发现服务,生成代理类 ...
- Pytest 源码解读 [1] - [pluggy] 核心设计理念浅读
背景: Pytest 是一个功能强大的 Python 测试框架,它使用了一个名为 "pluggy" 的插件系统来扩展其功能.在 Pytest 的源码中,pluggy 模块负责实现插 ...
- x64dbg 2022 最新版编译方法
x64dbg 调试器的源码编译很麻烦,网络上的编译方法均为老版本,对于新版本来说编译过程中会出现各种错误,编译的坑可以说是一个接着一个,本人通过研究总结出了一套编译拳法可以完美编译输出,不过话说回来x ...
- vue + elementui 分页切换页面,缓存页码
问题场景 列表页面输入查询条件,选择第3页,点击详情进入详情页,从详情页返回时,默认列表页面页码重置为1:此时想要缓存该页码,有两种方式:可按业务场景使用 方式一:用vue自带的 keep-alive ...
- 一图看懂iPhone 15系列:15/Plus/Pro/Pro Max有啥区别?详细配置对比
距离iPhone 15系列发布只剩下2天(北京时间9月13日凌晨1点),即将推出预计分别是iPhone 15.iPhone 15 Plus,以及Pro系列的iPhone 15 Pro以及iPhone ...
- P10114 [LMXOI Round 1] Size 题解
题目链接:[LMXOI Round 1] Size 挺有意思的诈骗题,其实这类题都喜欢批一个外壳,例如数据范围提示之类的.记得以前遇到的很多诈骗题,有一道 cf 的高分题,问的是区间出现次数的次数 \ ...
- Android 相册