《Vue3学习手记2》

发布于:2025-04-16 ⋅ 阅读:(39) ⋅ 点赞:(0)

今天主要学习Vue3中的数据监视:
ps: 代码中的注释写的很详细,这样更有利于理解

watch

作用: 监视数据的变化(和Vue2中watch作用一致)
特点: Vue3中的watch只能监视以下四种数据:

  1. ref创建定义的数据(基本类型、对象类型)
  2. reactive定义的数据(对象类型)
  3. 函数返回一个值(getter函数)
  4. 一个包含上述内容的数组

语法: watch接收三个参数:第一个参数是监视的对象;第二个参数是执行的回调函数(回调函数会收到两个值:新值和旧值);第三个参数是是否进行深度监视或者是否打开页面就监视

下面分情况概述:

情况一:监听ref定义的基本数据及对象数据

<template>
  <div class="app">
    <!-- <h2>姓名:{{name}}</h2>
    <h2>年龄:{{age}}</h2>
    <button @click="changeName">点击修改姓名</button>
    <button @click="changeAge">点击修改年龄</button> -->
    <!-- ========================================================= -->
    <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">
      // 知识点一:watch监视
          // 首先 引入watch
          // watch监视的是ref定义的基本响应式数据
      import {ref,watch} from "vue"
      // 数据
            // const name=ref("张三")
            // const age=ref(18)
            // // 方法
            // function changeName(){
            //   name.value+="~"
            // }
            // function changeAge(){
            //   age.value++
            // }
      // watch在vue2是配置项,在vue3中是函数。
            // 对name进行监视
            // watch(name,(newValue,oldValue)=>{
            //   console.log("name改变了",newValue,oldValue)
            // })
    // =========================================================
    // 知识点二:watch监视的是ref定义的对象数据
    const person=ref({
      name:"张三",
      age:18
    })
    function changeName(){
        person.value.name+="~"
      }
    function changeAge(){
      person.value.age++
    }
    function changeperson(){
      person.value={name:"李四",age:19}
    }
    // 对person进行监视,此时只能监视到整个person的变化,而不能检测到person里属性的变化
        // watch(person,(newValue,oldValue)=>{
        //   console.log("person改变了",newValue,oldValue)
        // })
    // 添加第三个参数,可以检测到person中属性name和age的变化
    watch(person,(newValue,oldValue)=>{
       console.log("person改变了",newValue,oldValue)
      },{deep:true,immediate:true})

// =========================================================
    // 注意:
    // 进行深度监视后,name和age属性可以被监视到。
    // 监测name和age返回的新值和旧值都是新值,因为他们是同一对象
    // 监测整个person对象返回的分别是新值和旧值,因为他们不是同一对象,因为整个person都被修改了
  
        
    
</script>

<style>
  .app {
    background-color: #ddd;
    box-shadow: 0 0 10px;
    border-radius:10px;
    padding: 20px;
  }
</style>

情况二: 监视reactive定义的对象数据

<template>
  <div class="app">
    <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">
      // 知识点一:watch监视
          // 首先 引入watch
          // watch监视的是reactive定义的对象响应式数据
      import {reactive,watch} from "vue"
        const person=reactive({
          name:"张三",
          age:18
        })
        function changeName(){
            person.name+="~"
          }
        function changeAge(){
            person.age++
        }
        function changeperson(){
          Object.assign(person,{name:"李四",age:20})
        }
        // 对person进行监视,此时只能监视到整个person的变化,也能能检测到person里属性的变化(reactive对象数据,默认开启深度监视
            watch(person,(newValue,oldValue)=>{
              console.log("person改变了",newValue,oldValue)
            })

// =========================================================
    // 注意:
    // 监测name和age返回的新值和旧值(newValue和oldValue)都是新值,因为他们是同一对象
    // 监测整个person对象返回的newValue和oldValue分别是新值和旧值,因为他们不是同一对象
// =========================================================   
      //总结:  
     //reactive定义的对象数据和ref相同,都是对象中的属性 返回的新值和旧值都是新值,而整个person对象返回的newValue和oldValue分别是新值和旧值
  
        
    
</script>

<style>
  .app {
    background-color: #ddd;
    box-shadow: 0 0 10px;
    border-radius:10px;
    padding: 20px;
  }
</style>

情况三:(函数返回一个值)监视一个getter函数

常用于监视某个属性

