尚矽谷影片連結
watch監視的5種情況
情況1 監視【ref】定義的【基本型別】資料
<template>
<div class="person">
<h1>情況1:監視【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
}
// 增加監視
// watch(sum,(newVal,oldVal)=>{
// console.log('sum changed',newVal,oldVal);
// })
// 停止監視
const stopWatch = watch(sum,(newVal,oldVal)=>{
console.log('sum changed',newVal,oldVal);
if(newVal >= 10) {
stopWatch()
}
return 0
})
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button {
margin : 0 5px;
}
li {
font-size : 20px;
}
</style>
情況2:監視【ref】定義的【物件型別】資料
<template>
<div class="person">
<h1>情況2:監視【ref】定義的【物件型別】資料</h1>
<h2>姓名:{{person.name}}</h2>
<h2>年齡:{{person.age}}</h2>
<button @click="changeName">changeName</button>
<button @click="changeAge">changeAge</button>
<button @click="changePerson">changePerson</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {ref,watch} from 'vue'
let person = ref({
name:'zhangsan',
age:20
})
function changeName(){
person.value.name = 'lisi'
}
function changeAge(){
person.value.age++
}
function changePerson(){
person.value = {name:'lalala',age:30}
}
// 僅監視物件的地址值,當整個物件發生變化時,監視生效
// watch(person,(newVal,oldVal)=>{
// console.log(newVal,oldVal);
// })
// 監視物件內部值的變化(開啟深度監視deep 問題:此時由於物件沒有變化,因此取到的新、舊值均為新值
watch(person,(newVal,oldVal)=>{
console.log(newVal,oldVal);
},{deep:true})
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button {
margin : 0 5px;
}
li {
font-size : 20px;
}
</style>
情況3:監視【reactive】定義的【物件型別】資料
- 預設開啟深度監視,無法關閉
<template>
<div class="person">
<h1>情況3:監視【reactive】定義的【物件型別】資料</h1>
<h2>姓名:{{person.name}}</h2>
<h2>年齡:{{person.age}}</h2>
<button @click="changeName">changeName</button>
<button @click="changeAge">changeAge</button>
<button @click="changePerson">changePerson</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {reactive,watch} from 'vue'
let person = reactive({
name:'zhangsan',
age:20
})
function changeName(){
person.name = 'lisi'
}
function changeAge(){
person.age++
}
function changePerson(){
// person = {name:'lalala',age:30}
// 僅修改物件內的值,物件地址不變
Object.assign(person,{name:'lalala',age:30})
}
// 僅監視物件的地址值,當整個物件發生變化時,監視生效
// watch(person,(newVal,oldVal)=>{
// console.log(newVal,oldVal);
// })
// 預設開啟深度監視
watch(person,(newVal,oldVal)=>{
console.log(newVal,oldVal)
})
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button {
margin : 0 5px;
}
li {
font-size : 20px;
}
</style>
情況4:監視【reactive/ref】定義的【物件型別】資料中的某個屬性
推薦使用:函式+深度
<template>
<div class="person">
<h1>情況4:監視【reactive/ref】定義的【物件型別】資料中的某個屬性</h1>
<h2>姓名:{{person.name}}</h2>
<h2>年齡:{{person.age}}</h2>
<h2>車:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
<button @click="changeName">changeName</button>
<button @click="changeAge">changeAge</button>
<button @click="changeC1">changeC1</button>
<button @click="changeC2">changeC2</button>
<button @click="changeCar">changeCar</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {reactive,watch} from 'vue'
let person = reactive({
name:'zhangsan',
age:20,
car:{
c1:'第一',
c2:'第二'
}
})
function changeName(){
person.name += '!'
}
function changeAge(){
person.age++
}
function changeC1(){
person.car.c1 = '333'
}
function changeC2(){
person.car.c2 = '444'
}
function changeCar(){
person.car = {
c1:'555',
c2:'666'
}
}
// 要監視的值不是物件,需要寫成函式
watch(()=>person.name,(newVal,oldVal)=>{
console.log('person.name changed',newVal,oldVal);
})
// 要監視是值仍然是物件,可以直接寫,但建議寫成函式
// 直接寫時,如果改變整個物件,則無法監視到
watch(person.car,(newVal,oldVal)=>{
console.log('person.car changed',newVal,oldVal)
},{deep:true})
// 寫成函式+深度,可以監視到所有變化
watch(()=>person.car,(newVal,oldVal)=>{
console.log('person.car changed',newVal,oldVal)
},{deep:true})
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button {
margin : 0 5px;
}
li {
font-size : 20px;
}
</style>
情況5:監視上述的多個資料
使用陣列
watch([()=>person.car.c1,()=>person.name],(newVal,oldVal)=>{
console.log('person.car changed',newVal,oldVal)
},{deep:true})
watchEffect
// 使用watch,需要監視這兩個資料(如果有10個資料,要監視10個
// watch([temp,height],()=>{
// if(temp.value > 50 || height.value > 70){
// console.log('hhhhhhhhhhhh')
// }
// })
// 使用watchEffect,自動監視所有變化的資料
watchEffect(()=>{
if(temp.value > 50 || height.value > 70){
console.log('hhhhhhhhhhhh')
}
})