import Vue from 'vue'; export default { setup(props, context) { console.log(Vue.version); return {}; } };
當我們更改響應式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
方法來支援建立自訂元素。
import { defineCustomElement } from 'vue'; const MyVueElement = defineCustomElement({ /* 组件选项 */ }); // 注册自定义元素 customElements.define('my-vue-element', MyVueElement);
以上是Vue3通用API功能怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!