请阐述一下computed和methods有什么区别?

1,271 阅读3分钟

🙌 computed和methods区别

  • 一些浅显的回答
  1. 在使用时, computed可以当做属性使用,而methods则可以当做方法调用。
  2. computed可以具有getter和setter方法,因此可以赋值,而methods是不行的。
  3. computed无法接收多个参数,而methods可以
  4. computed是有缓存的,而methods没有
  • 更接近底层原理的回答

vue对methods的处理是比较简单的,只需要遍历methods配置中的每个属性,然后将对应的函数使用bind绑定当前组件实例上就可以了,之后我们就可以通过this.函数调用就行了

而vue对computed的处理会稍微复杂一些。

当组件的实例触发生命周期函数beforeCreate后,它会做一系列事情,其中就包含对computed的处理。关于vue生命周期可以看我这篇文章:请阐述vue生命周期

它会遍历computed配置中的所有属性,为每一个属性创建一个Watcher对象,并传入一个函数,这个函数会收集依赖,该函数的本质其实就是computed配置中的getter,这样一来,getter在运行过程中就会收集依赖。如果有一天getter中的依赖改变时,会重新运行Watcher

但是和渲染函数不同,为计算属性所创建的Watcher不会立即执行,因为要考虑到这个计算属性会不会被渲染函数使用,如果没有使用,就不会执行,比如v-if的存在。因此,在创建的Watcher的时候,它使用lazy配置,lazy是懒加载,偷懒的意思,lazy的配置可以让Watcher不会立即执行,我们可以在控制台打印一下vue的实例,找到渲染函数的Watcher和计算属性的Watcher进行对比,如下图:

渲染函数的Watcher

计算属性的Watcher

lazy为false说明渲染函数的Watcher是要立即就执行的,为true则说明计算属性的Watcher不会立即执行

受到lazy的影响,Watcher内部会保存两个关键属性来实现缓存,一个是value,一个是dirty

  1. value属性用来保存Watcher运行的结果,受lazy的影响,value在最开始的值为undefined

  2. dirty属性用于指示当前的value是否已经过时了,即是否为脏值,受lazy的影响,dirty最开始为true

Watcher创建好后,vue会使用代理模式,将计算属性挂载到组件实例中

当读取计算属性时,vue会检查其对应的Watcher是否为脏值,如果是,则运行函数,计算getter函数用到的依赖,并拿到对应的值,保存在Watcher的value中,然后设置dirty为false,然后返回。

如果dirty为false,则直接返回watcher的value

值得注意的是,在收集依赖时,被依赖的数据不仅会收集到计算属性的Watcher,还会收集到组件的Watcher,当计算属性的依赖变化时,会先触发计算属性的Watcher执行,此时,它只需要设置dirty为true就可以了,不会做其它处理。

由于依赖同时会收集到组件的Watcher,因此组件会重新渲染,而重新渲染的同时又读取到了计算属性,由于此时dirty为true,因此会重新运行getter进行运算

对于计算属性的setter方法,当设置计算属性的时候,直接运行setter就可以了。

😊 好了, 以上就是我的分享,大家对于computedmethods还有其它理解的话可以在评论区讨论鸭~希望小伙伴们点赞 👍 支持一下哦~ 😘,我会更有动力的 🤞