下面是关于“vue源码解析computed多次访问会有死循环原理”的完整攻略。
1. computed的原理
先来简单介绍一下computed的原理。在Vue组件中,computed是指计算属性,是一个基于响应式依赖进行缓存的数据属性,它的值在使用时会自动收集依赖,发现依赖变化时会重新计算,并且将结果缓存起来,直到依赖变化才重新计算。这样就避免了重复计算,提升渲染性能。computed的实现依赖于Vue内部的Watcher类。
2. 访问computed多次时可能出现的问题
由于computed的计算是基于依赖收集,因此在我们多次访问computed属性时,可能会导致依赖重复收集的问题,这会导致计算属性的getter方法被执行多次,进而引发死循环。下面通过代码示例进一步说明这个问题。
<!-- template -->
<template>
<div>{{ message }}</div>
</template>
// script
export default {
data() {
return {
count: 0,
}
},
computed: {
message() {
const count = this.count++
console.log(`count: ${count}`)
return `当前计数为 ${count}`
},
},
}
上面的代码中,message()
方法用于计算一个字符串,内部会打印出计数器的值,并将其返回在字符串中。我们将这个字符串插入到模板中,这样每次模板更新时就会访问message()
方法。我们可以通过多次访问message()
来测试computed的计算过程。
// 在其他地方使用,比如mounted或者created钩子函数
console.log(this.message) // 输出 "当前计数为 0"
console.log(this.message) // 输出 "当前计数为 1"
console.log(this.message) // 输出 "当前计数为 2"
我们可以从控制台输出看到,每次调用message()
方法时都会打印计数器的值。这是由于多次访问计算属性会引发计算属性本身的getter方法被多次触发。
3. 解决computed多次访问死循环的问题
为了避免多次访问computed时的死循环问题,Vue的computed实现中采用了缓存的方式,只要计算属性的依赖没有发生改变,就会直接返回缓存的值,而不是重新计算。这个缓存是通过Watcher类实现的。
完整源码的解析过程这里暂且不细讲(可以参考一些源码解析的文章),通过对computed的简单分析,我们可以得出以下几点结论:
- computed的实现依赖于Vue内部的Watcher类,每个computed属性都会被创建一个watcher实例
- 每个watcher实例都有一个缓存变量,用于存储computed属性的值
- 计算computed属性时,会将计算过程中涉及到的依赖收集起来,如果依赖发生变化,就会重新计算值,否则直接返回缓存的值
- 对于一个指定的watcher实例,每次执行它的get方法时,会先将当前watcher实例设置为Dep.target,然后再访问计算属性的值,在计算属性计算的过程中,所有访问的响应式数据都会被添加到当前watcher实例的依赖中(核心:响应式数据发生变化后会触发Watcher实例的update方法,这个方法中会将缓存值失效并重新计算),最后将当前watcher置为空。
以上是对一些computed的基本原理和实现细节的解释,相信通过这个简单的分析,你已经对computed的工作原理有了一些了解。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue源码解析computed多次访问会有死循环原理 - Python技术站