首页 > 其他分享 >watch监听

watch监听

时间:2024-12-24 09:42:18浏览次数:6  
标签:car watch 监听 person oldValue 监视 newValue

watch监听

参考地址:https://cn.vuejs.org/api/reactivity-core.html

特别注意:凡是监视对象类型,只要引用没有发生变化,oldValue和newValue一致。

作用:监视数据的变化(和Vue2中的watch作用一致)

特点:Vue3中的watch只能监视以下四种数据

ref定义的数据。

reactive定义的数据。

​ 函数返回一个值(getter函数)。

​ 一个包含上述内容的数组。

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

情况一 监视ref定义的【基本类型】数据

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

<template>
  <div class="person">
    <h2>监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。</h2>
    <h2>当前求和数据: {{sum}}</h2>
    <button @click="changeSum">点我sum + 1</button>
  </div>
</template>

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

  //数据
  let sum = ref(0)
  
  //方法
  function changeSum() {
    sum.value += 1;
  }

  //监视
  const stopWatch =  watch(sum, (newVlaue, oldValue) => {  //参数说明:监视对象, 回调函数
    console.log('sum变化了从' + oldValue + "变为了" + newVlaue);
    if(sum.value >= 10) {
      stopWatch()   //返回的是一个停止监听的函数
    }
  })
</script>

<style>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px; /* 盒子阴影 */
  border-radius: 10px;
  padding: 20px;
}

button {
  margin: 0 5px;
}
</style>

情况二 监视ref定义的【对象类型】数据

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

注意:

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

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

<template>
  <div class="person">
    <h2>监视ref定义的【对象类型】数据</h2>
    <h2>姓名: {{person.name}}</h2>
    <h2>年龄: {{person.age}}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改人</button>
  </div>
</template>

<script setup lang="ts" 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};
  }

  //监视
  // watch(person, (newValue, oldValue) => { //直接这样写,只会监视person这个对象的变化,对于其内部的变化不会触发
  //   console.log('person从: ', oldValue, "变为: ", newValue);
  // });

  //深度监视
  watch(person, (newValue, oldValue) => { //需要传递第三个参数 {deep:true}
    console.log('person从: ', oldValue, "变为: ", newValue);
  }, {deep: true}); //### 还可以添加参数 {immediate:?}  这样初始化的时候也会监视一下

</script>

<style>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px; /* 盒子阴影 */
  border-radius: 10px;
  padding: 20px;
}

button {
  margin: 0 5px;
}
</style>

情况三 监视reactive定义的【对象类型】数据

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

<template>
  <div class="person">
    <h2>监视reactive定义的【对象类型】数据,且默认开启了深度监视。</h2>
    <h2>姓名: {{person.name}}</h2>
    <h2>年龄: {{person.age}}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改人</button>
  </div>
</template>

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

  //数据
  let person = reactive({
    name: '张三',
    age: 18
  })
  
  //方法
  function changeName() {
    person.name += "~";
  }

  function changeAge() {
    person.age += 1;
  }

  function changePerson() {
    // person = {name: '李四', age: 90};  //这里由于使用了reactive所以不能直接修改对象

    //注意:这里这个引用没有发生变化哦
    Object.assign(person, {name: '李四', age: 90}); //需要使用这种方式,响应式才不会被破坏
  }

  //监视 因为person是reactive定义的 默认深度监视,无法关闭
  watch(person, (newValue, oldValue) => { //因为person是reactive定义的,直接这样写,默认就开启了deep监视
    console.log('person从: ', oldValue, "变为: ", newValue);
  });

</script>

<style>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px; /* 盒子阴影 */
  border-radius: 10px;
  padding: 20px;
}

button {
  margin: 0 5px;
}
</style>

情况四 监视refreactive定义的【对象类型】数据中的某个属性

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

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

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

<template>
  <div class="person">
    <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="changeOneCar">修改第一台车</button>
    <button @click="changeTwoCar">修改第二台车</button>
    <button @click="changeCar">修改整个车</button>    
  </div>
