computed与watch到底有什么区别?

咱也不去深刨什么源码。

从实际使用来讲就一句话:你computed能做的,我watch能做,你computed做不了的,我watch也能做!

只是从代码的优雅度来讲,因为watch是根据响应式副作用触发的回调,在这个回调函数里面,可以做任何前提为数据发生变化所想执行的操作,并且能拿到修改之前的值。

而computed是依赖于一个响应式数据,当这个数据发生改变,执行方法根据这个数据衍生出一个新数据。并且计算属性值会基于其响应式依赖被缓存。如果依赖的数据没有发生变化,就可以直接返回缓存的值,避免了重复计算的开销。 这个也是它还能存在的原因。不然直接watch一把梭了。

下面是几个场景分别看看watch跟computed是如何实现的。

场景一:需要监听一个响应式变量,一旦变量的值发生变化就执行里面代码。

js 复制代码
<template>
  <div class="difference">
    <h2>我是数字 {{ count }}</h2>
    <h2>我是watch {{ watchDoubleCount }}</h2>
    <h2>我是computed {{ computedDoubleCount }}</h2>
    <el-button type="primary" @click="countClick">按钮</el-button>
  </div>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
const count = ref(1)
const watchDoubleCount = ref(null)

function countClick() {
  count.value++
}

// watch示例
// 每次count变化时,watch中的回调函数都会被调用。
watch(
  count,
  (newVal, oldVal) => {
    //数据发生变化所想执行的操作
    console.log('------watch------')
    watchDoubleCount.value = newVal * 2
    console.log('新值:' + newVal, '旧值:' + oldVal)
  },
)
// computed示例
// computed会自动跟踪count的变化,并在count变化时重新计算computedDoubleCount的值。
const computedDoubleCount = computed(() => {
  console.log('------computed------')
  console.log('新值:' + count.value)
  console.log('旧值:无从获取')
  //根据这个数据衍生出一个新数据。
  return count.value * 2
})
</script>

还没执行任何操作时(还没点击按钮),因为watch是根据回调函数执行还没有被触发,而计算属性computed会在页面初始化时立即执行一次,是为了确保初始值是正确的,并将其缓存起来。当然给watch传入第三个参数{immediate: true}也是可以立即执行一次的。


点击按钮对数字进行了更改,可以看到里面方法都有被执行,效果是一样的。

但是如果是下面这种情况computed就无能为力了

场景二:需要监听一个对象,一旦对象的某条属性发生变化就执行里面代码。注意是某一条。

js 复制代码
<template>
  <div class="difference">
    <h2>我是数字 {{ count.salary }}</h2>
    <el-button type="primary" @click="countClick">按钮</el-button>
  </div>
</template>

<script setup>
import { ref, watch, computed } from 'vue'

const count = ref({
  name: '张三',
  age: 25,
  gender: '男',
  occupation: '工程师',
  salary: 1000,
  isMarried: false
})

function countClick() {
  count.value.salary++
}

//watch示例
watch(
  count,
  (newVal, oldVal) => {
    console.log('------watch------')
    // watchDoubleCount.value = newVal.salary * 2
    // console.log('新值:' + newVal.salary, '旧值:' + newVal.salary)
  },
  { deep: true }
)

// computed示例
const computedDoubleCount = computed(() => {
  console.log('------computed------')
  console.log(count.value)
  // console.log('新值:' + count.value.salary)
  // console.log('旧值:无从获取')
})

因为如果给computed确切的去指出哪一条属性的话,那么它会自动添加依赖。这并不是我想要的某一条情况,另外这种情况的话需要给 watch增加第三个参数{ deep: true }深度侦听。

看效果

能看出来只有watch实现了,里面的操作被多次执行。

因此,在实际使用中,如果只是简单的数据监听和计算,推荐使用computed,因为它会带来一定的性能提升。而对于一些需要执行副作用或者比较复杂的逻辑操作的情况,可以选择使用watch。

相关推荐
2601_949970691 分钟前
HumanizeDuration 跨端三方库仓颉适配全流程
前端·javascript·flutter
风骏时光牛马2 小时前
后端服务接口开发与性能优化
前端
kyriewen2 小时前
我让 4 个 AI 互相 review 代码,最温柔的那个下手最狠
前端·程序员·ai编程
考研保研资料分享2 小时前
无论文竞赛保研中科院植物所:三场考核、科研追问与准备复盘
面试
计算机魔术师2 小时前
493家公司白砸AI钱?Apollo这组数据戳破了幻觉
前端
救救孩子把2 小时前
AI面试八股文-23_23-Agent可观测性与生产监控面试题
人工智能·面试·职场和发展·agent·langsmith·langfuase
IT_陈寒2 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
柳杉3 小时前
用 Codex 完成智慧高速 3D 可视化大屏,从 18 张行业设计稿到可交互的运行监测中心
前端·ai编程·数据可视化
review445433 小时前
拿到 codex 第一步
前端·agent·vibecoding
鶴哥只手遮天3 小时前
jQuery 4.0 源码架构与工程实践-第 01 章 · 全景与工程结构:一个 20 岁库的自省
前端·javascript·jquery