当前位置: 首页 > news >正文

vb 网站开发湖南seo公司

vb 网站开发,湖南seo公司,迅当网络深圳外贸网站建设,网站建设费用能否计入广告费前言 本文是 vue3 源码分析系列的第三篇文章,主要介绍 vue3 computed 原理。computed 是 vue3 的一个特性,可以根据其他响应式数据创建响应式的计算属性。计算属性的值会根据依赖的数据变化而自动更新,而且具有缓存机制,提高了性…

前言

本文是 vue3 源码分析系列的第三篇文章,主要介绍 vue3 computed 原理。computed 是 vue3 的一个特性,可以根据其他响应式数据创建响应式的计算属性。计算属性的值会根据依赖的数据变化而自动更新,而且具有缓存机制,提高了性能。在这篇文章中,我们将深入探讨 computed 的实现原理,并通过源码分析来理解其工作机制。

computed 的基本用法

在 vue3 中,computed 的基本用法如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>computed</title>
</head>
<body>
<script src="../packages/reactivity/dist/reactivity.global.js"></script>
<script>let { reactive, computed } = VueReactivity;const state = reactive({count: 0});const double = computed(() => state.count * 2);console.log(double.value); // 0setTimeout(() => {state.count++;console.log(double.value); // 2}, 1000);
</script></body>
</html>

在上面的例子中,我们首先创建了一个响应式对象 state,然后我们使用 computed 创建了一个计算属性 double。这个计算属性的值是 state.count 的两倍。当 state.count 的值发生变化时,double 的值也会自动更新。

computed 的实现原理

computed 函数的源码如下:

// 定义一个名为computed的函数,该函数接受一个参数getterOrOptions,这个参数可以是计算属性的getter函数,也可以是包含get和set方法的对象
export function computed<T>(getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>) {// 定义两个变量getter和setter,分别用于存储计算属性的getter函数和setter函数let getter: ComputedGetter<T>let setter: ComputedSetter<T>// 判断getterOrOptions是否为函数类型,如果是,说明只传入了getter函数const onlyGetter = isFunction(getterOrOptions)if (onlyGetter) {// 如果只传入了getter函数,将getterOrOptions赋值给getter,同时定义setter函数getter = getterOrOptionssetter = __DEV__? () => {warn(`Write operation failed: computed value is readonly`)}: NOOP} else {// 如果传入了包含get和set方法的对象,将get方法赋值给getter,将set方法赋值给settergetter = getterOrOptions.getsetter = getterOrOptions.set}// 创建一个新的ComputedRefImpl实例,并返回。这个实例接收getter、setter和一个布尔值参数return new ComputedRefImpl(getter,setter,isFunction(getterOrOptions) || !getterOrOptions.set) as any
}

computed 函数接受一个函数或一个对象作为参数,如果是函数,就是计算属性的 getter 函数。如果是对象,就是包含 get 和 set 函数的选项对象。computed 函数会返回一个 ComputedRefImpl 的实例。ComputedRefImpl 的构造函数如下:

ComputedRefImpl

ComputedRefImpl 函数的源码如下:

class ComputedRefImpl<T> {// 定义一个私有变量 _dirty,表示是否需要重新计算值。初始化为 true 表示需要重新计算private _dirty = true// 定义一个公共的 reactive effect,用于观察和响应值的变化public readonly effect: ReactiveEffect<T>// 定义两个公共的只读属性,用于标识这个引用是否只读和是否是响应式的引用public readonly __v_isReadonly: booleanpublic readonly __v_isRef = trueconstructor(getter: ComputedGetter<T>,private readonly _setter: ComputedSetter<T>,isReadonly: boolean) {// 创建一个 reactive effect,当值发生变化时触发。如果值没有变化则不触发。 this.effect = effect(getter, {lazy: true, // 懒加载,只有当需要时才执行scheduler: () => { // 调度器函数if (!this._dirty) {this._dirty = true // 重置 _dirty 为 true,表示需要重新计算}}})this.effect.computed = this}// 定义一个 getter 方法,返回当前的值。get value() {if (this._dirty) { // 如果 _dirty 为 true,表示需要被重新计算this._value = this.effect() // 调用 effect 方法来计算值this._dirty = false // 设置 _dirty 为 false,表示值已经被计算过}return this._value}// 定义一个 setter 方法,设置新的值并调用传入的 setter 方法来处理这个新值set value(newValue: T) {this._setter(newValue)}
}

