最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3動(dòng)態(tài)組件&異步組件用法及說明

 更新時(shí)間:2026年04月29日 10:37:43   作者:難渡-  
動(dòng)態(tài)組件通過`<component:is="組件標(biāo)識(shí)">`語法實(shí)現(xiàn)不同組件的動(dòng)態(tài)渲染,支持組件對(duì)象、全局組件名稱、異步組件等多種形式,結(jié)合`<KeepAlive>`可保留組件狀態(tài),配合異步組件實(shí)現(xiàn)按需加載,優(yōu)化首屏性能,通過`defineAsyncComponent`支持異步加載,提供加載狀態(tài)處理和配置項(xiàng)優(yōu)化

動(dòng)態(tài)組件

動(dòng)態(tài)組件是通過 <component :is="組件標(biāo)識(shí)"> 語法,讓 Vue 動(dòng)態(tài)渲染不同組件的特性 —— 你只需修改 :is 綁定的值,Vue 就會(huì)自動(dòng)替換渲染的組件,無需寫大量 v-if/v-else 分支。

核心特點(diǎn)

  • 一個(gè)<component>標(biāo)簽即可渲染任意組件;
  • 支持綁定「組件對(duì)象」「組件名稱(全局注冊)」「異步組件」;
  • 配合 <KeepAlive> 可保留組件狀態(tài)(如輸入框內(nèi)容、滾動(dòng)位置);
  • 可以根據(jù)不同的條件靈活切換顯示不同的組件,核心是通過component標(biāo)簽和is屬性;
  • 可以動(dòng)態(tài)傳遞props/事件。

基礎(chǔ)用法

1. 核心語法:綁定組件對(duì)象

Vue3 中 <script setup> 下組件不會(huì)自動(dòng)注冊為全局名稱,直接綁定組件對(duì)象是最優(yōu)寫法:

<template>
  <div>
    <!-- 切換按鈕 -->
    <button @click="currentComp = CompA">組件A</button>
    <button @click="currentComp = CompB">組件B</button>
    <button @click="currentComp = CompC">組件C</button>
    <!-- 動(dòng)態(tài)組件核心標(biāo)簽 -->
    <component :is="currentComp"></component>
  </div>
</template>
<script setup>
import { ref } from 'vue'
// 導(dǎo)入需要切換的組件
import CompA from './CompA.vue'
import CompB from './CompB.vue'
import CompC from './CompC.vue'
// 綁定組件對(duì)象(響應(yīng)式)
const currentComp = ref(CompA) // 默認(rèn)渲染 CompA
</script>

2. 綁定全局組件名稱

如果組件已全局注冊(在 main.js 中注冊),可綁定字符串名稱:

// main.js 全局注冊組件
import { createApp } from 'vue'
import App from './App.vue'
import CompA from './CompA.vue'

const app = createApp(App)
app.component('CompA', CompA) // 全局注冊
app.mount('#app')
<template>
  <component :is="currentCompName"></component>
</template>

<script setup>
import { ref } from 'vue'
const currentCompName = ref('CompA') // 綁定全局組件名稱
</script>

進(jìn)階技巧

1. 保留組件狀態(tài):結(jié)合

動(dòng)態(tài)組件默認(rèn)切換時(shí)會(huì)銷毀舊組件、創(chuàng)建新組件(狀態(tài)丟失),<KeepAlive> 可緩存組件實(shí)例,保留狀態(tài):

<template>
  <div>
    <button @click="currentComp = CompA">組件A</button>
    <button @click="currentComp = CompB">組件B</button>

    <!-- KeepAlive 緩存組件,切換后輸入框內(nèi)容不丟失 -->
    <KeepAlive>
      <component :is="currentComp"></component>
    </KeepAlive>
  </div>
</template>

<!-- CompA.vue 示例(帶輸入框) -->
<template>
    <input v-model="inputVal" placeholder="組件A輸入內(nèi)容" />
</template>
<script setup>
import { ref } from 'vue'
const inputVal = ref('') // 狀態(tài)會(huì)被 KeepAlive 保留
</script>

KeepAlive 高級(jí)配置:

  • - include:僅緩存指定組件(支持字符串 / 正則 / 數(shù)組);
  • - exclude:排除不需要緩存的組件;
  • - max:限制緩存組件的最大數(shù)量(避免內(nèi)存溢出)。

2. 動(dòng)態(tài)傳參:Props / 事件透傳

動(dòng)態(tài)組件支持像普通組件一樣傳遞 Props 和監(jiān)聽事件:

