import Vue from 'vue'; export default { setup(props, context) { console.log(Vue.version); return {}; } };
Wenn wir den reaktionsfähigen state
ändern, Vue
update DOM
wird nicht synchron in Echtzeit aktualisiert, sondern speichert alle synchron ausgeführten Statusaktualisierungen. Nach der Ausführung des Synchronisierungscodes wird der Dom-Aktualisierungsvorgang ausgeführt, was sehr wichtig ist schwierig. Die Leistung von render
wurde stark optimiert und die Anzahl der Dom
-Updates wurde reduziert. state
时,Vue
更新DOM
并不是同步实时更新的,而是将同步执行的所有state更新缓存起来,同步代码执行完后再去执行Dom更新操作,很大程度的优化了render
性能,减少了Dom
更新次数;
而这一特性带来的一个问题,我们无法在state
更改后获取到真实的Dom
,所以Vue提供了nextTick
来获取state
更新后的Dom
function nextTick(callback?: () => void): Promise<void>
使用案例
<template> <div class="test_demo"> <h3 class="text">{{ text }}</h3> <button @click="onBtnClick">更新</button> </div> </template> <script lang="ts" setup> import { ref, nextTick } from 'vue'; const text = ref('test_0'); const onBtnClick = () => { text.value = 'test_1'; nextTick(() => { const text = ( document.querySelector<HTMLElement>('.text') as HTMLElement ).innerText; console.log(text); }); text.value = 'test_2'; }; </script>
点击更新
按钮后,输出test_2。但是,如果注释掉text.value = 'test_1';
,输出结果大不一样,输出test_0。
为什么会有这个问题?
text.value
赋值操作是同步实时的,代码执行遇到响应式state
的更改时,会提交一个视图更新逻辑
到微任务队列,遇到nextTick,也会向微任务队列提交。 所以上述代码,视图更新逻辑
在nextTick
前边,视图更新逻辑
的执行是将text.value = 'test_1'
和text.value = 'test_2'
合并后再更新视图,所以输出test2;
注释掉text.value = 'test_1'
后,nextTick
在微任务队列的顺序就在视图更新逻辑
前边了,所以输出test_0。
如果你使用<script setup lang='ts'>
语法,就需要使用defineProps
让TS
推导出组件的Props
<script setup lang="ts"> // 启用了 TypeScript import { ref } from 'vue' const props = defineProps({ msg: String }) const count = ref(1) </script> <template> <!-- 启用了类型检查和自动补全 --> {{ count.toFixed(2) }} </template>
如果没有使用setup
语法,考虑使用defineComponent
进行包裹,从而实现类型推导
import { defineComponent } from 'vue' export default defineComponent({ // 启用了类型推导 props: { message: String }, setup(props) { props.message // 类型:string | undefined } })
如果项目用Webpack,需要注意下,defineComponent
可能导致组件无法被tree shaking
, 为了确保组件被安全的tree shaking
,需要我们开发时做一下处理
export default /*#__PURE__*/ defineComponent(/* ... */)
如果项目用Vite,不需要做任何处理,因为Vite
底层的Rollup
会智能的认为defineComponent
没有副作用。
开发过程中,有一些场景例如:弹框内的表单、其它Tab下的组件等在页面初始化时不需要加载,我们可以考虑使用defineAsyncComponent
来声明成异步组件,从而提高页面初始化的速度。
import { defineAsyncComponent } from 'vue'; const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { // ...从服务器获取组件 resolve(/* 获取到的组件 */); }); });
import { defineAsyncComponent } from 'vue'; const AsyncComp = defineAsyncComponent( () => import('./components/MyComponent.vue') );
const AsyncComp = defineAsyncComponent({ // 加载函数 loader: () => import('./Foo.vue'), // 加载异步组件时使用的组件 loadingComponent: LoadingComponent, // 展示加载组件前的延迟时间,默认为 200ms delay: 200, // 加载失败后展示的组件 errorComponent: ErrorComponent, // 如果提供了一个 timeout 时间限制,并超时了 // 也会显示这里配置的报错组件,默认值是:Infinity timeout: 3000 });
<Suspense>
是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态。
虽然defineAsyncComponent
具备loadingComponent
参数来配置加载异步组件时的Loading组件,但是在一些场景,是需要使用Suspense
来使用的。例如:A组件依赖了B、C、D,如果三个都是异步组件,加载的过程要显示3个Loading,而Suspense
可以配置所有子组件存在未加载时而现实的Loading。
关于Web Components
的介绍请参考文章 Web Components入门
Vue 提供了一个和定义一般 Vue 组件几乎完全一致的defineCustomElement
state</code >Der echte <code>Dom
wird nach der Änderung erhalten, daher stellt Vue nextTick
bereit, um den aktualisierten Dom
nach < zu erhalten code>state🎜 import { defineCustomElement } from 'vue'; const MyVueElement = defineCustomElement({ /* 组件选项 */ }); // 注册自定义元素 customElements.define('my-vue-element', MyVueElement);
Update
wird test_2 ausgegeben. Wenn Sie jedoch text.value = 'test_1';
auskommentieren, ist das Ausgabeergebnis ganz anders, test_0 wird ausgegeben. 🎜🎜Warum gibt es dieses Problem? 🎜🎜text.value
-Zuweisungsvorgang erfolgt synchron und in Echtzeit. Wenn bei der Codeausführung Änderungen im responsiven Zustand
festgestellt werden, wird eine Ansichtsaktualisierungslogik
ausgeführt übermittelt Gehen Sie zur Mikrotask-Warteschlange und wenn Sie auf nextTick stoßen, wird es auch an die Mikrotask-Warteschlange gesendet. Daher steht im obigen Code die Ansichtsaktualisierungslogik
vor nextTick
und die Ausführung der Ansichtsaktualisierungslogik
besteht darin, zu ändern text.value = 'test_1' und <code>text.value = 'test_2'
werden vor dem Aktualisieren der Ansicht zusammengeführt, sodass test2 ausgegeben wird;🎜🎜Nach dem Auskommentieren von text.value = 'test_1'
, nextTick
in der Mikrotask-Warteschlange liegt direkt vor view updatelogic
, daher wird test_0 ausgegeben. 🎜🎜defineComponent (Hilfsfunktion für die Typinferenz, die es TypeScript ermöglicht, den Typ in der Komponentenoption korrekt abzuleiten)🎜🎜Wenn Sie die Syntax <script setup lang='ts'>
verwenden, benötigen Sie Durch die Verwendung von defineProps
kann TS
die Props
der Komponente ableiten Wenn das Projekt Webpack verwendet, beachten Sie bitte, dass defineComponent
dazu führen kann, dass die Komponente nicht in der Lage ist, tree shaking. Um sicherzustellen, dass die Komponente das sichere <code>Baumschütteln
während der Entwicklung verarbeitet werden muss🎜rrreee🎜Wenn das Projekt Vite verwendet, ist keine Verarbeitung erforderlich, da die zugrunde liegende RollupVite /code> geht intelligent davon aus, dass defineComponent
keine Nebenwirkungen hat. 🎜🎜defineAsyncComponent (asynchrone Komponente)🎜🎜Während des Entwicklungsprozesses gibt es einige Szenarien, wie zum Beispiel: Formulare in Popup-Feldern, Komponenten unter anderen Registerkarten usw. müssen während der Seiteninitialisierung nicht geladen werden. Wir können die Verwendung von defineAsyncComponent, um es als asynchrone Komponente zu deklarieren, um die Geschwindigkeit der Seiteninitialisierung zu erhöhen. 🎜🎜Verwendung eins (Komponenten vom Server abrufen)🎜rrreee🎜Verwendung zwei (lokale Komponenten asynchron laden)🎜rrreee🎜defineAsyncComponent andere Parameterkonfiguration🎜rrreee🎜Suspense🎜🎜<Suspense>
ist ein eingebauter in Komponente. Wird verwendet, um die Verarbeitung asynchroner Abhängigkeiten im Komponentenbaum zu koordinieren. Dadurch können wir weiter oben im Komponentenbaum darauf warten, dass mehrere verschachtelte asynchrone Abhängigkeiten unten aufgelöst werden, und während des Wartens einen Ladezustand rendern. 🎜🎜Obwohl defineAsyncComponent
über den Parameter loadingComponent
verfügt, um die Loading-Komponente beim Laden asynchroner Komponenten zu konfigurieren, muss in einigen Szenarien Suspense
verwendet werden. Beispiel: Eine Komponente hängt von B, C und D ab. Wenn alle drei asynchrone Komponenten sind, zeigt der Ladevorgang drei Ladungen an, und Suspense
kann alle Unterkomponenten so konfigurieren, dass sie tatsächlich geladen werden, wenn sie vorhanden sind sind nicht geladen. 🎜🎜defineCustomElement (Verwenden von Vue-Komponenten zum Entwickeln von Webkomponenten)🎜🎜Eine Einführung in Webkomponenten
finden Sie im Artikel Erste Schritte mit Webkomponenten. 🎜🎜Vue bietet ein defineCustomElement, das nahezu vollständig ist Identisch mit der Definition allgemeiner Vue-Komponenten
zur Unterstützung der Erstellung benutzerdefinierter Elemente. 🎜rrreeeDas obige ist der detaillierte Inhalt vonSo verwenden Sie die allgemeine API-Funktion von Vue3. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!