Vue3-4 Watch

Watch监视

  • 作用:监视数据变化
  • 特点:只能监视以下四种数据
    • ref定义的数据
    • reactive定义的数据
    • 函数返回一个值
    • 一个包含上述内容的数组

情况一:

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

<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>

情况二:

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

注意:

  • 若修改的是ref定义的对象中的属性,newValue和oldValue都是新值,因为他们是同一个对象
  • 若修改的是整个ref定义的对象,newValue是新值,oldValue是旧值,因为不是同一个对象了
<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:2
  })
 //方法
    function changeName() {
        person.value.name += '~'
    }
    function changeAge() {
        person.value.age += 1
    }
    function changePerson() {
        person.value = {name:'大狗',age:5} 
    }
//监视 情况二:监视【ref】定义的【对象类型】数据,监视的是对象的地址值
//watch的第一个参数是:被监视的数据
//watch的第二个参数是:监视的回调
//watch的第三个参数是:配置对象(deep、immediate)
    watch(person, (newValue,oldValue) => {
        console.log('person变化了',newValue,oldValue);
    },{deep:true,immediate:true})

情况三:

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

//reactive更改整个对象的 person地址没有发生变化
function changePerson() {
        Object.assign(person,{name:'大狗',age:5}) 
}
//监视 情况三:监视【reactive】定义的【对象类型】数据,且默认开启深度监视
watch(person, (newValue,oldValue) => {
    console.log('person变化了',newValue,oldValue);
 })

情况四

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

<template>
    <div class="person">
        <h1>情况四:监视【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="changeFirstCar">修改第一台车</button>
        <button @click="changeSecondCar">修改第二台车</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 changeFirstCar() {
        person.car.c1 = '奥迪'
    }
    function changeSecondCar() {
        person.car.c2 = '大众'
    }
    function changeCar() {
        person.car = {c1:'雅迪',c2:'艾玛'}
    }
//监视,情况四:监视响应式对象中某个属性,且该属性是基本类型,要写成函数式
    watch(()=>{return person.name}, (newValue, oldValue) => {
        console.log('person.name变化了',newValue,oldValue);
    })
//监视,情况四:监视响应式对象中某个属性,且该属性是对象类型,可以直接写,也能写函数
    watch(()=>person.car, (newValue, oldValue) => {
        console.log('person.car变化了',newValue,oldValue);
    },{deep:true})
</script>
  1. 若该属性值不是【对象类型】,需要写成函数
//不能直接写person.name 这样是监视不到的,不属于上述四种类型之一 写成getter函数,箭头函数
watch(()=>{return person.name}, (newValue, oldValue) => {
        console.log('person.name变化了',newValue,oldValue);
    })
  1. 若该属性值依然是【对象类型】,可直接编,也可以写成函数,
//修改第一台、第二台可以变,修改整个车没法改变
watch(person.car, (newValue, oldValue) => {
        console.log('person.car变化了',newValue,oldValue);
    })
//整个车修改可以看到改变,细枝末节改变没法监视到
watch(()=>person.car, (newValue, oldValue) => {
        console.log('person.car变化了',newValue,oldValue);
    })
//监视,情况四:监视响应式对象中某个属性,且该属性是对象类型,可以直接写,也能写函数
    watch(()=>person.car, (newValue, oldValue) => {
        console.log('person.car变化了',newValue,oldValue);
    },{deep:true})

情况五

写成数组形式

//监视,情况五:监视多个数据
    watch([()=>person.name,person.car], (newValue, oldValue) => {
        console.log('person.name变化了',newValue,oldValue);
    },{deep:true})

WatchEffect

<template>
    <div class="person">
        <h2>需求:当天气是晴天,或温度超过25,向服务器发送请求</h2>
       <h2>当前天气为:{{wea}}</h2>
       <h2>当前温度为:{{ deg }}</h2>
       <button @click="changeWea">点我wea改变</button>
       <button @click="changeDeg">点我deg改变</button>
    </div>
</template>


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

//数据
let wea = ref('晴天')
let deg = ref(22)

//方法
function changeWea() {
    wea.value = '阴天'
}
function changeDeg() {
    deg.value -= 1
}

//监视,watch写
// watch([wea, deg], (value) => {
//     //获取新的天气和温度
//     let [newWea, newDeg] = value;
//     console.log(newWea, newDeg);
//     if (newWea == '晴天' || newDeg <= 18) {
//         console.log('给服务器发送请求');
//     }
// })

//监视,watchEffect实现
watchEffect(() => {
    if (wea.value == '晴天' || deg.value <= 18) {
        console.log('给服务器发送请求');
    }
})
</script>

标签的ref属性

作用:用于注册模板引用

  • 可以用在普通DOM标签上,获得的是DOM节点

    <template>
        <div class="person">
            <h1>中国</h1>
            <h2  ref="title2">北京</h2>
            <h3>尚硅谷</h3>
            <button @click="showLog">点我输出h2</button>
        </div>
    </template>
    
    
    <script lang="ts" setup name="Person">
    import { ref,defineExpose } from 'vue'
    function showLog() {
            console.log(title2.value);
            
        }
    
        //告诉根组件可以查看哪些内容,包括上面引入defineExpose
        defineExpose({a,b,c})
    </script>
    
    <style scoped>
    .person {
        background-color: skyblue;
        box-shadow: 0 0 10px;
        border-radius: 10px;
        padding: 20px;
    }
    
    button {
        margin: 0 5px;
    }
    
    input{
        margin-bottom: 10px;
    }
    </style>
    
  • 用在组件标签APP.vue上,获取的是组件实例对象

    <template>
        <!-- html -->
        <h2 ref="title2">你好</h2>
        <button @click="showLog">测试</button>
        <Person ref="ren"/>
    </template>
    
    <script lang="ts" setup name="APP">
    import Person from './components/Person.vue'; //引入Person.vue
    import { ref } from 'vue'
    
    let title2 = ref()
    let ren = ref()
    
    function showLog() {
        console.log(ren.value);
    }
    </script>
    

TS中接口、泛型、自定义类型

接口

export interface PersonInter {
    //定义一个接口,用于限制person对象具体属性
    id: string,
    name: string,
    age: number
}

引入规范,不是一个具体值,必须加上type

<script lang="ts" setup name="Person">
import {type PersonInter} from '@/types'

let person:PersonInter = { id: '12344', name: '小黑', age: 2 }
    
</script>

泛型

如果要定义一个数组,可以先写需要她是一个数组,数组里面必须满足规范。不能直接写personLIst:PersonInter

let personList:Array<PersonInter> = [
    { id: '12344', name: '小黑', age: 2 },
    { id: '12345', name: '小黑2', age: 3 },
    { id: '12346', name: '小黑3', age: 4 }
]

另一种写法,更简洁

//一个自定义类型
// export type Persons = Array<PersonInter>

//另一种写法
export type Persons = PersonInter[]
import {type PersonInter,type Persons} from '@/types'

let personList:Persons = [
    { id: '12344', name: '小黑', age: 2 },
    { id: '12345', name: '小黑2', age: 3 },
    { id: '12346', name: '小黑3', age: 4 }
]
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值