本篇文章,分享一下vue中侦听器(watch
)的核心用法。
注:侦听器有两种:一个是watch,一个是watchEffect。文章篇幅有限,先介绍watch侦听器
侦听器,是vue中非常非常实用的一个功能。
例如,在一个电商应用中,当用户筛选商品,修改了价格区间时,页面就应该根据用户的操作,进行相应的调整,这就涉及到侦听器的使用。
1、基础使用
侦听器watch
是一个函数,它的名字跟功能一样,就是watch(看)
。
看啥呢?
就看,传给它的参数。
例如,代码中有个变量叫abc
,只要这个变量发生变化了,就执行回调函数——打印一段文字 “ 变化了额
”。
代码如下:
<script setup>
import { ref, watch } from 'vue'
const abc = ref('')
watch(abc, () => {
console.log('变化了额');
})
</script>
<template>
<p>
输入一段文字:
<input v-model="abc" />
</p>
</template>
渲染结果展示如下:
2、watch函数
watch
函数可以监听一个或多个响应式数据的变化,当其中任何一个数据发生变化时,回调函数都会被激活。
下面讲一下,watch
函数的传参:
第一个参数
watch()
函数的第一个参数,可以是如下几种类型:
- 一个函数,返回一个值
- 一个 ref
- 一个响应式对象
- …或是由以上类型的值组成的数组
ref
类型在第一章节
已经演示过了。下面,演示一下其它几种形式。
<script setup>
import { reactive, ref, watch } from 'vue'
const abc = reactive({ str: "" })
const abc1 = ref('')
watch(() => abc.str, () => { //侦听getter函数
console.log('getter函数: 变化了额');
})
watch(abc, () => { //侦听reactive对象
console.log('reactive: 变化了额');
})
watch([abc1, () => abc.str], () => { //侦听它们组合的数组,
//只要数组中有一个元素变化,就会调用回调函数
console.log('数组: 变化了额');
})
</script>
<template>
<p>
输入一段文字:
<input v-model="abc.str" />
</p>
<br>
<p>
另外,再输入一段文字:
<input v-model="abc1" />
</p>
</template>
当第一段输入框里的文字发生变化时,三个回调函数均被调用。
渲染结果如下:
当第二段输入框里的文字发生变化时,侦听数组的那个回调函数,会被调用。
渲染结果如下:
第二个参数
第二个参数,是一个回调函数。
当侦听数据发生变化时,该函数会被触发。
这个回调函数的传参列表里,有三个参数:新值,旧值,回调函数(没错!回调函数中,又有回调函数)。
这里展示一下:新值和旧值的用法
。
如果,侦听的是,单一数据,则新旧值也是单一变量;
如果,侦听的是,多个数据,那么新旧值使用的是数组变量。
代码如下:
<script setup>
import { reactive, ref, watch } from 'vue'
const abc = reactive({ str: "" })
const abc1 = ref('')
watch(() => abc.str, (newValue, newValue) => {
console.log('oldValue ', oldValue);
console.log('newValue ', newValue);
})
watch([abc1, () => abc.str], ([newValue1, newValue2],[oldValue1, oldValue2]) => {
console.log('oldValue1 ', oldValue1);
console.log('oldValue2 ', oldValue2);
console.log('newValue1 ', newValue1);
console.log('newValue2 ', newValue2);
})
</script>
<template>
<p>
输入一段文字:
<input v-model="abc.str" />
</p>
<br>
<p>
另外,再输入一段文字:
<input v-model="abc1" />
</p>
</template>
首先,改动第一个输入框里的内容,可以看到:新值和旧值,都被打印了出来。
每输入一个数字,回调函数就会被触发一次。
第二个watch
函数传入了一个数组,它也同样侦听了abc
的变化,
因此,它的回调函数也会被触发。
渲染结果如下:
第三个参数
第三个参数是可选的,参数类型是一个对象。
例如:{once:true}
对象里有如下几个内置的可选项:
- immediate
当immediate
为 true时,侦听器在创建的那一刻,就触发一次回调。
而不必等到被监听数据变化时,才首次触发。
代码如下:
<script setup>
import { reactive, ref, watch } from 'vue'
const abc = reactive({ str: "" })
watch(() => abc.str, (newValue, oldValue) => {
console.log('oldValue ', oldValue);
console.log('newValue ', newValue);
}, { immediate: true })
</script>
<template>
<p>
输入一段文字:
<input v-model="abc.str" />
</p>
</template>
旧值在初次调用的时候为undefined
。
渲染结果如下:
- deep 深度监听。
被监听的数据,如果是一个对象或数组,并且deep
设置为true
。
那么, watch不仅会监听对象或数组的引用变化(即整个对象或数组被重新赋值),还会监听对象的属性或数组中,元素的变化。
如果deep
为false
(默认值),则只监听对象或数组的引用变化。
举例来说,代码中定义一个reactive变量,
const abc = reactive({ str: "", count: 0, a1: { str1: '123' } })
。
可以看出这个变量有一丢丢复杂,abc
对象里面有个对象元素a1
, a1
里面又嵌套一个str1
元素。
接着,将deep
设置为false
。
代码展示如下:
<script setup>
import { reactive, ref, watch } from 'vue'
const abc = reactive({ str: "", count: 0, a1: { str1: '123' } })
watch(abc, (newValue, oldValue) => {
console.log('oldValue ', oldValue);
console.log('newValue ', newValue);
}, { deep: false }) //这里使用false
</script>
<template>
<p>
输入一段文字:
<input v-model="abc.a1.str1" /> //这里使用 abc.a1.str1作为绑定字段
</p>
</template>
可以看出,无论我们输入怎样的内容,都不会触发回调函数。
页面渲染如下:
而,当把deep
改为{deep:true}
之后,watch
就是深层次监听了,回调函数就可以被触发了。
页面渲染如下:
除了上面两个可选参数之外,还有其它的可选参数:
- flush 调整回调函数刷新
- onTrack/onTrigger 调试侦听器依赖
- once 回调函数仅运行一次
它们使用方式与上面介绍的两个,基本相同。只是功能不同。
文章篇幅有限,就不再一一列举这些参数的使用了。
大家有兴趣的话,可以去vue官网了解一下,这些参数的具体作用。
以上,就是vue
中侦听器(watch)
的核心用法,感谢阅读。