Was ist das Implementierungsprinzip der Vue3-Listener-Uhr?
Die Essenz der Uhr
Die sogenannte Uhr, ihre Essenz besteht darin, reagierende Daten zu beobachten, zu benachrichtigen und die entsprechende Rückruffunktion auszuführen, wenn sich die Daten ändern. Tatsächlich besteht die Essenz der Implementierung von watch darin, die Optionen effect und options.scheduler zu verwenden. Wie im folgenden Beispiel gezeigt:
// watch 函数接收两个参数,source 是响应式数据,cb 是回调函数 function watch(source, cb){ effect( // 触发读取操作,从而建立联系 () => source.foo, { scheduler(){ // 当数据变化时,调用回调函数 cb cb() } } ) }
Wie im Code gezeigt, handelt es sich bei der Quelle um reaktive Daten und bei cb um die Rückruffunktion. Wenn in der Nebeneffektfunktion eine Scheduler-Option vorhanden ist, wird bei einer Änderung der Reaktionsdaten die Ausführung der Scheduler-Funktion ausgelöst, anstatt die Ausführung der Nebeneffektfunktion direkt auszulösen. Aus dieser Perspektive entspricht die Scheduler-Planungsfunktion einer Rückruffunktion, und die Implementierung von watch nutzt dies aus. Die Funktionssignatur von
watch
hört auf mehrere Quellen
Die abzuhörende Datenquelle kann ein Array sein, wie in der folgenden Funktionssignatur gezeigt:
// packages/runtime-core/src/apiWatch.ts // 数据源是一个数组 // overload: array of multiple sources + cb export function watch< T extends MultiWatchSources, Immediate extends Readonly<boolean> = false >( sources: [...T], cb: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>, options?: WatchOptions<Immediate> ): WatchStopHandle
Ein Array kann auch zum Abhören mehrerer Quellen verwendet werden gleichzeitig, wie unten gezeigt. Die Funktionssignatur ist wie folgt:
// packages/runtime-core/src/apiWatch.ts // 使用数组同时侦听多个源 // overload: multiple sources w/ `as const` // watch([foo, bar] as const, () => {}) // somehow [...T] breaks when the type is readonly export function watch< T extends Readonly<MultiWatchSources>, Immediate extends Readonly<boolean> = false >( source: T, cb: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>, options?: WatchOptions<Immediate> ): WatchStopHandle
Abhören einer einzelnen Quelle
Die abzuhörende Datenquelle ist ein Ref-Typ-Datentyp oder eine Getter-Funktion mit einem Rückgabewert, wie im Folgenden gezeigt Funktionssignatur:
// packages/runtime-core/src/apiWatch.ts // 数据源是一个 ref 类型的数据 或者是一个具有返回值的 getter 函数 // overload: single source + cb export function watch<T, Immediate extends Readonly<boolean> = false>( source: WatchSource<T>, cb: WatchCallback<T, Immediate extends true ? T | undefined : T>, options?: WatchOptions<Immediate> ): WatchStopHandle export type WatchSource<T = any> = Ref<T> | ComputedRef<T> | (() => T)
Die abzuhörenden Daten. Die Quelle ist ein reaktionsfähiges Objekt, wie in der folgenden Funktionssignatur gezeigt:
// packages/runtime-core/src/apiWatch.ts // 数据源是一个响应式的 obj 对象 // overload: watching reactive object w/ cb export function watch< T extends object, Immediate extends Readonly<boolean> = false >( source: T, cb: WatchCallback<T, Immediate extends true ? T | undefined : T>, options?: WatchOptions<Immediate> ): WatchStopHandle
Implementierung der Überwachung
Überwachungsfunktion
// packages/runtime-core/src/apiWatch.ts // implementation 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) }
Wie Sie sehen können, empfängt die Überwachungsfunktion 3 Parameter: Quelle Die abzuhörende Datenquelle, CB-Rückruffunktion, Optionen Abhöroptionen.
Quellenparameter
Aus der Funktionsüberladung von watch können Sie erkennen, dass beim Abhören einer einzelnen Quelle die Quelle Daten vom Typ Ref oder eine Getter-Funktion mit einem Rückgabewert oder ein reaktives Objekt sein kann. Beim Anhören mehrerer Quellen kann die Quelle ein Array sein.
cb-Parameter
In der cb-Rückruffunktion stellt es Entwicklern den neuesten Wert, den alten Wert und die onCleanup-Funktion zur Bereinigung von Nebenwirkungen zur Verfügung. Wie in der folgenden Typdefinition gezeigt:
export type WatchCallback<V = any, OV = any> = ( value: V, oldValue: OV, onCleanup: OnCleanup ) => any
Optionsparameter
Optionsoptionen können das Verhalten der Uhr steuern. Beispielsweise kann der Optionsparameter „Immediate“ von Optionen verwendet werden, um zu steuern, ob der Rückruf der Uhr sofort ausgeführt wird Der Optionsparameter von Optionen kann verwendet werden, um die Rückruffunktion der Uhr zu steuern. Ob sie synchron oder asynchron ausgeführt werden soll. Die Typdefinition des Optionsparameters lautet wie folgt:
export interface WatchOptionsBase extends DebuggerOptions { flush?: 'pre' | 'post' | 'sync' } export interface WatchOptions<Immediate = boolean> extends WatchOptionsBase { immediate?: Immediate deep?: boolean }
Sie können sehen, dass WatchOptions WatchOptionsBase erbt. Das heißt, zusätzlich zu den beiden einzigartigen Parametern „immediate“ und „deep“ in den Optionen von watch können auch alle Parameter in WatchOptionsBase übergeben werden, um das Verhalten bei der Ausführung von Nebeneffekten zu steuern.
Die doWatch-Funktion wird im Funktionskörper von watch aufgerufen. Schauen wir uns ihre Implementierung an.
doWatch-Funktion
Tatsächlich wird die doWatch-Funktion letztendlich während der Ausführung aufgerufen, unabhängig davon, ob es sich um die Watch-Funktion oder die watchEffect-Funktion handelt.
doWatch-Funktionssignatur
function doWatch( source: WatchSource | WatchSource[] | WatchEffect | object, cb: WatchCallback | null, { immediate, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ ): WatchStopHandle
Die Funktionssignatur von doWatch ist im Wesentlichen dieselbe wie die Funktionssignatur von watch und empfängt außerdem drei Parameter. Um die Verwendung der Optionsoption zu erleichtern, wird sie von der doWatch-Funktion dekonstruiert.
Variablen initialisieren
Erstens die aktuelle Komponenteninstanz über die Komponente abrufen und dann drei verschiedene Variablen deklarieren. Eine der Funktionen heißt Getter und wird als Argument an die Nebeneffektfunktion übergeben. Die Variable forceTrigger ist ein boolescher Wert, der angibt, ob die Nebeneffektfunktion erzwungen werden muss. Die Variable isMultiSource ist ebenfalls ein boolescher Wert, der verwendet wird, um zu markieren, ob es sich bei der Listening-Datenquelle um eine einzelne Quelle oder um mehrere Quellen handelt, die in Form eines Arrays übergeben werden. Der Anfangswert ist „false“, was darauf hinweist, dass es sich bei der Listening-Datenquelle um eine einzelne Quelle handelt. Wie im folgenden Code gezeigt:
const instance = currentInstance let getter: () => any // 是否需要强制触发副作用函数执行 let forceTrigger = false // 侦听的是否是多个源 let isMultiSource = false
Als nächstes initialisieren Sie diese drei Variablen entsprechend der abgehörten Datenquelle.
Die Abhördatenquelle sind Daten vom Ref-Typ.
Wenn es sich bei der Abhördatenquelle um Daten vom Ref-Typ handelt, wird der Getter durch die Rückgabe von source.value initialisiert, d. h., wenn die Getter-Funktion ausgelöst wird, die tatsächlichen Abhördaten wird über source.value abgerufen. Verwenden Sie dann die Funktion isShallow, um zu bestimmen, ob die abgehörte Datenquelle eine flache Antwort ist, und weisen Sie das Ergebnis forceTrigger zu, um die Initialisierung der Variable forceTrigger abzuschließen. Wie im folgenden Code gezeigt:
if (isRef(source)) { // 侦听的数据源是 ref getter = () => source.value // 判断数据源是否是浅响应 forceTrigger = isShallow(source) }
Die abhörende Datenquelle ist eine reaktionsfähige Datenquelle.
Wenn es sich bei der abhörenden Datenquelle um eine reaktionsfähige Datenquelle handelt, wird die Quelle direkt zurückgegeben, um den Getter zu initialisieren, d. h. wenn die Getter-Funktion vorhanden ist getriggert Gibt direkt die lauschende Datenquelle zurück. Da es sich bei den Antwortdaten möglicherweise um ein Objekt handelt, wird die Tiefe auf „true“ gesetzt, und die Attributwerte des Objekts können rekursiv gelesen werden, wenn die Getter-Funktion ausgelöst wird. Wie im folgenden Code gezeigt:
else if (isReactive(source)) { // 侦听的数据源是响应式数据 getter = () => source deep = true }
Die Abhördatenquelle ist ein Array
Wenn die Abhördatenquelle ein Array ist, werden mehrere Quellen gleichzeitig abgehört. Setzen Sie zu diesem Zeitpunkt die Variable isMultiSource direkt auf true, um anzuzeigen, dass mehrere Quellen abgehört werden. Verwenden Sie dann die Methode some des Arrays, um zu erkennen, ob in den mehreren Überwachungsquellen reagierende Objekte vorhanden sind, und weisen Sie die Ergebnisse forceTrigger zu. Durchlaufen Sie das Array und schließen Sie die Initialisierung der Getter-Funktion basierend auf dem Typ jeder Quelle ab. Wie im folgenden Code gezeigt:
else if (isArray(source)) { // 侦听的数据源是一个数组,即同时侦听多个源 isMultiSource = true forceTrigger = source.some(isReactive) getter = () => // 遍历数组,判断每个源的类型 source.map(s => { if (isRef(s)) { // 侦听的数据源是 ref return s.value } else if (isReactive(s)) { // 侦听的数据源是响应式数据 return traverse(s) } else if (isFunction(s)) { // 侦听的数据源是一个具有返回值的 getter 函数 return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER) } else { __DEV__ && warnInvalidSource(s) } }) }
Die Abhördatenquelle ist eine Funktion
当侦听的数据源是一个具有返回值的 getter 函数时,判断 doWatch 函数的第二个参数 cb 是否有传入。如果有传入,则处理的是 watch 函数的场景,此时执行 source 函数,将执行结果赋值给 getter 。该情况仅适用于 watchEffect 函数未接收到参数的情况。如果组件实例已被卸载,则直接返回而不执行 source 函数,根据该场景进行处理。如果未能执行成功,则执行清除依赖的代码并调用source函数,将返回结果赋值给getter。如下面的代码所示:
else if (isFunction(source)) { // 处理 watch 和 watchEffect 的场景 // watch 的第二个参数可以是一个具有返回值的 getter 参数,第二个参数是一个回调函数 // watchEffect 的参数是一个 函数 // 侦听的数据源是一个具有返回值的 getter 函数 if (cb) { // getter with cb // 处理的是 watch 的场景 // 执行 source 函数,将执行结果赋值给 getter getter = () => callWithErrorHandling(source, instance, ErrorCodes.WATCH_GETTER) } else { // no cb -> simple effect // 没有回调,即为 watchEffect 的场景 getter = () => { // 件实例已经卸载,则不执行,直接返回 if (instance && instance.isUnmounted) { return } // 清除依赖 if (cleanup) { cleanup() } // 执行 source 函数 return callWithAsyncErrorHandling( source, instance, ErrorCodes.WATCH_CALLBACK, [onCleanup] ) } } }
递归读取响应式数据
如果侦听的数据源是一个响应式数据,需要递归读取响应式数据中的属性值。如下面的代码所示:
// 处理的是 watch 的场景 // 递归读取对象的属性值 if (cb && deep) { const baseGetter = getter getter = () => traverse(baseGetter()) }
在上面的代码中,doWatch 函数的第二个参数 cb 有传入,说明处理的是 watch 中的场景。deep 变量为 true ,说明此时侦听的数据源是一个响应式数据,因此需要调用 traverse 函数来递归读取数据源中的每个属性,对其进行监听,从而当任意属性发生变化时都能够触发回调函数执行。
定义清除副作用函数
声明 cleanup 和 onCleanup 函数,并在 onCleanup 函数的执行过程中给 cleanup 函数赋值,当副作用函数执行一些异步的副作用时,这些响应需要在其失效是清除。如下面的代码所示:
// 清除副作用函数 let cleanup: () => void let onCleanup: OnCleanup = (fn: () => void) => { cleanup = effect.onStop = () => { callWithErrorHandling(fn, instance, ErrorCodes.WATCH_CLEANUP) } }
封装 scheduler 调度函数
为了便于控制 watch 的回调函数 cb 的执行时机,需要将 scheduler 调度函数封装为一个独立的 job 函数,如下面的代码所示:
// 将 scheduler 调度函数封装为一个独立的 job 函数,便于在初始化和变更时执行它 const job: SchedulerJob = () => { if (!effect.active) { return } if (cb) { // 处理 watch 的场景 // watch(source, cb) // 执行副作用函数获取新值 const newValue = effect.run() // 如果数据源是响应式数据或者需要强制触发副作用函数执行或者新旧值发生了变化 // 则执行回调函数,并更新旧值 if ( deep || forceTrigger || (isMultiSource ? (newValue as any[]).some((v, i) => hasChanged(v, (oldValue as any[])[i]) ) : hasChanged(newValue, oldValue)) || (__COMPAT__ && isArray(newValue) && isCompatEnabled(DeprecationTypes.WATCH_ARRAY, instance)) ) { // 当回调再次执行前先清除副作用 // cleanup before running cb again if (cleanup) { cleanup() } // 执行watch 函数的回调函数 cb,将旧值和新值作为回调函数的参数 callWithAsyncErrorHandling(cb, instance, ErrorCodes.WATCH_CALLBACK, [ newValue, // 首次调用时,将 oldValue 的值设置为 undefined // pass undefined as the old value when it's changed for the first time oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue, onCleanup ]) // 更新旧值,不然下一次会得到错误的旧值 oldValue = newValue } } else { // watchEffect // 处理 watchEffect 的场景 effect.run() } }
在 job 函数中,判断回调函数 cb 是否传入,如果有传入,那么是 watch 函数被调用的场景,否则就是 watchEffect 函数被调用的场景。
如果是 watch 函数被调用的场景,首先执行副作用函数,将执行结果赋值给 newValue 变量,作为最新的值。然后判断需要执行回调函数 cb 的情况:
如果侦听的数据源是响应式数据,需要深度侦听,即 deep 为 true
如果需要强制触发副作用函数执行,即 forceTrigger 为 true
如果新旧值发生了变化
如果存在上述三种情况之一,就必须执行 watch 函数的回调函数 cb。如果回调函数 cb 是再次执行,在执行之前需要先清除副作用。然后调用 callWithAsyncErrorHandling 函数执行回调函数cb,并将新值newValue 和旧值 oldValue 传入回调函数cb中。在回调函数cb执行后,更新旧值oldValue,避免在下一次执行回调函数cb时获取到错误的旧值。
如果是 watchEffect 函数被调用的场景,则直接执行副作用函数即可。
设置 job 的 allowRecurse 属性
设置 job 函数的 allowRecurse 属性根据是否传递回调函数 cb 来进行。这个设置非常关键,因为它可以使作业充当监听器的回调,这样调度程序就能够知道它是否允许调用自身。
// important: mark the job as a watcher callback so that scheduler knows // it is allowed to self-trigger (#1727) // 重要:让调度器任务作为侦听器的回调以至于调度器能知道它可以被允许自己派发更新 job.allowRecurse = !!cb
flush 选项指定回调函数的执行时机
在调用 watch 函数时,可以通过 options 的 flush 选项来指定回调函数的执行时机:
当 flush 的值为 sync 时,代表调度器函数是同步执行,此时直接将 job 赋值给 scheduler,这样调度器函数就会直接执行。
当 flush 的值为 post 时,代表调度函数需要将副作用函数放到一个微任务队列中,并等待 DOM 更新结束后再执行。
当 flush 的值为 pre 时,即调度器函数默认的执行方式,这时调度器会区分组件是否已经挂载。如果组件未挂载,则先执行一次调度函数,即执行回调函数cb。在组件挂载之后,将调度函数推入一个优先执行时机的队列中。
// 这里处理的是回调函数的执行时机
let scheduler: EffectScheduler if (flush === 'sync') { // 同步执行,将 job 直接赋值给调度器 scheduler = job as any // the scheduler function gets called directly } else if (flush === 'post') { // 将调度函数 job 添加到微任务队列中执行 scheduler = () => queuePostRenderEffect(job, instance && instance.suspense) } else { // default: 'pre' // 调度器函数默认的执行模式 scheduler = () => { if (!instance || instance.isMounted) { // 组件挂载后将 job 推入一个优先执行时机的队列中 queuePreFlushCb(job) } else { // with 'pre' option, the first call must happen before // the component is mounted so it is called synchronously. // 在 pre 选型中,第一次调用必须发生在组件挂载之前 // 所以这次调用是同步的 job() } } }
创建副作用函数
初始化完 getter 函数和调度器函数 scheduler 后,调用 ReactiveEffect 类来创建一个副作用函数
// 创建一个副作用函数 const effect = new ReactiveEffect(getter, scheduler)
执行副作用函数
在执行副作用函数之前,首先判断是否传入了回调函数cb,如果有传入,则根据 options 的 immediate 选项来判断是否需要立即执行回调函数cb,如果指定了immediate 选项,则立即执行 job 函数,即 watch 的回调函数会在 watch 创建时立即执行一次。如果不这样做,就需要手动调用副作用函数,将其返回值赋值给oldValue作为旧值。如下面的代码所示:
if (cb) { // 选项参数 immediate 来指定回调是否需要立即执行 if (immediate) { // 回调函数会在 watch 创建时立即执行一次 job() } else { // 手动调用副作用函数,拿到的就是旧值 oldValue = effect.run() } }
如果 options 的 flush 选项的值为 post ,需要将副作用函数放入到微任务队列中,等待组件挂载完成后再执行副作用函数。如下面的代码所示:
else if (flush === 'post') { // 在调度器函数中判断 flush 是否为 'post',如果是,将其放到微任务队列中执行 queuePostRenderEffect( effect.run.bind(effect), instance && instance.suspense ) }
其余情况都是立即执行副作用函数。如下面的代码所示:
else { // 其余情况立即首次执行副作用 effect.run() }
返回匿名函数,停止侦听
最终,doWatch函数返回了一个匿名函数,该函数用于取消对数据源的监听。因此在调用 watch 或者 watchEffect 时,可以调用其返回值类结束侦听。
return () => { effect.stop() if (instance && instance.scope) { // 返回一个函数,用以显式的结束侦听 remove(instance.scope.effects!, effect) } }
Das obige ist der detaillierte Inhalt vonWas ist das Implementierungsprinzip der Vue3-Listener-Uhr?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Möglicherweise sind Sie schon einmal auf das Problem gestoßen, dass auf dem Bildschirm Ihres Smartphones grüne Linien erscheinen. Auch wenn Sie es noch nie gesehen haben, müssen Sie entsprechende Bilder im Internet gesehen haben. Haben Sie schon einmal erlebt, dass der Bildschirm einer Smartwatch weiß wird? Am 2. April erfuhr CNMO aus ausländischen Medien, dass ein Reddit-Benutzer ein Bild auf der sozialen Plattform geteilt hatte, auf dem zu sehen war, wie der Bildschirm der Smartwatches der Samsung Watch-Serie weiß wurde. Der Benutzer schrieb: „Ich war gerade dabei, aufzuladen, und als ich zurückkam, war es so. Ich habe versucht, neu zu starten, aber der Bildschirm der Samsung Watch wurde beim Neustart immer noch weiß.“ Der Reddit-Benutzer hat das Smartwatch-spezifische Modell nicht angegeben. Dem Bild nach zu urteilen dürfte es sich jedoch um eine Samsung Watch5 handeln. Zuvor hatte sich auch ein anderer Reddit-Benutzer gemeldet

vue3+vite:src verwendet „require“, um Bilder dynamisch zu importieren, und vue3+vite importiert dynamisch mehrere Bilder. Wenn Sie „requireisnotdefined“ verwenden, wird eine Fehlermeldung angezeigt like vue2 like imgUrl:require(' .../assets/test.png') wird importiert, da Typescript Require nicht unterstützt, daher wird Import verwendet. So lösen Sie das Problem: Verwenden Sieawaitimport

tinymce ist ein voll funktionsfähiges Rich-Text-Editor-Plug-in, aber die Einführung von tinymce in Vue ist nicht so reibungslos wie bei anderen Vue-Rich-Text-Plug-ins. Tinymce selbst ist nicht für Vue geeignet, und @tinymce/tinymce-vue muss eingeführt werden. und Es handelt sich um ein ausländisches Rich-Text-Plug-in, das die chinesische Version nicht bestanden hat. Sie müssen das Übersetzungspaket von der offiziellen Website herunterladen (möglicherweise müssen Sie die Firewall umgehen). 1. Installieren Sie die zugehörigen Abhängigkeiten npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S2. 3. Führen Sie den Skin und das chinesische Paket ein. Erstellen Sie einen neuen Tinymce-Ordner im öffentlichen Ordner des Projekts und laden Sie ihn herunter

Um das Blog-Frontend mit Vue zu implementieren, müssen Sie die Markdown-Analyse implementieren. Wenn Code vorhanden ist, müssen Sie die Code-Hervorhebung implementieren. Es gibt viele Markdown-Parsing-Bibliotheken für Vue, wie z. B. markdown-it, vue-markdown-loader, markiert, vue-markdown usw. Diese Bibliotheken sind alle sehr ähnlich. Hier wird Markiert verwendet, und highlights.js wird als Code-Hervorhebungsbibliothek verwendet. Die spezifischen Implementierungsschritte lauten wie folgt: 1. Installieren Sie abhängige Bibliotheken. Öffnen Sie das Befehlsfenster unter dem Vue-Projekt und geben Sie den folgenden Befehl ein: npminstallmarked-save//marked, um Markdown in htmlnpmins zu konvertieren

Um eine teilweise Aktualisierung der Seite zu erreichen, müssen wir nur das erneute Rendern der lokalen Komponente (dom) implementieren. In Vue lässt sich dieser Effekt am einfachsten mit der v-if-Direktive erzielen. In Vue2 können wir zusätzlich zur Verwendung der v-if-Anweisung zum erneuten Rendern des lokalen Doms auch eine neue leere Komponente erstellen. Wenn wir die lokale Seite aktualisieren müssen, springen wir zu dieser leeren Komponentenseite und springen dann wieder hinein der beforeRouteEnter-Schutz in der leeren Komponente. Wie in der Abbildung unten gezeigt, wie man in Vue3.X auf die Schaltfläche „Aktualisieren“ klickt, um das DOM im roten Feld neu zu laden und den entsprechenden Ladestatus anzuzeigen. Da der Guard in der Komponente in der scriptsetup-Syntax in Vue3.X nur o hat

Vorwort Ob Vue oder React: Wenn wir auf mehrere wiederholte Codes stoßen, werden wir darüber nachdenken, wie wir diese Codes wiederverwenden können, anstatt eine Datei mit einer Reihe redundanter Codes zu füllen. Tatsächlich können sowohl Vue als auch React eine Wiederverwendung durch Extrahieren von Komponenten erreichen. Wenn Sie jedoch auf einige kleine Codefragmente stoßen und keine andere Datei extrahieren möchten, kann React im Vergleich dazu verwendet werden Deklarieren Sie das entsprechende Widget in der Datei , oder implementieren Sie es über die Renderfunktion, wie zum Beispiel: constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(

Verwenden von Vue zum Erstellen benutzerdefinierter Elemente. WebComponents ist ein Sammelname für eine Reihe webnativer APIs, die es Entwicklern ermöglichen, wiederverwendbare benutzerdefinierte Elemente (Customelements) zu erstellen. Der Hauptvorteil von benutzerdefinierten Elementen besteht darin, dass sie mit jedem Framework verwendet werden können, auch ohne Framework. Sie sind ideal, wenn Sie Endbenutzer ansprechen, die möglicherweise einen anderen Front-End-Technologie-Stack verwenden, oder wenn Sie die endgültige Anwendung von den Implementierungsdetails der verwendeten Komponenten entkoppeln möchten. Vue und WebComponents sind komplementäre Technologien und Vue bietet hervorragende Unterstützung für die Verwendung und Erstellung benutzerdefinierter Elemente. Sie können benutzerdefinierte Elemente in bestehende Vue-Anwendungen integrieren oder Vue zum Erstellen verwenden

Der letzte Effekt besteht darin, die VueCropper-Komponente „garnaddvue-cropper@next“ zu installieren. Wenn es sich um Vue3 handelt oder Sie andere Methoden als Referenz verwenden möchten, besuchen Sie bitte die offizielle npm-Adresse. Es ist auch sehr einfach, es in einer Komponente zu referenzieren und zu verwenden. Sie müssen nur die entsprechende Komponente und ihre Stildatei einführen. Ich verweise hier nicht global, sondern nur auf import{userInfoByRequest}from'../js/api ' in meiner Komponentendatei. import{VueCropper}from'vue-cropper&