</template>

<script setup lang="ts" name="Person">
  import {reactive, watch} from 'vue'
  
  //数据
  let person = reactive({
    name: '张三',
    age: 20,
    car: {
      c1: '小米',
      c2: '奔驰'
    }
  })

  //方法
  function changeName() {
    person.name += '~';
  }

  function changeAge() {
    person.age += 1;
  }
  
  function changeOneCar() {
    person.car.c1 += '~';
  }

  function changeTwoCar() {
    person.car.c2 += '~';
  }

  function changeCar() {
    Object.assign(person, {
      name: '李四',
      age: 30,
      car: {
        c1: '大众',
        c2: '马自达'
      }
    })
  }

  //监听, 为了监视响应式对象中的某个对象,且该属性是:基本数据类型,要写为函数式
  watch(() => person.name, (newValue, oldValue) => {
    console.log('person.name变化了', newValue, oldValue);
  })


  //##### 监听对象中的对象 ######
  // watch(person.car, (newValue, oldValue) => {   //可以发现监视响应式对象中的对象属性ok的,但是修改整个外层对象时,又无法监听到
  //   console.log('person.car变化了', newValue, oldValue);
  // })

  // watch(() => person.car, (newValue, oldValue) => { //而使用函数式后 car整体变化ok了,但是细节变化又不行了,因为监听变化的是car变量的引用了
  //   console.log('person.car变化了', newValue, oldValue);
  // })

  //##### 所以得出如果想要 监听对象中的对象 细枝末节变和整体变都可以监听到的最佳实践 ######
  watch(() => person.car, (newValue, oldValue) => {
    console.log('person.car变化了 或者 car中的属性变化了', newValue, oldValue);
  }, {deep: true})

  // watch(() => person.car.c1, (newValue, oldValue) => {
  //   console.log('person.car.c1变化了', newValue, oldValue);
  // })

</script>

<style>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px; /* 盒子阴影 */
  border-radius: 10px;
  padding: 20px;
}

button {
  margin: 0 5px;
}
</style>
监听对象中的对象最佳实践:
  //##### 监听对象中的对象 ######
  // watch(person.car, (newValue, oldValue) => {   //可以发现监视响应式对象中的对象属性ok的,但是修改整个外层对象时,又无法监听到
  //   console.log('person.car变化了', newValue, oldValue);
  // })

  // watch(() => person.car, (newValue, oldValue) => { //而使用函数式后 car整体变化ok了,但是细节变化又不行了,因为监听变化的是car变量的引用了
  //   console.log('person.car变化了', newValue, oldValue);
  // })

  //##### 所以得出如果想要 监听对象中的对象 细枝末节变和整体变都可以监听到的最佳实践 ######
  watch(() => person.car, (newValue, oldValue) => {
    console.log('person.car变化了 或者 car中的属性变化了', newValue, oldValue);
  }, {deep: true})

情况五 监视上诉的多个数据

​ 监视上述的多个数据,即我们的watch使用时第一个参数可以传递一个数组,只要其中的一个发生变化都会执行回调函数。这里对应的写法都推荐函数式。说明:基本类型也可以使用函数式写法如:() => name.value

<template>
  <div class="person">
    <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="changeOneCar">修改第一台车</button>
    <button @click="changeTwoCar">修改第二台车</button>
    <button @click="changeCar">修改整个车</button>    
  </div>
</template>

<script setup lang="ts" name="Person">
  import {reactive, ref, watch} from 'vue'
  
  //数据
  let name = ref(0);
  let person = reactive({
    name: '张三',
    age: 20,
    car: {
      c1: '小米',
      c2: '奔驰'
    }
  });

  //方法
  function changeName() {
    person.name += '~';
  }

  function changeAge() {
    person.age += 1;
  }
  
  function changeOneCar() {
    person.car.c1 += '~';
  }

  function changeTwoCar() {
    person.car.c2 += '~';
  }

  function changeCar() {
    Object.assign(person, {
      name: '李四',
      age: 30,
      car: {
        c1: '大众',
        c2: '马自达'
      }
    })
  }

  //监听
  watch([() => person.name, () => person.car.c1], (newValue, oldValue) => {
    console.log('person.name变化了 或者 person.car.c1', newValue, oldValue);
  }, {deep: true})

