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 ...
随机推荐
- [转帖]linux性能检测之sar详解
http://blog.51niux.com/?id=99 sar也是sysstat中的一员. 一.介绍 1.1 简介 sar是一个优秀的一般性能监视工具,它可以输出Linux所完成的几乎所有工作的数 ...
- 我们开源了一个轻量的 Web IDE UI 框架
我们开源了一个轻量的 Web IDE UI 框架 Molecule 一个轻量的 Web IDE UI 框架 简介 Molecule 是一个受 VS Code 启发,使用 React.js 构建的 We ...
- echarts 设置legend样式
设置legend样式 legend: { x: 'center', data: ['班车', '包车'], icon: "circle", // 这个字段控制形状 类型包括 cir ...
- golang实现的 https 协议的四层代理和七层代理
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 四层代理 在 tcp 这一层转发很简单. http 协议是 ...
- springboot多模块打包报错问题根因分析:Unable to find main class
问题背景: 项目结构为springboot多模块,其中有四个模块bean.utils.user.ems,其中user和ems模块为主程序,包含启动类,其他两个模块为其服务,提供依赖 问题分析: 查看u ...
- window下部署单机hadoop环境
window本地部署单机hadoop,修改配置文件和脚本如下,只记录关键配置和步骤,仅供参考 hadoop-2.6.5 spark-2.3.3 1.配置文件core-site.xml <conf ...
- Windows配置PHP的MongoDB扩展
环境 Windows 10 PHP 5.6.40/8.1.11 配置 下载MongoDB扩展 下载地址:https://pecl.php.net/package/mongodb 下载PHP版本对应的扩 ...
- Qwik 1.0 发布,全栈式 Web 框架
Qwik 是一个全栈式 Web 框架,Qwik 基于 React.Angular 和 Vue 等其他 Web 框架的概念,但以 JavaScript 流等更新的方法脱颖而出,允许以高性能向用户交付复杂 ...
- [转载自jayant97] nRF9160与nRF Cloud 超详细入门攻略
原文链接:nRF9160与nRF Cloud 超详细入门攻略 1. 产品简介 1.1. nRF Cloud nRF Cloud是Nordic Semiconducotr公司在AWS上搭建的IoT平 ...
- 4.if语句--《Python编程:从入门到实践》
4.1 检查多个条件 1.使用 and 检查多个条件 2.使用 or 检查多个条件 4.2 检查特定值是否包含在列表中 使用 in 检查特定值是否在列表中 >>> req ...