7.5 initComputed
和上面的分析方法一样,initComputed
是computed
数据的初始化,不同之处在于以下几点:
computed
可以是对象,也可以是函数,但是对象必须有getter
方法,因此如果computed
中的属性值是对象时需要进行验证。- 针对
computed
的每个属性,要创建一个监听的依赖,也就是实例化一个watcher
,watcher
的定义,可以暂时理解为数据使用的依赖本身,一个watcher
实例代表多了一个需要被监听的数据依赖。
除了不同点,initComputed
也会将每个属性设置成响应式的数据,同样的,也会对computed
的命名做检测,防止与props,data
冲突。
function initComputed (vm, computed) {
···
for (var key in computed) {
var userDef = computed[key];
var getter = typeof userDef === 'function' ? userDef : userDef.get;
// computed属性为对象时,要保证有getter方法
if (getter == null) {
warn(("Getter is missing for computed property \"" + key + "\"."),vm);
}
if (!isSSR) {
// 创建computed watcher
watchers[key] = new Watcher(vm,getter || noop,noop,computedWatcherOptions);
}
if (!(key in vm)) {
// 设置为响应式数据
defineComputed(vm, key, userDef);
} else {
// 不能和props,data命名冲突
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);
}
}
}
}
显然Vue
提供了很多种数据供开发者使用,但是分析完后发现每个处理的核心都是将数据转化成响应式数据,有了响应式数据,如何构建一个响应式系统呢?前面提到的watcher
又是什么东西?构建响应式系统还需要其他的东西吗?接下来我们尝试着去实现一个极简风的响应式系统。