Vue3_2024_5天【vue2(3种)和vue3(5种)中watch的使用场景】watch、computed

上一章,我们主要介绍了计算属性与方法的区别、及计算属性Vue2和Vue3对比;

前言:这章主要介绍,vue中watch概念及vue2、3版本使用区别;

watch概念:允许你在数据变化时执行特定的逻辑(方法),从而实现更复杂的数据处理和业务逻辑。

第一:Vue2中的使用~监听器(监听基本类型、引用数据类型、立即执行):
  • 1.在 Vue 实例中,你可以定义一个 watch 属性来监听 data 属性的变化。【基本数据类型】
new Vue({  
  el: '#app',  
  data: {  
    message: 'Hello'  
  },  
  watch: {  
    message(newVal, oldVal) {  
      console.log(`消息发生变化 ${oldVal} 和 ${newVal}`);  
    }  
  }  
});
  • 2当你想监听一个对象或数组的内部变化时,你可以使用 deep 选项。【引用数据类型】
new Vue({  
  el: '#app',  
  data: {  
    obj: { a: 1 }  
  },  
  watch: {  
    obj: {  
      handler(newVal, oldVal) {  
        console.log('obj changed');  
      },  
      deep: true  
    }  
  }  
});

3.使用 immediate 选项,监听器将在 Vue 实例创建时立即执行一次。【立刻执行】

new Vue({  
  el: '#app',  
  data: {  
    message: 'Hello'  
  },  
  watch: {  
    message: {  
      handler(newVal, oldVal) {  
        console.log(`消息发生变化 ${oldVal}和 ${newVal}`);  
      },  
      immediate: true  
    }  
  }  
});
第二:vue3中的使用(以setup语法糖里举例):

vue3官网提到一共四种监听使用(有分的细-5种)

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

<script lang="ts" setup name="Person">
  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()
    }
  })
</script>

  • 2.深度监听~ ref 定义的【引用数据类型】
<template>
  <div class="person">
    <h1>情况二:监视【ref】定义的【对象类型】数据</h1>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改整个人</button>
  </div>
</template>

<script lang="ts" setup name="Person">
  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}
  }
  /* 
    监视,情况一:监视【ref】定义的【对象类型】数据,监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视
    watch的第一个参数是:被监视的数据
    watch的第二个参数是:监视的回调
    watch的第三个参数是:配置对象(deep、immediate等等.....) 
  */
  watch(person,(newValue,oldValue)=>{
    console.log('person变化了',newValue,oldValue)
  },{deep:true})
  
</script>

注意:
*若修改的是ref定义的对象中的属性,newValue 和 oldValue 都是新值,因为它们是同一个对象。
*若修改整个ref定义的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了。

  • 3.深度监听~ reactive定义的【引用数据类型】

与 Vue 2 不同,Vue 3 的 watch 函数没有内置的 immediate 选项。但是,你可以在 watch 函数中立即调用回调函数来实现类似的效果。

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

<script lang="ts" setup name="Person">
  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)
  })
</script>

4.监视ref或reactive定义的【对象类型】数据中的某个属性,

注意点如下:
*若该属性值不是【对象类型】,需要写成函数形式。
*若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。

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

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

  // 数据
  let person = reactive({
    name:'张三',
    age:18,
    car:{
      c1:'奔驰',
      c2:'宝马'
    }
  })
  // 方法
  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})
</script>

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

5.监听上述多个数据

<template>
  <div class="person">
    <h1>情况五:监视上述的多个数据</h1>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <h2>汽车:{{ person.car.c1 }}{{ person.car.c2 }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changeC1">修改第一台车</button>
    <button @click="changeC2">修改第二台车</button>
    <button @click="changeCar">修改整个车</button>
  </div>
</template>

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

  // 数据
  let person = reactive({
    name:'张三',
    age:18,
    car:{
      c1:'奔驰',
      c2:'宝马'
    }
  })
  // 方法
  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,person.car],(newValue,oldValue)=>{
    console.log('person.car变化了',newValue,oldValue)
  },{deep:true})

</script>

第三:计算属性与监听器区别

Vue中的监听器(watch)和计算属性(computed)在功能和使用上有一些区别。

  • 1.功能上:
    计算属性:主要用于处理复杂逻辑和计算,基于它们的依赖进行缓存。只有当依赖的值发生改变时,计算属性才会重新计算。
    监听器:用于观察和响应 Vue 实例上的数据变化。当指定的数据项(如 data 或 computed 属性的值)发生变化时,监听器会触发相应的回调函数,执行特定的业务逻辑。

  • 2.缓存机制:
    计算属性:有缓存机制,只有当其依赖的属性发生变化时,才会重新计算。这有助于提高性能,特别是当计算属性涉及复杂的计算或异步操作时。
    监听器:没有缓存机制,每次监听的数据发生变化时,都会执行回调函数。

  • 3.异步操作:
    计算属性:不支持异步操作。如果需要在计算属性中进行异步操作,通常需要使用方法来替代。
    监听器:支持异步操作。你可以在监听器的回调函数中执行异步操作,如 API 调用等。

  • 4.数据依赖:
    计算属性:可以基于其他数据属性进行计算,并返回一个新的值。这个值会被缓存,并且只有当依赖的属性发生变化时才会重新计算。
    监听器:通常用于监听单个数据属性的变化。虽然也可以监听多个属性,但这通常不是监听器的典型用法。

  • 5.使用场景:
    计算属性:当你需要根据其他属性进行计算,并得到一个新的值时,使用计算属性。例如,购物车商品结算总价等。
    监听器:当你需要在数据变化时执行特定的逻辑,例如数据验证、异步获取数据等,使用监听器。例如,当搜索框内容发生变化时,发送请求获取相关搜索结果。

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值