3分钟带你了解——Vue的监听器

前言

前端开发时时常碰到这样的业务,表单中某个值发生修改后调用如发送请求、显示对话框的方法。除了使用组件的回调事件外,我们也可以使用Vue提供的监听器Api来实现这样的需求。

概念

监听器 watch 是 Vue 内部提供的一个用于侦听功能的更通用的方法,其用来响应数据的变化,通过特定的数据变化驱动一些操作。Vue 官方文档解释当需要在数据变化时执行异步或开销较大的操作时,推荐使用该方法。

基本使用方法

在 Vue2 中,watch 是一个用于观察和响应 Vue 实例上的数据更改的选项。watch 选项允许你指定一个或多个观察者,当被观察的数据发生变化时,会触发相应的处理函数。

new Vue({  
  el: '#app',  
  data: {  
    message: 'Hello Vue!'  
  },  
  watch: {  
    message: function(newValue, oldValue) {  
      console.log('message changed from', oldValue, 'to', newValue);  
    }  
  }  
});

在 Vue 3 中,watch 的使用方式与 Vue 2 类似,但有一些差异和改进。Vue 3 引入了 Composition API,使得组织和复用代码更加灵活。以下是 Vue 3 中使用 watch 的示例:

import { watch, ref } from 'vue';  
  
export default {  
  setup() {  
    const count = ref(0);  
  
    watch(count, (newVal, oldVal) => {  
      console.log(`Count changed from ${oldVal} to ${newVal}`);  
    });  
  
    return { count };  
  }  
};

深度监听

深度监听(deep watching)在 Vue 中是指不仅监听对象或数组本身的变化,还监听其内部嵌套属性或元素的变化。

例如,如果你有一个包含对象的数组,并且你想要监听数组中每个对象的属性变化,那么你就需要使用深度监听。Vue 会递归地观察这些对象或数组,以确保任何内部的变化都能被捕捉到。

Vue2 开启深度监听

new Vue({  
  el: '#app',  
  data: {  
    obj: {  
      name: 'Alice',  
      age: 25  
    }  
  },  
  watch: {  
    obj: {  
      handler: function(newValue, oldValue) {  
        console.log('obj changed:', newValue);  
      },  
      deep: true, // 深度观察对象内部的更改  
      immediate: true // 立即执行一次处理函数  
    }  
  }  
});

Vue3 开启深度监听

import { watch, reactive } from 'vue';  
  
export default {  
  setup() {  
    const state = reactive({ count: 0 });  
  
    watch(  
      () => state.count,  
      (newCount, oldCount) => {  
        console.log(`Count changed from ${oldCount} to ${newCount}`);  
      },  
      { deep: true }  
    );  
  
    // 注意:在这个特定例子中,使用 deep: true 实际上是不必要的,因为我们只观察 state.count。  
    // 但如果你要观察整个 state 对象或其包含嵌套属性的部分,那么 deep: true 将是有用的。  
  
    return { state };  
  }  
};

注意:深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

watchEffect()

侦听器的回调使用与源完全相同的响应式状态是很常见的。例如下面的代码,在每当 toolId 的引用发生变化时使用侦听器来加载一个远程资源:

const todoId = ref(1)
const data = ref(null)

watch(
  todoId,
  async () => {
    const response = await fetch(
      `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
    )
    data.value = await response.json()
  },
  { immediate: true }
)

特别是注意侦听器是如何两次使用 toolId 的,一次是作为源,另一次是在回调中。我们可以用 watchEffect() 来简化上面的代码。watchEffect() 允许我们自动跟踪回调的响应式依赖。上面的侦听器可以重写为:

watchEffect(async () => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
  )
  data.value = await response.json()
})

对于这种只有一个依赖项的例子来说,watchEffect() 的好处相对较小。但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。此外,如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect()  可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值