<template>
  <component
    :is="currentComp"
    :msg="parentMsg"
    @change="handleCompChange"
  ></component>
</template>

<script setup>
import { ref } from 'vue'
import CompA from './CompA.vue'

const currentComp = ref(CompA)
const parentMsg = ref('父組件傳遞的消息')

const handleCompChange = (val) => {
  console.log('子組件觸發(fā)的事件:', val)
}
</script>

3. 異步加載:結(jié)合 defineAsyncComponent

動(dòng)態(tài)組件 + 異步組件 = 「按需加載 + 動(dòng)態(tài)切換」,優(yōu)化首屏性能:

<template>
  <component :is="currentComp"></component>
</template>

<script setup>
import { ref, defineAsyncComponent } from 'vue'

// 異步加載組件(切換時(shí)才加載代碼)
const CompA = defineAsyncComponent(() => import('./CompA.vue'))
const CompB = defineAsyncComponent(() => import('./CompB.vue'))

const currentComp = ref(CompA)
</script>

帶加載 / 錯(cuò)誤狀態(tài)的異步組件:

<script setup>
import { ref, defineAsyncComponent } from 'vue'
import Loading from './Loading.vue'
import Error from './Error.vue'

// 配置異步組件的加載/錯(cuò)誤狀態(tài)
const CompA = defineAsyncComponent({
  loader: () => import('./CompA.vue'),
  loadingComponent: Loading, // 加載中顯示
  errorComponent: Error,     // 加載失敗顯示
  delay: 200,                // 延遲顯示加載組件(避免閃屏)
  timeout: 3000              // 超時(shí)時(shí)間
})

const currentComp = ref(CompA)
</script>

4. 動(dòng)態(tài)組件的生命周期

被 <KeepAlive> 緩存的動(dòng)態(tài)組件,會(huì)觸發(fā)兩個(gè)特殊生命周期:

  • activated:組件被激活(切換顯示)時(shí)觸發(fā);
  • deactivated:組件被失活(切換隱藏)時(shí)觸發(fā)。
<!-- CompA.vue -->
<script setup>
import { onActivated, onDeactivated } from 'vue'

onActivated(() => {
  console.log('CompA 被激活(顯示)')
})

onDeactivated(() => {
  console.log('CompA 被失活(隱藏)')
})
</script>

異步組件

異步組件是指組件在需要渲染時(shí)才會(huì)被加載(而非頁面初始化時(shí)) 的組件,底層依賴 ES6 的 import() 動(dòng)態(tài)導(dǎo)入語法和 Vue 提供的 defineAsyncComponent 封裝函數(shù)。

核心價(jià)值

  • 拆分代碼包體積,首屏只加載核心代碼,非核心組件按需加載;
  • 降低首屏加載時(shí)間,提升頁面響應(yīng)速度;
  • 配合動(dòng)態(tài)組件、路由懶加載,實(shí)現(xiàn)更靈活的組件加載策略。

基礎(chǔ)用法

1.最簡寫法

通過 defineAsyncComponent 包裹 import() 函數(shù),返回異步組件對(duì)象:

<template>
  <!-- 像普通組件一樣使用異步組件 -->
  <AsyncComp />
</template>

<script setup>
import { defineAsyncComponent } from 'vue'

// 定義異步組件(最簡寫法)
const AsyncComp = defineAsyncComponent(() => {
  // import() 動(dòng)態(tài)導(dǎo)入組件,返回 Promise
  return import('./AsyncComp.vue')
})
</script>

2.核心邏輯解析

  • import('./AsyncComp.vue'):ES6 動(dòng)態(tài)導(dǎo)入,返回一個(gè) Promise,只有當(dāng)組件需要渲染時(shí)才會(huì)執(zhí)行這個(gè)導(dǎo)入操作;
  • defineAsyncComponent:Vue 封裝的異步組件處理函數(shù),接收加載函數(shù) / 配置對(duì)象,返回一個(gè) “包裝器組件”(同步組件),Vue 會(huì)先渲染包裝器,等真實(shí)組件加載完成后再替換。

進(jìn)階配置

實(shí)際開發(fā)中,需要處理「加載中、加載失敗、超時(shí)、延遲」等場景,defineAsyncComponent 支持完整的配置項(xiàng):

<template>
  <AsyncComp />
</template>

<script setup>
import { defineAsyncComponent } from 'vue'
// 導(dǎo)入加載/錯(cuò)誤兜底組件
import LoadingComp from './LoadingComp.vue'
import ErrorComp from './ErrorComp.vue'

