Vue学习计划-Vue3--核心语法(三)computed计算属性、watch监听、watchEffect函数

发布时间:2024年01月04日
1. computed计算属性

作用:根据已有数据计算出新数据(和Vue2中的computed作用一致)。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

  1. 情况一

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

<template>
  <div>
    <h1>情况一:监视【ref】定义的【基本类型】数据</h1>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
    <button @click="changeName">修改姓名</button>
    <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script lang="ts" setup name="Person234">
import {ref, watch} from 'vue'
let name = ref('张三')
let age = ref(0)

function changeName(){
  name.value += '~'
}

function changeAge(){
  age.value += 1
}

watch(name, (nv, oldv)=>{
  console.log('名字变了', nv, oldv)
})
// 监视,情况一:监视【ref】定义的【基本类型】数据
// 返回一个函数,当年龄等于5以后,停止监视,即调用返回函数即可
const stopWatch = watch(age, (nv, oldv)=>{
  console.log('年龄变了', nv, oldv)
  if(nv === 5){
    stopWatch()
  }
})

// 监视两个数据
// watch([name, age], (nv, oldv)=>{
//   console.log('数据变了', nv, oldv)
// })

</script>
  1. 情况二

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

注意:

  • 若修改的是ref定义的对象中的属性,newValue和oldValue都是新值,因为它们是同一个对象
  • 若修改整个ref定义的对象,newValue是新值,oldValue是旧值,因为不是同一个对象了
<template>
  <div>
    <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="Person234">
import {ref, watch} from 'vue'
let person = ref({
  name: '张三',
  age: 19
})

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, (nv, oldv)=>{
  console.log('名字变了', nv, oldv)
}, {deep:true, immediate: true})

</script>
  1. 情况三

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

<template>
  <div>
    <h1>情况三:监视【reactive】定义的【对象类型】数据</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="Person234">
import {reactive, watch} from 'vue'
let person = reactive({
  name: '张三',
  age: 19
})

function changeName(){
  person.name += '~'
}

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

function changePerson(){
  person = Object.assign(person, { name: '李四', age: 90})
}


  // 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
watch(person, (nv, oldv)=>{
  console.log('名字变了', nv, oldv)
})

</script>
  1. 情况四

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

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

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

<template>
  <div>
    <h1>情况三:监视【reactive】定义的【对象类型】数据</h1>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <h2>第一量车:{{ person.car.c1 }}</h2>
    <h2>第二量车:{{ person.car.c2 }}</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="Person234">
import {reactive, watch} from 'vue'
let person = reactive({
  name: '张三',
  age: 19,
  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, (nv, oldv)=>{
  console.log('名字变了', nv, oldv)
})

// 监视,情况四:若该属性值是【对象类型】,可以直接编写
// 因为reactive定义的响应式对象person,所以car也是响应式对象,那么监视person.car就相当于reactive定义的一个car,默认开启深度监视,当修改c1和c2的时候,会监视到,但是当修改整个car,就相当于car的指针换了地址,原对象不变,所以changeCar不会触发监视,所以建议写成函数
// watch(person.car, (nv, oldv)=>{
//   console.log('车变了', nv, oldv)
// })

// 监视,情况四:若该属性值是【对象类型】,建议写成函数 
// 函数返回值是car的空间地址,对空间地址进行监视,则修改car的指针,会触发,但是内部属性变化,不会触发, 需要手动开启深度监听
watch(()=>person.car, (nv, oldv)=>{
  console.log('车变了', nv, oldv)
},{ deep: true})
</script>
  1. 情况五

监视上述的多个数据

// watch([()=>person.name, ()=>person.car], (nv)=>{
//   console.log('车变了', nv)
// },{ deep: true})
// 或者
watch([()=>person.name, person.car], (nv)=>{
  console.log('车变了', nv)
},{ deep: true})
2. watchEffect
  • 官网:立即运行一个函数,同时响应式的追踪其依赖,并在依赖更改时重新执行该函数
  • watch对比watchEffect
  1. 都能监听响应式数据的变化,不同的是监听数据变化的方式不同
  2. watch:要明确指出监视的数据
  3. watchEffect: 不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)
  • 示例代码:
<template>
  <div>
    <h1>当温度高于60或者高度高于20,调取接口</h1>
    <h2>温度:{{ temp }}</h2>
    <h2>高度:{{ height }}</h2>
    <button @click="changeTemp">修改温度</button>
    <button @click="changeHeight">修改高度</button>
  </div>
</template>
<script lang="ts" setup name="Person234">
import {ref, watch, watchEffect} from 'vue'
let temp = ref(0)
let height = ref(0)
function changeTemp(){
  temp.value += 10
}
function changeHeight(){
  height.value += 10
}
// 使用watch,需要指定监视谁
// watch([temp, height], (nv)=>{
//   const [temp, height] = nv
//   if(temp >= 60 || height>=80){
//     console.log('调取接口')
//   }
// })

 // 用watchEffect实现,不用
const stopWatch = watchEffect(()=>{
  if(temp.value >= 60 || height.value >= 20){
    console.log('调取接口', temp.value, height.value )
  }
  if(temp.value === 100 || height.value === 50){
    console.log('停止监视', temp.value, height.value )
    stopWatch()
  }

})

</script>
文章来源:https://blog.csdn.net/qq_35940731/article/details/135375388
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。