vue数据初始化initState的实例详解

2020-06-14 06:10:29易采站长站整理
vm.$watch
函数为watch中的属性绑定setter回调(如果组件中没有该属性则不能成功监听,属性必须存在于props、data或computed中)。如果watch中属性的值是一个函数,则默认为属性的setter回调函数,如果属性的值是一个数组,则遍历数组中的内容,分别为属性绑定回调,此外属性的值还可以是一个对象,此时,对象中的handler字段代表setter回调函数,immediate代表是否立即先去执行里面的handler方法,deep代表是否深度监听。

vm.$watch
函数会直接使用Watcher构建观察者对象。watch中属性的值作为watcher.cb存在,在观察者update的时候,在watcher.run函数中执行。想了解这一过程可以看我上一篇的 vue响应式系统–observe、watcher、dep中关于Watcher的介绍。


function initWatch(vm, watch) {
//遍历watch,为每一个属性创建侦听器
for(var key in watch) {
var handler = watch[key];
//如果属性值是一个数组,则遍历数组,为属性创建多个侦听器
//createWatcher函数中封装了vm.$watch,会在vm.$watch中创建侦听器
if(Array.isArray(handler)) {
for(var i = 0; i < handler.length; i++) {
createWatcher(vm, key, handler[i]);
}
} else {
//为属性创建侦听器
createWatcher(vm, key, handler);
}
}
}

function createWatcher(vm, expOrFn, handler, options) {
//如果属性值是一个对象,则取对象的handler属性作为回调
if(isPlainObject(handler)) {
options = handler;
handler = handler.handler;
}
//如果属性值是一个字符串,则从组件实例上寻找
if(typeof handler === 'string') {
handler = vm[handler];
}
//为属性创建侦听器
return vm.$watch(expOrFn, handler, options)
}

computed

computed本质是一个惰性求值的观察者,具有缓存性,只有当依赖变化后,第一次访问 computed 属性,才会计算新的值

下面将围绕这一句话来做解释。

上面代码中提到过,当计算属性中的数据存在与data和props中时,会被警告,也就是这种做法是错误的。所以一般的,我们都会直接在计算属性中声明数据。还是那个代码片段中,如果定义的计算属性不在组件实例上,会运行defineComputed函数对数据进行数据劫持。下面我们来看下defineComputed函数中做了什么。


function defineComputed(target, key, userDef) {
//是不是服务端渲染
var shouldCache = !isServerRendering();
//如果我们把计算属性的值写成一个函数,这时函数默认为计算属性的get
if(typeof userDef === 'function') {
sharedPropertyDefinition.get = shouldCache ?