Vue中computed实现原理及与method的区别

1.初始化 data 和 computed,分别代理其 set 和 get 方法,对 data 中的所有属性生成唯一的 dep 实例

2.对 computed 中的 属性生成唯一的 watcher,并保存在 vm._computedWatchers 中

3.访问计算属性时,设置 Dep.target 指向 计算属性的 watcher,调用该属性具体方法

4.方法中访问 data 的属性,即会调用 data 属性的 get 方法,将 data 属性的 dep 加入到 计算属性的 watcher , 同时该 dep 中的 subs 添加这个 watcher

5.设置 data 的这个属性时,调用该属性代理的 set 方法,触发 dep 的 notify 方法

6.因为时 computed 属性,只是将 watcher 中的 dirty 设置为 true

7.最后,访问计算属性的 get 方法时,得知该属性的 watcher.dirty 为 true,则调用 watcher.evaluate() 方法获取新的值

综合以上:也可以解释了为什么有些时候当computed没有被访问(或者没有被模板依赖),当修改了this.data值后,通过vue-tools发现其computed中的值没有变化的原因,因为没有触发到其get方法。

computed vs methods
计算属性跟方法都能打到同样的方法,那么他们之间有什么不同呢?我们还是看一段代码理解一下

// methods 每次render都会重新计算
<template>
  <p>{{getName()}}</p>
</template>
methods:{
  getName:function(){
    return this.name.split(' ').reverse().join(' ')
  }
}
// 使用computed ,computed是基于他们的依赖进行缓存的,也就是说下面这段代码只要this.name不改变,每次访问都会立即返回结果
<template>
  <p>{{getName}}</p>
</template>
computed:{
  getName:function(){
    return this.name.split(' ').reverse().join(' ')
  },
}

总结:methods是实时的,在重新渲染时,函数总会重新调用执行,不会缓存,(多次输出时间不同)
而computed只有在属性值发生改变时才会触发,因此 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
但是在利用实时信息时,比如显示当前进入页面的时间,必须用methods方式

methods: {
    now: function () {
      return Date.now()
    }
}

如果用computed计算属性的话,每次进入页面将一直沿用第一次的信息,不会再触发now。

发布了193 篇原创文章 · 获赞 139 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/qappleh/article/details/102621040