<template>
  <div class="app">
    <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">点击修改C1</button>
    <button @click="changeC2">点击修改C2</button>
    <button @click="changecar">点击修改汽车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
      // 知识点一:watch监视
          // 首先 引入watch
          // watch监视:函数返回一个值(getter函数)
      import {reactive,watch} from "vue"
        const person=reactive({
          name:"张三",
          age:18,
          car:{
            C1:"柯尼塞格",
            C2:"布加迪威龙"
          }
        })
        function changeName(){
            person.name+="~"
          }
        function changeAge(){
            person.age++
        }
        function changeC1(){
          person.car.C1="奥迪"
        }
        function changeC2(){
          person.car.C2="大众"
        }
        function changecar(){
          person.car={C1:"特斯拉",C2:"小米"}   //这里注意,由于car也是一个对象,所以不用用Object assign来定义
        }
  // =========================================================
  // 要求一:只对name属性进行监视   此时需要写成getter函数(watch可以检测到getter函数),判断该属性是不是对象类型,不是对象类型,应写成函数式
        // watch(()=>{return person.name},(newValue,oldValue)=>{
        // 可简写为:
        watch(()=>person.name,(newValue,oldValue)=>{
          console.log("name改变了",newValue,oldValue)
        })
  //要求二:只对car属性进行监视   判断该属性是不是对象类型,是对象类型,应写成函数式(推荐),也可以直接写
        watch(()=>person.car,(newValue,oldValue)=>{
          console.log("car改变了",newValue,oldValue)
        },{deep:true})
  // =========================================================
  // 总结:监视的是对象里的属性(注意:首先要满足是对象,不管是对象里的基本数据还是对象数据类型),最好都写成函数式,注意点:若是也需要监视对象内部,则需手动开启深度监视。
  
</script>

<style>
  .app {
    background-color: #ddd;
    box-shadow: 0 0 10px;
    border-radius:10px;
    padding: 20px;
  }
</style>

情况四:监视多个数据(包含上述内容的数组)

<template>
  <div class="app">
    <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">点击修改C1</button>
    <button @click="changeC2">点击修改C2</button>
    <button @click="changecar">点击修改汽车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
      // 知识点一:watch监视
          // 首先 引入watch
          // watch监视:监视上述内容的数组(多个数据)
      import {reactive,watch} from "vue"
        const person=reactive({
          name:"张三",
          age:18,
          car:{
            C1:"柯尼塞格",
            C2:"布加迪威龙"
          }
        })
        function changeName(){
            person.name+="~"
          }
        function changeAge(){
            person.age++
        }
        function changeC1(){
          person.car.C1="奥迪"
        }
        function changeC2(){
          person.car.C2="大众"
        }
        function changecar(){
          person.car={C1:"特斯拉",C2:"小米"}   //这里注意,由于car也是一个对象,所以不用用Object assign来定义
        }
  // =========================================================
  // 对name属性和car对象里面的C1属性进行监视   
        watch([()=>person.name,()=>person.car.C1],(newValue,oldValue)=>{
          console.log("name和car被修改了",newValue,oldValue)
        },{deep:true})
  // 此时newValue返回的是name和car.C1返回的新值组成的数组
</script>

<style>
  .app {
    background-color: #ddd;
    box-shadow: 0 0 10px;
    border-radius:10px;
    padding: 20px;
  }
</style>

watchEffect

watch对比watchEffect
1.都能监听响应式数据的变化,不同的是监听数据变化的方式不同
2. watch:要明确指出监视的数据,当需要监视的数据过多时,操作麻烦
3.watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性),它会自己分析。

<template>
  <div class="app">
  <h2>水温:{{temp}}</h2>
  <h2>水位:{{height}}</h2>
  <button @click="changeTemp">点击水温+10</button>
  <button @click="changeHeight">点击水位+10</button>
  </div>
</template>

<script lang="ts" setup name="Person">
      // 知识点:watchEffect监视
          // 首先 引入watchEffect
      import {ref,watch,watchEffect} from "vue"
        const temp=ref(0)
        const height=ref(10)
        function changeTemp(){
          temp.value+=10
        }
        function changeHeight(){
          height.value+=10
        }
// 要求:当水温大于60或水位大于80,向服务器发送请求
// 对水温和水位进行监视  (不是对象里的属性,可直接写)
  // =========================================================
  // 第一种写法:
      // watch([temp,height],()=>{   //value表示newValue,返回的是newTemp和newHeight组成的数组
      //   // 解构
      //   // const [newTemp,newHeight]=value
      //   // 进行判断
      //   if(temp.value>60 || height.value>80){
      //     console.log("向服务器发送请求")
      //   }
      // })
  // 第二种写法:
    // watch([temp,height],(value)=>{   //value表示newValue,返回的是temp和height的新值组成的数组
    //   // 进行判断
    //   if(value[0]>60 || value[1]>80){
    //     console.log("向服务器发送请求")
    //   }
    // })
  
    // 第三种写法:
      // watch([temp,height],(value)=>{   //value表示newValue,返回的是newTemp和newHeight组成的数组
      //   // 解构
      //   const [newTemp,newHeight]=value
      //   // 进行判断
      //   if(newTemp>60 || newHeight>80){
      //     console.log("向服务器发送请求")
      //   }
      // })
      

    // =========================================================
    // 使用watchEffect写:(直接使用,watchEffect会自己分析),适用于监视的对象足够多的情况
    watchEffect(()=>{
      if(temp.value>60 || height.value>80){
          console.log("向服务器发送请求")
        }
    })
</script>

<style>
  .app {
    background-color: #ddd;
    box-shadow: 0 0 10px;
    border-radius:10px;
    padding: 20px;
  }
</style>

网站公告

今日签到

点亮在社区的每一天
去签到