Vue3 watch侦听器

一 侦听响应式ref

侦听响应式ref常量,当常量的ref的value值发生改变时会触发watch

一个小栗子:当输入框的输入内容变化时下方的文本也会跟着改变

<template>
  <div class="box content">
    <div class="intro">
      <el-input v-model="input" @change="inputChange"></el-input>
    </div>
    <div class="intro">
      <el-text>{{ message }}</el-text>
    </div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
import { getCurrentInstance } from 'vue';

const instance = getCurrentInstance().proxy;

const input = ref("");
const message = ref("");

watch(input, (newValue, oldValue) => {
  message.value = "input值发生了变化,newValue = " + newValue + ", oldValue = " + oldValue;
});

/** 事件回调 */
const inputChange = () => {
  console.log("input value = ", input.value);
}
</script>
<style scoped lang="less">
.box{
  display: flex;
  flex-direction: column;
  margin: 10px;
  padding: 15px;

  .intro{
    padding: 20px;
  }
}
</style>

二 监听reactive响应式对象

系统默认是深层监听,当响应式对象的属性发生改变时,会触发watch

一个小栗子:当点击一次primary按钮时,可以看到cmpNum的count会加3

<template>
  <div class="box content">
    <div class="intro">
      <el-button type="primary" @click="cmpNumChange">cmpNum.count = {{ cmpNum.count }}</el-button>
    </div>
    <div class="intro">
      <el-text>{{ cmpMsg }}</el-text>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
import { getCurrentInstance } from 'vue';

const instance = getCurrentInstance().proxy;

const cmpNum = reactive({count: 0});
const cmpMsg = ref("");

// 监听reactive响应式对象,系统默认是深层监听,当响应式对象的属性发生改变时,会触发watch
// 当点击一次primary按钮时,可以看到cmpNum的count会加3
watch(cmpNum, (newValue, oldValue) => {
  cmpMsg.value = "cmpNum.cout = " + cmpNum.count;
});

// 注:当监听响应式对象时,不能直接监听响应式对象的value
watch(
  () => cmpMsg.value,
  (value) => {
    console.log("watch cmpMsg value = ", value);
  }
)

/** 事件回调 */
const cmpNumChange = () => {
  cmpNum.count = cmpNum.count + 2;
  console.log("cmpNum.value = ", cmpNum.count);
}
</script>
<style scoped lang="less">
.box{
  display: flex;
  flex-direction: column;
  margin: 10px;
  padding: 15px;

  .intro{
    padding: 20px;
  }
}
</style>

三 深层侦听器

直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发

一个小栗子 :当点击button时,会在回调事件中改变person的属性,从而触发侦听器watch

在使用时,主要是在代码中加入:{deep: true}

<template>
  <div class="box content">
    <div class="intro">
      <el-button type="primary" @click="changePersonName">person name is {{ state.person.name }}</el-button>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
import { getCurrentInstance } from 'vue';

const person = {name: "Pem", age: 20};
const state = ref({person: person});

// 使用deep:true属性,进行对象的深层监听
watch (
  () => state.value.person,
  (newValue, oldValue) => {
    console.log("deep newValue = ", newValue);
    console.log("deep oldValue = ", oldValue);
  },
  {deep: true}
)

/** 事件回调 */
const changePersonName = () => {
  state.value.person.name = input.value + ".Pem";
}
</script>
<style scoped lang="less">
.box{
  display: flex;
  flex-direction: column;
  margin: 10px;
  padding: 15px;

  .intro{
    padding: 20px;
  }
}
</style>

四 即时回调的侦听器

watch在默认情况下是懒加载的,仅在数据源发生变化时才会触发。但在某些场景下,我们希望在创建watch时立即执行一次回调。

我们可以通过传入 immediate: true 选项来强制侦听器的回调立即执行。

一个小栗子:

<template>
  <div class="box content">
    <div class="intro">
      <el-input v-model="immediateInput"></el-input>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';

const immediateInput = ref("");

// 即使回调的侦听器
/* 
watch默认是懒执行的:仅当数据变化时,才会执行回调。但在某些场景中,我们希望在创建某些侦听器时,
立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据
在下面的例子中,可以看到在页面第一次渲染出来后就可以看到在watch中设置的初始值,说明这个watch
被执行了一次
*/
watch (
  () => immediateInput.value,
  (newValue, oldValue) => {
    console.log("new value = ", newValue);
    if (newValue === "") {
      getStartValue();
    }
  },
  {immediate: false}   //这里需要加入这句
)
function getStartValue(){
  immediateInput.value = "start base value";
  console.log("getStartValue");
} 
</script>
<style scoped lang="less">
.box{
  display: flex;
  flex-direction: column;
  margin: 10px;
  padding: 15px;

  .intro{
    padding: 20px;
  }
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值