写点什么

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

用户头像
法医
关注
发布于: 2021 年 06 月 13 日
请阐述一下computed和methods有什么区别?

🙌 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还有其它理解的话可以在评论区讨论鸭~希望小伙伴们点赞 👍 支持一下哦~ 😘,我会更有动力的 🤞

发布于: 2021 年 06 月 13 日阅读数: 18
用户头像

法医

关注

公众号@前端猎手 2020.07.17 加入

喜欢用写作记录自己技术成长过程

评论

发布
暂无评论
请阐述一下computed和methods有什么区别?