watch函數用來偵聽某個值的變化,當該值改變後,觸發對應的處理邏輯。
<template> <div> <div>{{ count }}</div> <button @click="changCount">更改count的值</button> </div> </template> <script setup> import {ref,reactive, watch} from 'vue' const count = ref(0) function changCount(){ count.value++ } watch(count,(newValue,oldValue)=>{ if(newValue){ console.log(`我侦听到了count状态的变化,当前值为${newValue},从而处理相关逻辑`); } }) </script> <style> </style>
<template> <div> <div>{{ x }}</div> <button @click="changCount">更改count的值</button> </div> </template> <script setup> import { ref, reactive, watch } from "vue"; const x = ref(1); const y = ref(5); function changCount() { x.value++; } watch( () => x.value + y.value, (sum) => { console.log(`我是x与y之和${sum}`); } ); </script> <style> </style>
<template> <div> <div>{{ x }}</div> <button @click="changCount">更改count的值</button> </div> </template> <script setup> import { ref, reactive, watch } from "vue"; const x = ref(1); const y = ref(5); function changCount() { x.value++; } watch( [x,y], ([x,y]) => { console.log(`我是x=>${x},我是y=》${y}`); } ); </script> <style> </style>
<template> <div> <div>{{ obj.name }}</div> <button @click="changObj">更改count的值</button> </div> </template> <script setup> import { ref, reactive, watch } from "vue"; const obj = ref({name:'你好'}) function changObj(){ obj.value.name+='我不好' } watch(()=>obj.value.name,(name)=>{ console.log(name); }) </script> <style> </style>
用來開啟深度監聽
#<template> <div> <div>{{ obj.name }}</div> <button @click="changObj">更改count的值</button> </div> </template> <script setup> import { ref, reactive, watch, watchEffect } from "vue"; const obj = ref({name:'你好'}) function changObj(){ obj.value.name+='我不好' } // obj是一个RefImpl对象,当不开启深度监听的时候,监听obj无法检测到obj属性的变化 watch(obj,()=>{ console.log(obj.value.name); }, { deep: true }) </script> <style> </style>
是否開啟初始化偵測,預設是值發生變化時,才會執行監聽器裡面的方法,開啟immediate後初始化就執行一次。
<template> <div> <div>{{ obj.name }}</div> <button @click="changObj">更改count的值</button> </div> </template> <script setup> import { ref, reactive, watch, watchEffect } from "vue"; const obj = ref({name:'你好'}) function changObj(){ obj.value.name+='我不好' } // obj是一个RefImpl对象,当不开启深度监听的时候,监听obj无法检测到obj属性的变化 watch(obj,()=>{ console.log(obj.value.name); }, { deep: true,immediate:true }) </script> <style> </style>
偵聽器的回呼使用與來源完全相同的響應式狀態是很常見的。例如:
<template> <div> <div>{{ obj.name }}</div> <button @click="changObj">更改count的值</button> </div> </template> <script setup> import { ref, reactive, watch, watchEffect } from "vue"; const obj = ref({name:'你好'}) function changObj(){ obj.value.name+='我不好' } watch(obj.value,()=>{ console.log(obj.value.name); }) </script> <style> </style>
我們可以使用watchEffect 函數來簡化上面的程式碼。 watchEffect()
允許我們自動追蹤回呼的響應式依賴。上面的偵聽器可以重寫為:
<template> <div> <div>{{ obj.name }}</div> <button @click="changObj">更改count的值</button> </div> </template> <script setup> import { ref, reactive, watch, watchEffect } from "vue"; const obj = ref({name:'你好'}) function changObj(){ obj.value.name+='我不好' } // watch(obj.value,()=>{ // console.log(obj.value.name); // }) watchEffect(()=>{ console.log(obj.value.name); }) </script> <style> </style>
註:需要注意的是watchEffect 回呼會立即執行,不需要指定immediate
watch 和watchEffect 都能響應式地執行有副作用的回呼。它們之間的主要區別是追蹤響應式依賴的方式:
watch 只追蹤明確偵聽的資料來源。它不會追蹤任何在回調中訪問到的東西。另外,僅在資料來源確實改變時才會觸發回調。 watch 會避免在發生副作用時追蹤依賴,因此,我們能更精確地控制回呼函數的觸發時機。
watchEffect,則會在副作用發生期間追蹤依賴。它會在同步執行過程中,自動追蹤所有能存取到的響應式屬性。這更方便,而且程式碼往往更簡潔,但有時其響應性依賴關係會比較不明確。
如果想在偵聽器回呼中能存取被Vue 更新之後的DOM,你需要指明flush: ' post' 選項:
watch(source, callback, { flush: 'post' }) watchEffect(callback, { flush: 'post' })
停止監聽
在setup() 或