computed + watch【vue 知识汇点7】

184 阅读2分钟

computed 和 watch 定义

computed

computed 是计算属性,对绑定到视图的数据进行处理,并监听变化,进而执行对应的方法。只有相关依赖发生变化时,它们才会重新请求值。

watch

watch 是一个侦听的动作,用来观察和响应 Vue 实例上的数据变动。

使用 watch 选项允许我们执行异步操作,限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态,这些都是计算属性做不到的。

computed 和 watch 用法异同

相同: computed 和 watch 都起到监听。依赖一个数据,并进行处理的作用

不同:都是 vue 对监听器的实现,只不过 computed 主要是对同步数据的处理,watch 则主要用来观测某个值的变化去完成一段开销比较大的复杂业务逻辑。

computed 底层如何工作

计算属性的初始化是在 Vue 实例初始化阶段的 iniState 函数中,先创建一个空对象,接着对 computed 对象做遍历,拿到计算属性的每一个 userDef,然后尝试获取这个 userDef 对应的 getter 函数,为每一个 getter 创建一个 watcher,这个 watcher 和渲染 watcher 有一点很大的不同,它是一个 computed watcher,因为 const computedWatcherOptions = {computed: true}。 然后如果 key 不是 vm 的属性,则调用 defineComputed(vm, key, userDef)

defineComputed(vm, key, userDef) 就是给计算属性对应的 key 值添加 getter 和 setter,setter 通常是计算属性是一个对象,并且拥有 set 方法的时候才有,否则是一个空函数。实际开发中,计算属性很少有 setter,我们重点关注一下 getter,getter 对应的是 createComputedGetter(key) 的返回值

function createComputedGetter(key) {
	return function computedGetter() {
    	const watcher = this._computedWatchers && this._computedWatchers[key];
        if (watcher) {
        	watcher.depend();
            return watcher.evaluate();
        }
    }
}

computed watcher 有两种模式,lazy 和 active,如果没有人订阅这个 computed watcher 的变化,只有当下次再访问这个计算属性的时候才会求值,否则的话,会重新计算值,对比新旧值,如果发生了变化则执行回调函数,触发渲染 watcher 重新渲染。

watch 底层如何工作

watch 的初始化是在 Vue 实例初始化阶段的 iniState 函数中,遍历 watch 对象,并将每个 watch[key] 赋值给 handler,如果是数组,则遍历调用 createWatcher 方法,最底层就是 Vue.prototype.$watch 方法。通过实例化一个 watcher 的方式,一旦我们 watch 的数据发送变化,它最终会执行 watcher 的 run 方法,执行回调函数 cb,如果设置了 immediate 为 true,则直接会执行回调函数的 cb,