// 完整配置的異步組件
const AsyncComp = defineAsyncComponent({
  // 1. 核心:加載函數(shù)(返回 Promise)
  loader: () => import('./AsyncComp.vue'),

  // 2. 加載中顯示的組件(可選)
  loadingComponent: LoadingComp,
  // 延遲顯示加載組件(避免閃屏,默認(rèn) 200ms)
  delay: 200,

  // 3. 加載失敗顯示的組件(可選)
  errorComponent: ErrorComp,
  // 加載失敗的重試邏輯(可選)
  onError: (err, retry, fail, attempts) => {
    // err:錯(cuò)誤信息
    // retry:重試加載的函數(shù)
    // fail:終止加載的函數(shù)
    // attempts:已重試次數(shù)
    if (attempts < 3) {
      // 重試 3 次
      setTimeout(retry, 1000)
    } else {
      // 超過 3 次則失敗
      fail()
    }
  },

  // 4. 超時(shí)時(shí)間(可選,毫秒)
  timeout: 5000, // 5 秒加載不完成則觸發(fā)失敗
})
</script>

配置項(xiàng)說明

配置項(xiàng)類型作用默認(rèn)值
loaderFunction動(dòng)態(tài)導(dǎo)入組件的函數(shù)(必須返回 Promise)-
loadingComponentComponent加載中顯示的兜底組件undefined
delayNumber延遲顯示加載組件的時(shí)間(避免閃屏)200
errorComponentComponent加載失敗顯示的兜底組件undefined
onErrorFunction加載失敗的回調(diào)(支持重試)undefined
timeoutNumber加載超時(shí)時(shí)間(超時(shí)觸發(fā)失?。?/td>Infinity

常見使用場景

1.結(jié)合動(dòng)態(tài)組件使用(按需切換加載)

異步組件 + 動(dòng)態(tài)組件 = 「切換時(shí)才加載組件代碼」,適合 Tab 標(biāo)簽頁等場景:

<template>
  <button @click="currentComp = AsyncTab1">標(biāo)簽1</button>
  <button @click="currentComp = AsyncTab2">標(biāo)簽2</button>
  
  <component :is="currentComp"></component>
</template>

<script setup>
import { ref, defineAsyncComponent } from 'vue'

// 定義多個(gè)異步組件
const AsyncTab1 = defineAsyncComponent(() => import('./Tab1.vue'))
const AsyncTab2 = defineAsyncComponent(() => import('./Tab2.vue'))

const currentComp = ref(AsyncTab1)
</script>

2.路由懶加載(最常用場景)

Vue Router 中結(jié)合異步組件實(shí)現(xiàn)路由級(jí)別的按需加載,是項(xiàng)目優(yōu)化的核心手段:

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { defineAsyncComponent } from 'vue'
import Loading from '@/components/Loading.vue'

// 路由懶加載(方式1:最簡)
const Home = () => import('@/views/Home.vue')

// 路由懶加載(方式2:帶配置)
const About = defineAsyncComponent({
  loader: () => import('@/views/About.vue'),
  loadingComponent: Loading,
  delay: 100
})

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ]
})

export default router

3. 條件渲染的異步組件

僅當(dāng)滿足條件時(shí)才加載組件,避免無用代碼加載:

<template>
  <button @click="showModal = true">打開彈窗</button>
  <!-- 彈窗顯示時(shí)才加載組件 -->
  <AsyncModal v-if="showModal" @close="showModal = false" />
</template>

<script setup>
import { ref, defineAsyncComponent } from 'vue'

const showModal = ref(false)
// 彈窗組件僅在需要時(shí)加載
const AsyncModal = defineAsyncComponent(() => import('./Modal.vue'))
</script>

原理補(bǔ)充

defineAsyncComponent 的核心邏輯是返回一個(gè)「包裝器組件」:

  • 1.包裝器組件先渲染 loadingComponent(延遲后);
  • 2.執(zhí)行 loader 函數(shù)加載真實(shí)組件;
  • 3.加載成功:替換為真實(shí)組件;
  • 4.加載失敗 / 超時(shí):渲染 errorComponent。

簡化版?zhèn)未a:

function defineAsyncComponent(options) {
  return {
    setup() {
      const state = ref('loading') // loading/success/error
      const component = ref(null)
      
      // 執(zhí)行加載
      options.loader()
        .then(comp => {
          component.value = comp.default
          state.value = 'success'
        })
        .catch(() => state.value = 'error')
      
      return { state, component }
    },
    render() {
      if (this.state === 'loading') return h(options.loadingComponent)
      if (this.state === 'error') return h(options.errorComponent)
      return h(this.component)
    }
  }
}

