Vue-数据监听

Vue-数据监听

从vue框架中导入watch方法,可使用watch方法实现对响应式数据的监听

<script setup>
import { reactive, ref, watch } from "vue";
let fullname = ref("");
let firstname = ref("");
let lastname = reactive({
  name: "",
});
</script>

<template>
  <div>
    姓氏:<input type="text" v-model="firstname" /> <br />
    名字:<input type="text" v-model="lastname.name" /> <br />
    全名:{{ fullname }}
  </div>
</template>

<style scoped>
</style>

ref响应式数据的监听

使用watch监听ref修饰的响应式数据时,watch中应该有两个参数:

  • 一个变量:被监听的变量名称
  • 一个函数:当响应式数据发生改变时,要执行的函数(推荐使用箭头函数)
//这段代码为:监听响应式数据firstname,当该数据发生变化时将字符串拼接到fullname中
watch(firstname, (newValue, oldValue) => {
  fullname.value = newValue + lastname.name;
});

要执行的函数中,能接到两个参数:newValue时更改后的数据,oldValue是更改前的数据

reactive响应式数据的监听

使用watch监听reactive修饰的响应式数据时,watch中应该有两个参数:

  • 一个函数,该函数返回被监听的变量/对象
  • 一个函数,当响应式数据发生变化时,要执行的函数
监听属性

当第一个参数返回值为对象中的属性时:

//这段代码为:监听响应式数据对象lastname中的name属性,当该数据发生变化时将字符串拼接到fullname中
watch(
  () => {
    return lastname.name;
  },
  (newValue, oldValue) => {
    fullname.value = firstname.value + newValue;
  }
);
监听对象

当第一个参数返回值为对象本身时(也就是直接监听此对象),watch需要再增加一个参数:

  • {deep:true}:增加此键值对对象,表明设置该watch为深度监听,即可实现监听对象
//这段代码为:监听响应式数据对象lastname,当对象中的任何数据发生变化时将字符串拼接到fullname中
watch(
  () => {
    return lastname;
  },
  () => {
    fullname.value = firstname.value + lastname.name;
  },
  { deep: true }
);

注:当监听对象时,newValue和oldValue参数都为对象本身,没有意义


原始数据的immediate参数

当监听的响应式数据有原始数据时,因为数据没有发生改变,所以函数也不会执行

immediate参数的默认值为false,当他为true时,将会在页面加载时立刻执行一次函数

watch(
  () => {
    return lastname;
  },
  () => {
    fullname.value = firstname.value + lastname.name;
  },
  { deep: true, immediate: true }
);

watchEffect

此API从vue框架中导入

此API中只有一个参数:

  • 一个函数:当响应式数据发生改变时,要执行的函数(推荐使用箭头函数)

此API无需区分ref和reactive的用法

watchEffect并不是监听所有响应式数据,他只监听在函数中使用过的响应式数据

<script setup>
import { reactive, ref, watchEffect } from "vue";
let fullname = ref("");
let firstname = ref("xiao");
let lastname = reactive({
  name: "bai",
});

watchEffect(()=>{
  fullname.value = firstname.value + lastname.name;
})
</script>

<template>
  <div>
    姓氏:<input type="text" v-model="firstname" /> <br />
    名字:<input type="text" v-model="lastname.name" /> <br />
    全名:{{ fullname }}
  </div>
</template> 

<style scoped>
</style>

然而,在实际开发中,使用双向绑定即可完成大部分的需求,这章仍然是白学 😓