vue的computed原理(5)

本文详细介绍了Vue的响应式系统,包括observe、watcher和dep的运作机制,以及计算属性的初始化过程。在initState函数中,Vue为组件实例初始化了计算属性,通过对getter的监听和定义,确保了计算属性的实时更新。同时,文章还讨论了如何处理计算属性的定义,支持函数和带有get/set的对象两种形式。
摘要由CSDN通过智能技术生成

 首先需要了解vue的响应设计

Vue响应系统,其核心有三点:observe、watcher、dep:
observe:遍历data中的属性,使用 Object.defineProperty 的get/set方法对其进行数据劫持,
         顺便在get加入了dep依赖收集,在set里面加入了触发dep依赖更新

dep:每个属性拥有自己的消息订阅器dep,用于存放所有订阅了该属性的观察者对象

watcher:观察者(对象),通过dep实现对响应属性的监听,监听到结果后,
主动触发自己的回调进行响应 (执行observe的时候会初始化这个观察者)

对响应式系统有一个初步了解后,我们再来分析计算属性。
首先我们找到计算属性的初始化是在src/core/instance/state.js文件中的initState函数中完成的

export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  // computed初始化
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

调用了initComputed函数(其前后也分别初始化了initDatainitWatch)并传入两个参数vm实例和opt.computed开发者定义的computed选项,转到initComputed函数:

const computedWatcherOptions = { computed: true }
 
function initComputed (vm: Component, computed: Object) {
  // $flow-disable-line
  const watchers = vm._computedWatchers = Object.create(null)
  // computed properties are just getters during SSR
  const isSSR = isServerRendering()
 
  for (const key in computed) {
    const userDef = computed[key]
    const getter = typeof userDef === 'function' ? userDef : userDef.get
    if (process.env.NODE_ENV !== 'production' && getter == null) {
      warn(
        `Getter is missing for computed property "${key}".`,
        vm
      )
    }
 
    if (!isSSR) {
      // create internal watcher for the computed property.
      watchers[key] = new Watcher(
        vm,
        getter || noop,
        noop,
        computedWatcherOptions
      )
    }
 
    // component-defined computed properties are already defined on the
    // component prototype. We only need to define computed properties defined
    // at instantiation here.
    if (!(key in vm)) {
      defineComputed(vm, key, userDef)
    } else if (process.env.NODE_ENV !== 'production') {
      if (key in vm.$data) {
        warn(`The computed property "${key}" is already defined in data.`, vm)
      } else if (vm.$options.props && key in vm.$options.props) {
        warn(`The computed property "${key}" is already defined as a prop.`, vm)
      }
    }
  }
}

定义一个计算属性有两种写法,一种是直接跟一个函数,另一种是添加setget方法的对象形式,所以这里首先获取计算属性的定义userDef,再根据userDef的类型获取相应的getter求值函数。

defineComputed并将所有computed属性通过defineProperties绑定到vm上,以便可以通过vm[key]直接获取到值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值