p"/> p">
Heim >Web-Frontend >View.js >So verwenden Sie watch, um den Eigenschaftswert eines Objekts in Vue3 zu überwachen
Der zweite Parameter: die Rückruffunktion, die ausgelöst werden soll, wenn sich die Abhörquelle ändert. (newValue, oldValue) => { /* code */}
Beim Abhören mehrerer Quellen akzeptiert die Rückruffunktion zwei Arrays, die dem neuen Wert und dem alten Wert im Quellarray entsprechenWenn( [ newValue1 , newValue2 ] , [ oldValue1 , oldValue2 ]) => {/* code */}Der dritte Parameter: optionales Objekt, das diese Optionen unterstützen kannimmediate: Der Rückruf wird sofort ausgelöst, wenn der Listener tief erstellt wird: if Die Quelle ist ein Objekt, das die Tiefendurchquerung dazu zwingt, die Rückruffunktion auszulösen, wenn sich die Tiefenebene bündig ändert: Passen Sie den Aktualisierungszeitpunkt der Rückruffunktion an onTrack / onTrigger: Debuggen Sie Listener-Abhängigkeiten
2 Grund
Weil
watch Die Abhörquelle von code> kann nur die 4 oben genannten Situationen sein
-Abhörquelle,cb
-Rückruffunktion,options
-Abhörkonfiguration und schließlich eindoWatch
4.doWatch-Quellcode werden zurückgegeben Analyse
<script lang="ts" setup> // 接受父组件传递的数据 const props = defineProps({ test: { type: String, default: '' } }) // 使用 watch 侦听 props 中的 test 属性 watch( // 这种写法不会侦听到 props 中 test 的变化 props.test, () => { console.log("侦听成功") } ) watch( // 这种写法会侦听到 props 中 test 的变化 () => props.test, () => { console.log("侦听成功") } ) </script>
doWatch
akzeptiert weiterhin drei Parameter:source
Abhörquelle,cb
Rückruffunktion,options
Listening-KonfigurationHier konzentrieren wir uns auf die Analyse des Quellcodes der Hörquelle (
Quellenstandardisierung)
source
ist ref
-Typ, getter
ist eine Funktion, die source.value
zurückgibt, forceTrigger
hängt davon ab, ob source
ist flache Reaktionsfähigkeit.
const obj = reactive({ count: 0 }) // 错误,因为 watch() 中的侦听源是一个 number,最终 source 返回的 getter 函数是一个空,所以就得不到侦听的数据 watch(obj.count, (count) => { console.log(`count is: ${count}`) }) // 正确,主要思想是,将侦听源转化为以上4种类型(转化为getter函数是最简单方便的) watch( () => obj.count, (count) => { console.log(`count is: ${count}`) } )
watch
的侦听源只能是上面的4中情况export function watch<T = any, Immediate extends Readonly<boolean> = false>( source: T | WatchSource<T>, cb: any, options?: WatchOptions<Immediate> ): WatchStopHandle { if (__DEV__ && !isFunction(cb)) { warn( `\`watch(fn, options?)\` signature has been moved to a separate API. ` + `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` + `supports \`watch(source, cb, options?) signature.` ) } return doWatch(source as any, cb, options) }
function doWatch( source: WatchSource | WatchSource[] | WatchEffect | object, cb: WatchCallback | null, { immediate, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ ): WatchStopHandle { // ... // 当前组件实例 const instance = currentInstance // 副作用函数,在初始化effect时使用 let getter: () => any // 强制触发侦听 let forceTrigger = false // 是否为多数据源。 let isMultiSource = false }
从源码中可以看出,watch
接收三个参数:source
侦听源、cb
回调函数、options
侦听配置,最后会返回一个doWatch
if (isRef(source)) { getter = () => source.value forceTrigger = isShallow(source) }
doWatch
依然接受三个参数:source
侦听源、cb
回调函数、options
侦听配置
这里着重对侦听源的源码进行分析(source标准化)
如果source
是ref
类型,getter
是个返回source.value
的函数,forceTrigger
取决于source
是否是浅层响应式。
if (isReactive(source)) { getter = () => source deep = true }
如果source
是reactive
类型,getter
是个返回source
的函数,并将deep
设置为true
。 当直接侦听一个响应式对象时,侦听器会自动启用深层模式
<template> <div class="container"> <h3>obj---{{ obj }}</h3> <button @click="changeName">修改名字</button> <button @click="changeAge">修改年龄</button> </div> </template> <script lang="ts" setup> import { reactive, watch } from "vue"; const obj = reactive({ name: "张三", age: 18, }); const changeName = () => { obj.name += "++"; }; const changeAge = () => { obj.age += 1; }; // obj 中的任一属性变化了,都会被监听到 watch(obj, () => { console.log("变化了"); }); </script>
例子
if (isArray(source)) { isMultiSource = true forceTrigger = source.some(isReactive) getter = () => source.map(s => { if (isRef(s)) { return s.value } else if (isReactive(s)) { return traverse(s) } else if (isFunction(s)) { return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER) } else { __DEV__ && warnInvalidSource(s) } }) }
如果source
是个数组,将isMultiSource
设为true
,forceTrigger
取决于source
是否有reactive
类型的数据,getter
函数中会遍历source
,针对不同类型的source
做不同处理。
if (isFunction(source)) { if (cb) { getter = () => callWithErrorHandling(source, instance, ErrorCodes.WATCH_GETTER) } else { // watchEffect getter = () => { // 如果组件实例已经卸载,直接return if (instance && instance.isUnmounted) { return } // 如果清理函数,则执行清理函数 if (cleanup) { cleanup() } // 执行source,传入onCleanup,用来注册清理函数 return callWithAsyncErrorHandling( source, instance, ErrorCodes.WATCH_CALLBACK, [onCleanup] ) } } }
如果source
是个function
。存在cb
的情况下,getter
函数中会执行source
,这里source
会通过callWithErrorHandling
函数执行,在callWithErrorHandling
中会处理source
执行过程中出现的错误;不存在cb
的话,在getter
中,如果组件已经被卸载了,直接return
,否则判断cleanup
(cleanup
是在watchEffect
中通过onCleanup
注册的清理函数),如果存在cleanup
执行cleanup
,接着执行source
,并返回执行结果。source
会被callWithAsyncErrorHandling
包装,该函数作用会处理source
执行过程中出现的错误,与callWithErrorHandling
不同的是,callWithAsyncErrorHandling
会处理异步错误。
getter = NOOP __DEV__ && warnInvalidSource(source)
其他情况getter
Wenn source
vom Typ reactive
ist, ist es auch getter
eine Rückgabefunktion von source
und setzen Sie deep
auf true
. Beim direkten Abhören eines reaktiven Objekts aktiviert der Listener automatisch den Deep-Modus
source
ein Array ist , setzen Sie isMultiSource
auf true
, forceTrigger
hängt davon ab, ob source
reactive
für Code hat > Typdaten durchläuft die Getter
-Funktion die Quelle
und führt unterschiedliche Verarbeitungen für verschiedene Arten von Quelle
durch. 🎜🎜🎜rrreeesource
eine function
ist. Wenn cb
vorhanden ist, wird source
in der Funktion getter
ausgeführt, wobei source
callWithErrorHandlingFunktionsausführung, Fehler, die während der Ausführung von <code>source
auftreten, werden in callWithErrorHandling
behandelt, wenn in cb
vorhanden ist >Getter , wenn die Komponente deinstalliert wurde, direkt zurück
, andernfalls cleanup
bestimmen (cleanup
ist in watchEffect code> (Bereinigungsfunktion registriert durch <code>onCleanup
), wenn es eine cleanup
gibt, führen Sie cleanup
aus und führen Sie dann source aus code> und Ausführungsergebnisse zurückgeben. <code>source
wird von callWithAsyncErrorHandling
umschlossen. Diese Funktion behandelt Fehler, die während der Ausführung von source
auftreten, was sich von callWithErrorHandling Ja, <code>callWithAsyncErrorHandling
behandelt asynchrone Fehler. 🎜🎜🎜rrreeegetter
eine leere Funktion zugewiesen🎜🎜🎜rrreeeDas obige ist der detaillierte Inhalt vonSo verwenden Sie watch, um den Eigenschaftswert eines Objekts in Vue3 zu überwachen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!