computed 原理,首先得讲 vue 响应式原理,因为 computed 的实现是基于 Watcher
对象的。 那么 vue 的响应式原理是什么呢?众所周知,vue 是基于 Object.defineProperty
实现监听的。在 vue 初始化数据 data 和 computed 数据过程中。会涉及到以下几个对象:
-
Observe
对象(观察者) -
Dep
对象(订阅者) -
Watch
对象 Observe
对象是在 data 执行响应式时候调用,因为 computed 属性基于响应式属性,所以其不需要创建 Observe 对象。 Dep 对象主要功能是做依赖收集,有个属性维护多个 Watch 对象,当更新时候循环调用每个 Watch 执行更新。 Watch 对象主要是用于更新,而且是收集的重点对象。
computed的两种定义方式
这里谈到 computed 计算属性,首先要知道,其有两种定义方式。
一种是方法,另一种是 get,set
属性。而且,其内部监听的对象必须是已经定义响应式的属性,比如 data 的属性、vuex 的属性。
vue 在创建 computed 属性时候,会循环所有计算属性,每一个计算属性会创建一个 watch,并且在通过 defineProperty
定义监听,在 get 中,计算属性工作是做依赖收集,在 set 中,计算属性重要工作是重新执行计算方法,这里需要多补充一句,因为 computed 是懒执行,也就是说第一次初始化之后,便不会执行计算,下一次变更执行重新计算是在 set 中。
依赖收集的时机
另一个补充点是依赖收集的时机,computed 收集时机和 data 一样,是在组件挂载前,但是其收集对象是自己属性对应的 watch,而 data 本身所有数据对应一个 watch。