Vue3—侦听器watch的用法

371 阅读1分钟

Watch

作用:watch侦听器,可侦听响应式变量ref、reactive的数据变化。一旦数据发生变化,就自动执行监听回调。

语法

watch(source, (cur, pre) => {})

参数

watch有三个参数:

第一个参数是侦听器的(source),用于指定要侦听的响应式变量。这个来源可以是一个 ref一个响应式对象或是由以上类型的值组成的数组。

第二个参数是在发生变化时要调用的回调函数。该回调函数有三个参数,分别是cur(新值)、pre(旧值)以及一个回调函数。

第三个可选的参数是一个对象。如果需要深度监听,则deep:true。常见用法有{deep:true}、{ immediate: true }。

示例:当reactive对象嵌套对象时,此刻的deep生效。

const user = reactive({
   name:"tom",
   age:18,
   gender:"male",
   hobby:{
     sing:"唱歌",
     dangce:"跳舞"
   }
})
watch(()=>user.hobby,(cur,pre)=>{
  console.log(cur,pre);
},{deep:true})

当watch 监听多个数据时需用中括号[ ]括起来,值与值之间用逗号分隔。

watch的使用:

1.watch侦听ref响应式数据 (侦听单个数据源)

<template>
  <div>
    <p>
      {{ message }}
    </p>
    <button @click="changeMsg">
      改变message
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
const message = ref('helloWorld');
const changeMsg = () => {
  message.value = '你好世界';
};
// 监听 message 变量,如果有发生变化,自动执行后面的回调函数
watch(message, (cur, pre) => {
  changeMsg();
  console.log(cur,pre); // 你好世界 helloWorld
},{deep:true});
</script>

2.watch侦听reactive响应式数据中某个属性或某一些数据的变化

<template>
  <div>
    <p>
      {{ user }}       <!-- ['KoKo', 18, 'male']-->
      {{ user.name }}  <!-- KoKo -->
    </p>
    <button @click="changeName">
      修改姓名
    </button>
  </div>
</template>

<script setup lang="ts">
import { reactive, watch } from 'vue';

const user = reactive({
  name: 'tom',
  age: 18,
  gender: 'male'
});
const changeName = () => {
  user.name = 'KoKo';
};
//监听 user 变量里的数据,如果有发生变化,自动执行后面的回调函数
//监听 [user.name, user.age,user.gender] 多个响应式数据,其中一个数据发生变化,就会触发 watch 回调函数
watch([() => user.name, () => user.age, () => user.gender], (cur, pre) => {
  changeName();
  console.log(cur,pre); // ['KoKo', 18, 'male'] ['tom', 18, 'male']
});
</script>

3.stop停止监听

<script setup lang="ts">
//如果在组件销毁之前想要停止掉某个监听,可以使用stop停止监听
const stopWatch = watch(source,(cur,pre) => {
      console.log("新值:", cur, "老值:", pre);
}, {deep:true});
// 当不再需要此侦听器时:
stopWatch()

//或使用定时器
//setTimeout(()=>{
    // 停止监听
//    stopWatch()
//  }, 2000);
</script>

watch进阶总结使用:

1.watch侦听ref响应式数据

<template>
  <div>test</div>
</template>

<script setup lang='ts'>
import { ref, reactive, watch, onMounted } from 'vue';
// watch侦听ref响应式数据
const c = ref({
  name: 'c',
  prop: 'prop'
});
const d = ref({
  name: 'd',
  prop: 'prop'
});
const c1 = ref({
  name: 'c1',
  prop: {
    name: 'c1',
    prop: 'prop'
  }
});
const d1 = ref({
  name: 'd1',
  prop: {
    name: 'd1',
    prop: 'prop'
  }
});

onMounted(() => {
  // watch侦听ref数据
  c.value.name = 'c-1';
  d.value.name = 'd-1';
  c1.value.prop.name = 'c1-1';
  d1.value.prop.name = 'd1-1';
});

// 1.watch侦听ref定义的一个或多个响应式数据,需要手动开启deep,否则无法侦听
watch(c, (cur, pre) => {
  console.log(cur, pre); // {name: 'c-1', prop: 'prop'} {name: 'c-1', prop: 'prop'}
}, { deep: true });
watch([c, d], (cur, pre) => {
  console.log(cur, pre); // [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}] [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}]
}, { deep: true });
// 2.watch侦听ref定义的一个响应式数据的一个或多个属性-基本数据
watch(() => c.value.name, (cur, pre) => {
  console.log(cur, pre); // c-1 c
});
watch([() => c.value.name, () => d.value.name], (cur, pre) => {
  console.log(cur, pre); // ['c-1', 'd-1'] ['c', 'd']
});
// 3.watch侦听ref定义的一个响应式数据的一个或多个属性-引用数据类型,无法获取preValue,需要手动开启deep,否则无法侦听
watch(() => c1.value.prop, (cur, pre) => {
  console.log(cur, pre); // {name:'c1-1',prop:'prop'}  {name:'c1-1',prop:'prop'}
}, { deep: true });
watch([() => c1.value.prop, () => d1.value.prop], (cur, pre) => {
  console.log(cur, pre); // [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}] [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}]
}, { deep: true });

</script>

2.watch侦听reactive响应式数据

<template>
  <div>test</div>
</template>

<script setup lang='ts'>
import { ref, reactive, watch, onMounted } from 'vue';
// watch侦听reactive响应式数据
const c = reactive({
  name: 'c',
  prop: 'prop'
});
const d = reactive({
  name: 'd',
  prop: 'prop'
});
const c1 = reactive({
  name: 'c1',
  prop: {
    name: 'c1',
    prop: 'prop'
  }
});
const d1 = reactive({
  name: 'd1',
  prop: {
    name: 'd1',
    prop: 'prop'
  }
});

onMounted(() => {
  // watch侦听reactive数据
  c.name = 'c-1';
  d.name = 'd-1';
  c1.prop.name = 'c1-1';
  d1.prop.name = 'd1-1';
});

// 1.watch侦听reactive定义的一个或多个响应式数据,会自动开启深度监听但无法获取preValue
watch(c, (cur, pre) => {
  console.log(cur, pre); // {name: 'c-1', prop: 'prop'} {name: 'c-1', prop: 'prop'}
});
watch([c, d], (cur, pre) => {
  console.log(cur, pre); // [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}] [{name:'c-1',prop:'prop'},{name:'d-1',prop:'prop'}]
});
// 2.watch侦听reactive定义的一个响应式数据的一个或多个属性-基本数据
watch(() => c.name, (cur, pre) => {
  console.log(cur, pre); // c-1 c
});
watch([() => c.name, () => d.name], (cur, pre) => {
  console.log(cur, pre); // ['c-1', 'd-1'] ['c', 'd']
});
// 3.watch侦听reactive定义的一个响应式数据的一个或多个属性-引用数据类型,无法获取preValue,需要手动开启deep,否则无法侦听
watch(() => c1.prop, (cur, pre) => {
  console.log(cur, pre); // {name:'c1-1',prop:'prop'}  {name:'c1-1',prop:'prop'}
}, { deep: true });
watch([() => c1.prop, () => d1.prop], (cur, pre) => {
  console.log(cur, pre); // [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}] [{name:'c1-1',prop:'prop'},{name:'d1-1',prop:'prop'}]
}, { deep: true });

</script>