總結(jié)

1.核心語法defineAsyncComponent 包裹 import() 是異步組件的基礎(chǔ),支持最簡寫法和完整配置;

2.核心配置:重點(diǎn)掌握 loadingComponent/errorComponent/delay/timeout,處理加載狀態(tài);

3.核心場景:路由懶加載、動(dòng)態(tài)組件切換、條件渲染的非核心組件;

4.優(yōu)化原則:按需拆分、做好兜底、避免過度拆分。

5.簡單記:異步組件 = 按需加載 + 狀態(tài)兜底 + 體積優(yōu)化,是 Vue 項(xiàng)目性能優(yōu)化的 “標(biāo)配” 手段。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue中l(wèi)et that=this的作用及說明

    vue中l(wèi)et that=this的作用及說明

    這篇文章主要介紹了vue中l(wèi)et that=this的作用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue中英文切換實(shí)例代碼

    vue中英文切換實(shí)例代碼

    在本篇文章里小編給大家整理了關(guān)于vue中英文切換實(shí)例代碼,需要的朋友們學(xué)習(xí)參考下。
    2020-01-01
  • Vue中引入json的三種方式總結(jié)

    Vue中引入json的三種方式總結(jié)

    這篇文章主要介紹了Vue中引入json的三種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue如何設(shè)置定時(shí)器和清理定時(shí)器

    vue如何設(shè)置定時(shí)器和清理定時(shí)器

    這篇文章主要介紹了vue如何設(shè)置定時(shí)器和清理定時(shí)器,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 詳解VUE項(xiàng)目中安裝和使用vant組件

    詳解VUE項(xiàng)目中安裝和使用vant組件

    這篇文章主要介紹了VUE安裝和使用vant組件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Vue輸入框狀態(tài)切換&自動(dòng)獲取輸入框焦點(diǎn)的實(shí)現(xiàn)方法

    Vue輸入框狀態(tài)切換&自動(dòng)獲取輸入框焦點(diǎn)的實(shí)現(xiàn)方法

    這篇文章主要介紹了Vue輸入框狀態(tài)切換&自動(dòng)獲取輸入框焦點(diǎn)的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • Element Plus 菜單組件區(qū)別和用法最佳實(shí)踐

    Element Plus 菜單組件區(qū)別和用法最佳實(shí)踐

    本文介紹了ElementPlus中的菜單組件,包括el-menu、el-menu-item、el-sub-menu和el-menu-item-group的特性、用法以及最佳實(shí)踐,通過對(duì)比不同場景的使用指南,幫助開發(fā)者根據(jù)需求選擇合適的組件組合,構(gòu)建功能強(qiáng)大且用戶友好的菜單系統(tǒng),感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • vue使用Print.js打印頁面樣式不出現(xiàn)的解決

    vue使用Print.js打印頁面樣式不出現(xiàn)的解決

    這篇文章主要介紹了vue使用Print.js打印頁面樣式不出現(xiàn)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 寫給vue新手們的vue渲染頁面教程

    寫給vue新手們的vue渲染頁面教程

    這篇文章主要給大家分享了一個(gè)寫給vue新手看的vue渲染頁面教程,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,感興趣的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Vite 打包目錄結(jié)構(gòu)自定義配置小結(jié)

    Vite 打包目錄結(jié)構(gòu)自定義配置小結(jié)

    在Vite工程開發(fā)中,默認(rèn)打包后的dist目錄資源常集中在asset目錄下,不利于資源管理,本文基于Rollup配置原理,本文就來介紹一下通過Vite配置自定義打包目錄結(jié)構(gòu),感興趣的可以了解一下
    2025-08-08

最新評(píng)論

应用必备| 北宁市| 宽城| 德令哈市| 博白县| 威远县| 东港市| 达日县| 余庆县| 黑水县| 仁布县| 棋牌| 牡丹江市| 平度市| 贵定县| 彩票| 建水县| 简阳市| 铁岭县| 南宁市| 福州市| 灵寿县| 南通市| 博爱县| 高要市| 石城县| 芦山县| 桃园市| 大同市| 西乌珠穆沁旗| 清新县| 潜江市| 沂南县| 河北省| 庆云县| 竹北市| 宜城市| 神农架林区| 信阳市| 行唐县| 大理市|