</script>

<style>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px; /* 盒子阴影 */
  border-radius: 10px;
  padding: 20px;
}

button {
  margin: 0 5px;
}
</style>

标签:car,watch,监听,person,oldValue,监视,newValue
From: https://www.cnblogs.com/fragmentary/p/18626669

相关文章

  • 数据监听器
    数据监听器数据监听器可以用于监听和响应任何属性和数据字段的变化。从小程序基础库版本2.6.1开始支持。使用数据监听器有时,在一些数据字段被setData设置时,需要执行一些操作。例如,this.data.sum永远是this.data.numberA与this.data.numberB的和。此时,可以使用数据监......
  • ✨ 自动化更新 Docker 应用:Watchtower 魔法
    ✨自动化更新Docker应用:Watchtower魔法......
  • Vue3——计算属性和监听
    一、computed作用:根据已有的数据计算出新数据,具有缓存性(如果依赖的计算数据不更新就只执行一次,更新再执行)只读写法:letfullName=computed(()=>{return计算结果;})可读可写:letfullName=computed({get(){return计算结果;},set(newVal){//......
  • 《深入剖析Redisson源码》揭秘Redisson分布式锁原理(可重入锁机制、PubSub可重试机制、
    Hiヽ(゜▽゜)-欢迎来到蓝染Aizen的CSDN博客~......
  • 在C#中,使用 Stopwatch 比较简单粗糙的替代 WIN32 下 C++ 中调用的 QueryPerformanceCo
    C#中自带的那个CTimer看上去是通过消息事件方式的,精度上好像小于10ms就不行了。于是找了半天网络,有的方式是引用kernel32.dll的库,然后就可以在C#中调用 QueryPerformanceCounter。感觉是不那么优雅。最后居然发现这个Stopwatch。真的像一个计时器一样,按一下,开始【Sto......
  • vue-监听滚动函数
    import{onDeactivated,onMounted,onUnmounted,ref}from'vue';import{throttle}from'underscore'//监听滚动位置执行回调函数//console.log(throttle)//exportdefaultfunctionuseScroll(reachBottomCB){//constscrollListenerHandler=()......
  • Go 监听8080端口
    创建一个文件夹,命名为 HttpServer2,打开这个文件夹打开终端,点击左下角叉和感叹号在弹出的窗口中点击TERMINAL进入终端(也可以使用快捷键CTRL+` 直接打开) 初始化Go的ModulegomodinitHttpServer2点击文件创建图标创建文件创建一个名为main.go的文件,按下回......
  • harmony_flutter_orientation_plugins(监听屏幕状态插件)
    harmony_flutter_orientation(屏幕旋转)flutter端监听鸿蒙手机得屏幕横竖屏切换等各种状态一.MethodChannel1.flutter端代码创建MethodChannel交互通道接收ohos端传递过来状态classOrientationPlugin{staticconst_methodChannel=constMethodChannel('sos......
  • harmony_flutter_keyboard_visibility(监听动态键盘)
    harmony_flutter_keyboard_visibility(监听动态键盘)一.MethodChannel1.flutter端代码创建StreamBuilder监听event接收ohos端传递过来的状态值finalKeyboardVisibilityController?controller;KeyboardVisibilityControllerget_controller=>controller?......
  • react hook如何监听数据的变化,useEffect
    在React中,如果你需要监听某个状态或属性的变化,可以使用useEffectHook。useEffect可以让你在函数组件中执行副作用操作,例如数据获取、订阅或手动更改React组件中的DOM。基本用法importReact,{useState,useEffect}from'react';constExampleComponent=()=>{......