阅读 333

浅析和总结一下Vue中computed,watch的使用

前言

目前使用vue也有一段时间了,埋头开发的时候也积累了不少困惑,当然,也积累了一些宝贵的经验。平日在论坛和一些评论区中闲逛时,也对很多大佬提出的问题,建议有了点自己的思考。于是便想着手开始动笔,认真的写些有用的东西。

PS:如果没了解过或是忘了computed和watch的基本使用的话,建议还是去翻翻官方文档吧!

cn.vuejs.org/v2/guide/co…

一、聊聊computed和watch

初学时沉浸在Vue的其他特性当中"无法自拔",没有认真的去琢磨这两个属性。直到上了项目···开始傻傻分不清了才慌忙去翻文档。现在想着在blog中好好总结一下,希望有缘人能看到并且能对你有点帮助吧:)

1、computed

首先为什么会有computed?它解决了什么?

作为本科四年都在开发adr的同学,见惯了View和Class(业务逻辑)的“强分离”,初见模板内表达式直呼真香的同时也带着一丝困惑,既然将view层单独抽出,但又提供了一些可以写逻辑代码的空间,那么不可避免的会有人在模板中塞下如下代码

<div id="example">
    {{ example.getMax() > 0 ? 1 : 2}}
</div>
复制代码

当然,这个例子浅显易懂,但真实的项目中或许有更加复杂的业务逻辑被强塞其中,想象一下,若是复杂的DOM树中夹杂着大量如此复杂的,和业务逻辑相关的表达式,那模板将失去它的简洁明了的特点,并且会让简单的DOM树变得晦涩难懂且难以维护。 由此,computed便来了,它的目标便是--解决和维护可能出现在模板中的一些逻辑表达式。在Vue3中,一些逻辑可以写成如下代码

setup() {
    const test = computed(() => example.value.getMax())
    // ...也可以做更多的逻辑处理
    return {
        test
    }
}
复制代码

当模板中较为复杂的逻辑都抽离开来,这样就会使得我们的代码变得更加易懂和可维护了!

computed的响应式

当然,被computed包裹后返回出来的变量是响应式的,比如:

  const playlist = computed(() => store.state.playList)
  console.log(playlist)
  // log: 
  //ComputedRefImpl {_dirty: true, __v_isRef: true, __v_isReadonly: true, _setter: ƒ, effect: ƒ}
复制代码

注意这个ComputedRefImpl,有时候你的数据“莫名其妙”失去响应式,而你还不明真相,这是查看一下是否是XXRefImpl,从而判断是否失响。 于是,computed在模板中的作用和普通function作用差异体现出来了普通函数在模板中使用,每次渲染模板都会调用,而computed,Vue内部做了响应式缓存,只有依赖的变量发生变化,才会再执行

2、watch

尤大在官网中建议,滥用watch来代替computed是不可取的,当然,个人认为,watch使用于重量级的业务场景,提供的oldVal和newVal的使用便可看出来,watch也更针对新老数据变更的这种场景。

简单的watch使用就不在这赘述啦,这里我还想再补充一个watch使用知识点----当想监听的数据不是响应式的该如何去做? 很简单,监听一个返回该数据的方法便可

watch(() => props.data, async () => {
  todoData()
  calculate()
})
复制代码

注意,props在setup中带来的变量会失去响应式,由此,我们可以传递一个函数进去来解决。

二、自己在日常开发中的使用

1、比如从store中拿取数据,返回到模板中,我便会使用computed,当然传递的函数中间也可以加一些逻辑处理...

const list = computed(() => store.state.XXList)
复制代码

2、watch一般用于重量级业务场景,比如复杂的计算或者数据处理,还加载着存取数据

  const useXXXEffect = (store, XXXRef, progress) => {
  const xx = computed(() => store.state.xx)
  watch(xx, async (newxx) => {
    if (newxx) {
      await nextTick()
      XXXRef.value.setOffset(progress.value)
    }
  })
  return {
    xx
  }
}
复制代码

写在最后

这是一篇偏个人笔记向的文章,笔者功力较浅,希望简单的一些笔记能够对帮助到有需要的人

文章分类
前端
文章标签