vue watch与watchEffect

vue watch监视数据的变化

  • 作用:监视数据的变化(和Vue2中的watch作用一致)
  • 特点:Vue3中的watch只能监视以下四种数据
  1. ref定义的数据。
  2. reactive定义的数据。
  3. 函数返回一个值(getter函数)。
  4. 一个包含上述内容的数组。

我们在Vue3中使用watch的时候,通常会遇到以下几种情况

* 情况一

监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。

<h1>情况一:监视【ref】定义的【基本类型】数据</h1>
<h2>当前求和为:{{sum}}</h2>
<button @click="changeSum">点我sum+1</button>

import { ref,watch } from "vue";
// 数据
let sum = ref(0)
// 方法
function changeSum(){
  sum.value += 1
}
// 监视,情况一:监视【ref】定义的【基本类型】数据
const stopWatch = watch(sum,(newValue,oldValue)=>{
    console.log('sum变化了',newValue,oldValue)
    if(newValue >= 10){
      stopWatch()
    }
})   

* 情况二

监视ref定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部属性的数据,要手动开启深度监视。

注意:

  • 若修改的是ref定义的对象中的属性,newValueoldValue 都是新值,因为它们是同一个对象。

  • 若修改整个ref定义的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了。

<div>情况二:监视【ref】定义的【对象类型】数据</div>
<div>{{ person.name }},{{ person.age }}</div>
<el-button @click="changeName">修改名字</el-button>
<el-button @click="changeAge">修改年龄</el-button>
<el-button @click="changePerson">修改整个人</el-button>

import { ref, watch } from "vue";

// 数据
let person = ref({
  name: '张三',
  age: 18
})
// 方法
function changeName() {
  person.value.name += '~'
}
function changeAge() {
  person.value.age += 1
}
function changePerson() {
  person.value = { name: '李四', age: 90 }
}

/*  
    监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视
    watch的第一个参数是:被监视的数据
    watch的第二个参数是:监视的回调
    watch的第三个参数是:配置对象(deep、immediate等等.....) 
*/
watch(person, (newValue, oldValue) => {
  console.log('person变化了', newValue, oldValue)
},
  { deep: true }
)

* 情况三

监视reactive定义的【对象类型】数据,且默认开启了深度监视。

<div>情况三:监视【reactive】定义的【对象类型】数据</div>
<div>{{ person.name }},{{ person.age }}</div>
<el-button @click="changeName">修改名字</el-button>
<el-button @click="changeAge">修改年龄</el-button>
<el-button @click="changePerson">修改整个人</el-button>
<h2>测试:{{ obj.a.b.c }}</h2>
<el-button @click="test">修改obj.a.b.c</el-button>

import { reactive, watch } from "vue";

// 数据
let person = reactive({
  name: '张三',
  age: 18
})
let obj = reactive({
  a: {
    b: {
      c: 666
    }
  }
})
// 方法
function changeName() {
  person.name += '~'
}
function changeAge() {
  person.age += 1
}
function changePerson() {
  Object.assign(person, { name: '李四', age: 80 })
}
function test() {
  obj.a.b.c = 888
}
// 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
watch(person, (newValue, oldValue) => {
  console.log('person变化了', newValue, oldValue)
})
watch(obj, (newValue, oldValue) => {
  console.log('Obj变化了', newValue, oldValue)
})

* 情况四

监视refreactive定义的【对象类型】数据中的某个属性,注意点如下:

  1. 若该属性值不是【对象类型】,需要写成函数形式。
  2. 若该属性值是依然是【对象类型】,可直接编写,也可写成函数,建议写成函数。

结论:监视的如果是对象的属性,最好写函数式,注意点:如果监视的是地址值,需要关注对象内部,需要手动开启深度监视。

<div>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</div>
<div>{{ person.name }},{{ person.age }}</div>
<el-button @click="changeName">修改名字</el-button>
<el-button @click="changeAge">修改年龄</el-button>
<el-button @click="changeCar">修改整个车</el-button>
<el-button @click="changeC1">修改第一台车</el-button>
<el-button @click="changeC2">修改第二台车</el-button>

import { reactive, watch } from "vue";
// 数据
let person = reactive({
  name: '张三',
  age: 18,
  car: {
    c1: '奔驰',
    c2: '宝马'
  }
})
let obj = reactive({
  a: {
    b: {
      c: 666
    }
  }
})
// 方法
function changeName() {
  person.name += '~'
}
function changeAge() {
  person.age += 1
}
function changeC1() {
  person.car.c1 = '奥迪'
}
function changeC2() {
  person.car.c2 = '大众'
}
function changeCar() {
  person.car = { c1: '雅迪', c2: '爱玛' }
}
// 监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
watch(()=> person.name,(newValue,oldValue)=>{
  console.log('person.name变化了',newValue,oldValue)
})

// 监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,更推荐写函数
watch(() => person.car, (newValue, oldValue) => {
  console.log('person.car变化了', newValue, oldValue)
}, { deep: true })

* 情况五

监视情况四的多个数据

 <div>{{ person.name }},{{ person.age }},{{person.car.c1}},{{person.car.c2}}</div>
<el-button @click="changeName">修改名字</el-button>
<el-button @click="changeAge">修改年龄</el-button>
<el-button @click="changeCar">修改整个车</el-button>
<el-button @click="changeC1">修改第一台车</el-button>
<el-button @click="changeC2">修改第二台车</el-button>
// 监视多个数据
watch([()=>person.name,person.car],(newValue,oldValue)=>{
  console.log('person.car变化了',newValue,oldValue);
  },{deep:true}
)

watchEffect

  • 官网:立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。

  • watch对比watchEffect

    1. 都能监听响应式数据的变化,不同的是监听数据变化的方式不同

    2. watch:要明确指出监视的数据

    3. watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性,自动追踪所有使用的响应式数据,监听的是响应式数据的整个变化)。

<div>{{ sum }},{{ obj.age }},{{obj.name}}</div>
<el-button @click="changeSum">修改sum</el-button>
<el-button @click="changeAge">修改age</el-button>
<el-button @click="changeAll">修改obj</el-button>

import { reactive, watch,ref,watchEffect } from "vue";
let sum = ref(0)
let obj = reactive({age:18,name:'小明'})
function changeSum(){
  sum.value += 1
}
function changeAge(){
  obj.age = 28
}
function changeAll(){
  Object.assign(obj,{age:25,name:'拉拉拉'})
}


// 一、用watch实现,需要明确指出要监视sum、obj.age
watch(sum,(newVal)=>{
  console.log(newVal);
})
watch(()=>obj.age,(newVal)=>{
  console.log(newVal);
  
})
// 二、用watchEffect实现
watchEffect(()=>{
  console.log(sum.value,obj.age); 
})

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值