首页 > 编程语言 >vue3源码学习6-计算属性computed

vue3源码学习6-计算属性computed

时间:2022-09-07 10:57:27浏览次数:79  
标签:computed self vue3 value getter ._ 源码 setter

packages/reactivity/src/computed.ts

export function computed<T>(
  getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>,
  debugOptions?: DebuggerOptions,
  isSSR = false
) {
  // getter函数
  let getter: ComputedGetter<T>
  // setter函数
  let setter: ComputedSetter<T>
  // 标准化参数
  const onlyGetter = isFunction(getterOrOptions)
  // 如果只有getter函数,不能修改计算属性的值
  if (onlyGetter) {
    getter = getterOrOptions
    setter = __DEV__
      ? () => {
          console.warn('Write operation failed: computed value is readonly')
        }
      : NOOP
  } else {
    getter = getterOrOptions.get
    setter = getterOrOptions.set
  }
  const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR)
  return cRef as any
}

接下来看ComputedRefImpl的实现:

export class ComputedRefImpl<T> {
  public dep?: Dep = undefined

  private _value!: T
  public readonly effect: ReactiveEffect<T>

  public readonly __v_isRef = true
  public readonly [ReactiveFlags.IS_READONLY]: boolean = false
  // 数据是否是脏的
  public _dirty = true
  public _cacheable: boolean

  constructor(
    getter: ComputedGetter<T>,
    private readonly _setter: ComputedSetter<T>,
    isReadonly: boolean,
    isSSR: boolean
  ) {
	// 特性1:只有当访问计算属性的时候,才会真正运行computed getter函数计算
    this.effect = new ReactiveEffect(getter, () => {
      if (!this._dirty) {
		// 派发通知,通知运行访问该计算属性的activeEffect
        this._dirty = true
        triggerRefValue(this)
      }
    })
    this.effect.computed = this
    this.effect.active = this._cacheable = !isSSR
    this[ReactiveFlags.IS_READONLY] = isReadonly
  }

  get value() {
	// 计算属性的getter
    // the computed ref may get wrapped by other proxies e.g. readonly() #3376
    const self = toRaw(this)
	// 依赖收集,收集运行访问该属性的activeeEffect
    trackRefValue(self)
	// 特性2:缓存,会自动缓存上次的计算结果_value,而且只有dirty为true时,才会重新计算,否则直接返回_value
	// 典型的空间换时间的优化思想
    if (self._dirty || !self._cacheable) {
	  // 只有数据为脏的时候才进行计算
      self._dirty = false
      self._value = self.effect.run()!
    }
    return self._value
  }

  set value(newValue: T) {
	// 计算属性的setter
    this._setter(newValue)
  }
}

标签:computed,self,vue3,value,getter,._,源码,setter
From: https://www.cnblogs.com/caicai521/p/16664509.html

相关文章

  • 【源码学习】Vue源码的敲门砖(目录结构)
    声明本文是开始学习 Vue 源码的第一篇笔记,当前的版本是 2.6.14 。源码结构目录结构在 github 上下载了源码,是一个叫vue-dev 的文件夹,展开以后 一级目录结构 ......
  • 在UNI-APP创建VUE3项目时配置VUE版本
    在UNI-APP创建项目时,默认是VUE2版本。如果直接使用VUE3代码时会出错。所以第一步就要求设置VUE版本,操作如下:打开根目录下/manifest.json文件,找到“基础配置”-->"Vue......
  • vue3 基础-non-props 特性
    本篇探讨当父组件通过属性给子组件传数据时,子组件如果不通过props属性进行接收,那数据会挂载到哪里,以及子组件如何能使用这些数据.正常的父子组件传值<!DOCTYPEh......
  • vue3项目-小兔鲜儿笔记-商品详情页03和登录页01
    1.封装数量选择组件功能分析:默认值为1可限制最大最小值点击-就是减1,点击+就是加1需要完成v-model的双向数据绑定存在无label的情况<scriptsetup>//......
  • QT4.8.6+mingw+qtcreator4.13.3 搭建环境+调试QT源码
    本文测试环境:win7x64由于考虑到跨平台的原因,本安装不基于visualstudio的插件来安装,这样的开发环境和linux更接近.三个文件请准备好:i686-4.8.2-release-posix-dwarf-r......
  • Vue3中如何使用this
    vue3提供了getCurrentInstance,通过这个属性,直接使用ctx是错误的,需要找到全局属性globalPropertiesimport{getCurrentInstance}from'vue'constinstance=getCurre......
  • Vue3拖拽式可视化低代码数据可视化平台
    简介......
  • Vue3——provide 与 inject
    作用:实现祖与后代组件间通信套路:父组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据,两个函数联合起来能实现祖孙组件间通信具体写......
  • vue3对比vue2获取通过refs获取组件数据
    vue21、组件设置ref标识<van-calendarref="calendarRef">2、在mounted中读取exportdefault{mounted(){//获取日历当前选择的时间constdat......
  • vuex源码分析
      什么是vuex是一个专为Vue.js应用程序开发的状态管理模式。什么是状态管理模式,vue根据data的变化会渲染模板,vuex则是把一些数据集中进行管理方便在vue组件中使......