ComputedRefImpl 构造函数内部创建了一个 effect 副作用函数,函数传入了 getter 函数,和一个选项对象。选项对象中有两个属性,一个是 lazy,表示副作用函数是否延迟执行,一个是 scheduler,表示副作用函数的调度器,用于在依赖的数据变化时触发副作用函数的重新执行。

effect

effect 函数的源码如下:

function effect<T = any>(fn: () => T, options?: ReactiveEffectOptions): ReactiveEffect<T> {// 创建一个新的effect函数,调用run方法执行原始的函数const _effect = new ReactiveEffect(fn, NOOP, () => {if (_effect.dirty) {_effect.run()}})// 如果options中没有设置lazy为true,就立即执行effect函数if (!options || !options.lazy) {_effect.run()}const runner = _effect.run.bind(_effect) as ReactiveEffectRunnerrunner.effect = _effectreturn runner
}
  • 由于在 ComputedRefImpl 类中定义 effect 函数时,传入的 lazy 为 true 函数并不会自动执行。

  • 当我们访问 double.value 时会触发 ComputedRefImpl 类里面的 get 这个函数,执行 effect 函数。在此过程中会建立属性依赖关系。

  • 执行完之后,将 this._dirty 设置为 false,这一步在后面计算属性是否会重新执行起到关键作用。

scheduler

scheduler 函数通常用于控制计算属性的更新调度。 函数提供了一种额外的调度控制机制,使你能够更好地控制计算属性的更新时机和逻辑。那么 scheduler 是如何被执行的:

function trigger (target, type, key, newValue?, oldValue?) {// 此处省略部分代码for (const effect of effects) {// computed 表示这是一个计算属性if (effect.computed) {// 执行调度器函数// 重新修改 dirty 的值,标记该计算属性为“脏”状态,表示其值已被修改effect.options.scheduler()} else {effect()}}
}
  • 对于 effects 中的每一个 effect,如果它是一个计算属性,那么会调用它的调度器函数来进行更新。否则,直接调用 effect() 来运行副作用。

  • scheduler 函数,用来在依赖项变化时改变 _dirty 标志位,表示计算属性需要重新计算。

  • 当我们再次访问 double.value 时,由于 this._dirty = true 又会重新执行 get 这个函数,然后更新 double 的值。

通过这个机制使得 vue3 能够精确地控制哪些副作用需要在响应式数据变化时更新,从而提高了性能。

总结

通过对 computed 的源码分析,我们可以看到 vue3 如何实现计算属性的。当我们创建一个计算属性时,vue 会收集这个计算属性的所有依赖项。然后,当这些依赖项发生变化时,vue 会重新计算这个计算属性的值。并通过 _dirty 这个标志位来判断是否需要执行副作用函数并更新 _value 的值。这种机制使得我们可以方便地创建基于其他响应式依赖项的计算属性。

http://www.zhongyajixie.com/news/27485.html

相关文章:

  • 中国人民银行网站查询网址怎么做营销
  • 1717做网站高端企业建站公司
  • 重庆企业做网站多少钱性价比高的seo网站优化
  • 网页设计基础课件seo 推广
  • 网站建设实验报告格式网络软文营销案例
  • 杭州网站建设案例怎么才能让百度收录网站
  • 怎么随便搞个网站如何创建一个网页
  • 怎样做淘宝客网站个人网站的制作
  • 瑞安做网站企业产品营销策划推广
  • 大连高新园区在哪成都网站优化及推广
  • 运用阿里云怎么做网站设计网页
  • 合优做网站需要多少钱宁波网站建设与维护
  • 网站制作软件平台广告策划案优秀案例
  • 有设计师做的装修效果图的网站如何推广公司网站
  • 厚街镇网站仿做优化大师win7官方免费下载
  • 洛阳免费提供建站方案网站优化排名推荐
  • 阿里云ecs 怎么做网站最新疫情19个城市封城
  • 中迅做网站是模板站吗知乎关键词排名优化工具
  • app运营费用预算免费seo排名软件
  • 芜湖有没有做网站的2021全国大学生营销大赛
  • 51源码网佛山外贸seo
  • 做公益网站软文营销文章案例
  • 软件外包学院大学承认吗百度移动排名优化软件
  • 2015年友情链接网站源代码下载网上永久视频会员是真的吗
  • 手机怎样建立网站公司快速建站
  • 网站开发流程丽江如何进行seo搜索引擎优化
  • 宝安营销型网站建设公司免费seo优化
  • 做网站怎么加水平线制作网站的步骤和过程
  • 新沂微网站开发最近新闻头条
  • 网站建设的技术淘宝店铺怎么引流推广