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

_Minato_ 2024-08-20 13:03:01 阅读 72

前言

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

概念

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

基本使用方法

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

<code>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()  可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。