Vue3 新特性学习(三)计算属性computed和侦听器watch

6,881 阅读3分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

对于 Vue3, 已经发布有一段时间了, 也断断续续探索过, 学习过, 但不是太系统, 也没有总结, 借这个周末作个简单的总结:

上文我们对于 Vue3进行了初体验, 以及 Vue3 生命周期和 setup() 函数的具体使用. 本文继续来学习 Vue3.x的两个特性:

computedwatch 是两个调用的比较多的知识点,

  • computed 表示计算属性, 通常用于处理数据, 方便在模板中的简化书写;
  • watch 表示监听,

Vue3 仓库 & 文档地址

Vue3 的源码仓库: github.com/vuejs/vue-n…

Vue3 的文档地址: v3.vuejs.org/

一个 使用 Vue3 的小练习: Vue3 + TypeScript: github.com/xn213/zhihu…

computed 计算属性

在模板中我们使用数据时使用 双大括号{{}}, 有时候数据不是我们想要的类型, 就会在 {{}} 中书写表达式, 这样就会是模板变得繁琐而不易读. 所以这通常不是好的书写方案, Vue 为我们提供了一些更好的方案, computed 计算属性就是其中一个

使用 computed 我们可以将数据处理成我们想要的格式, 而不是在模板中使用更长的计算表达式,

// 实战项目中 src/pages/PostDetail.vue
// 通过 computed 处理 html 模板 / 图片格式处理等等
const currentHTML = computed(() => {
  if (currentPost.value && currentPost.value.content) {
    return md.render(currentPost.value.content)
  }
  return { ni: 'ni' }
})
const currentPost = computed<PostProps>(() => store.getters.getCurrentPost(currentId))
const currentImageUrl = computed(() => {
  if (currentPost.value && currentPost.value.image) {
    const { image } = currentPost.value
    return (image as ImageProps).url + '?x-oss-process=image/resize,w_850'
  } else {
    return null
  }
})

Vue3 中的 watch 侦测数据变化

Vue3 -- Watch 文档地址

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

// watch 的简单应用
watch(data, () => {
  document.title = 'updated ' + data.count
})
// watch 的两个参数,同样也是代表新的值和旧的值
watch(refData.count, (newValue, oldValue) => {
  console.log('old', oldValue)
  console.log('new', newValue)
  document.title = 'updated ' + data.count
})

// watch 多个值,返回的也是多个值的数组
watch([greetings, data], (newValue, oldValue) => {
  console.log('old', oldValue)
  console.log('new', newValue)
  document.title = 'updated' + greetings.value + data.count
})

// 使用 getter 的写法 watch reactive 对象中的一项
watch([greetings, () => data.count], (newValue, oldValue) => {
  console.log('old', oldValue)
  console.log('new', newValue)
  document.title = 'updated' + greetings.value + data.count
})

使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

除了 watch 选项之外,你还可以使用命令式的 vm.$watch API

计算属性 VS 侦听器

在项目开发中, 当有一些数据需要处理: 随着其它数据变动而变动时,你很容易滥用 watch, 但是通常更好的做法是使用计算属性 computed, 而不是命令式的 watch 回调

计算属性是基于它们的响应依赖关系缓存的。计算属性只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 author.books 还没有发生改变,多次访问 publishedBookMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。