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>
- 若该属性值不是【对象类型】,需要写成函数
//不能直接写person.name 这样是监视不到的,不属于上述四种类型之一 写成getter函数,箭头函数
watch(()=>{return person.name}, (newValue, oldValue) => {
console.log('person.name变化了',newValue,oldValue);
})
- 若该属性值依然是【对象类型】,可直接编,也可以写成函数,
//修改第一台、第二台可以变,修改整个车没法改变
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 }
]