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

vue3使用keep-alive組件,包含動態(tài)組件使用詳解

 更新時間:2026年04月29日 10:50:25   作者:anjushi_  
文章主要講解了Vue3中使用keep-alive組件時需要注意的問題,包括動態(tài)組件使用、性能優(yōu)化建議以及路由級別的keep-alive實(shí)現(xiàn)方法,強(qiáng)調(diào)了keep-alive內(nèi)不要使用注釋,使用markRaw或shallowRef避免不必要的性能開銷,并舉例說明了如何正確使用keep-alive實(shí)現(xiàn)頁面部分刷新

vue3使用keep-alive組件,包含動態(tài)組件使用

組件不使用keep-alive

  • Father
<template>
  <div>
    Father
    <el-button @click="tabChange">change page</el-button>
    <Child :msg="cutTab" v-if="cutTab"></Child>
    <Child2 :msg="cutTab" v-else></Child2>
  </div>
</template>

<script setup lang="ts" name="Father">
const cutTab = ref(false);

const tabChange = () => {
  cutTab.value = !cutTab.value;
}
</script>
  • Child
<template>
  <div class="c1">
    Child +
    {{ props.msg }}
    <el-input v-model="input" placeholder="Please input" />
  </div>
</template>

<script setup lang="ts" name="Child">
const props = defineProps({
  msg: {
    type: Boolean,
    default: false,
  },
})
const input = ref('')
</script>
  • Child2
<template>
  <div class="c2">
    Child2 +
    {{ props.msg }}
    <el-input v-model="input" placeholder="Please input" />
  </div>
</template>

<script setup lang="ts" name="Child2">
const props = defineProps({
  msg: {
    type: Boolean,
    default: false,
  },
})
const input = ref('')
</script>

組件中使用

  • include:包含
  • exclude:排除

v-if切換

    <keep-alive>
      <Child :msg="cutTab" v-if="cutTab"></Child>
      <Child2 :msg="cutTab" v-else></Child2>
    </keep-alive>
    <keep-alive include="Child2">
      <Child :msg="cutTab" v-if="cutTab"></Child>
      <Child2 :msg="cutTab" v-else></Child2>
    </keep-alive>

component動態(tài)組件切換

因注釋導(dǎo)致的意外錯誤

<KeepAlive> expects exactly one child component

    <keep-alive include="Child2">
      <!-- <Child :msg="cutTab" v-if="cutTab"></Child>
      <Child2 :msg="cutTab" v-else></Child2> -->
      <component :is="com"></component>
    </keep-alive>

keep-alive組件內(nèi)不要使用注釋,會被解析為子節(jié)點(diǎn)

  • 添加div進(jìn)行包裹
    <keep-alive include="Child2">
      <div>
        <!-- <Child :msg="cutTab" v-if="cutTab"></Child>
        <Child2 :msg="cutTab" v-else></Child2> -->
        <component :is="com"></component>s
      </div>
    </keep-alive>
  • 移除注釋
    <keep-alive include="Child2">
      <component :is="com"></component>
    </keep-alive>

動態(tài)組件的使用

[Vue warn]: Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with 'markRaw' or using 'shallowRef' instead of 'ref'.

在 Vue 3 中,如果用 ref 或 reactive 將一個組件包裝成響應(yīng)式對象,可能會引發(fā)不必要的性能開銷。因?yàn)檫@會使 Vue 嘗試去追蹤組件的變化,而實(shí)際上組件實(shí)例并不需要被追蹤。組件本身不應(yīng)該是響應(yīng)式的,只有它的 props 和 state 才應(yīng)該是響應(yīng)式的。

所以,當(dāng)需要引用一個組件時,應(yīng)該使用 shallowRef或者 markRaw,這樣可以避免將整個組件變成響應(yīng)式的,只會跟蹤引用的變化

  • 使用markRaw
const com = ref(markRaw(Child2));

const comChange = () => {
  if(com.value === Child2){
    com.value = markRaw(Child);
  }else{
    com.value = markRaw(Child2);
  }
}
  • 使用shallowRef
const com = shallowRef(Child2);

const comChange = () => {
  if(com.value === Child2){
    com.value = Child;
  }else{
    com.value = Child2;
  }
}

完整示例

<template>
  <div>
    Father
    <el-button @click="comChange">change component</el-button>
    <keep-alive include="Child2">
      <component :is="com"></component>
    </keep-alive>
  </div>
</template>

<script setup lang="ts" name="Father">
import Child from "@/views/Child.vue";
import Child2 from "@/views/Child2.vue";

const cutTab = ref(false);
const com = ref(markRaw(Child2));

const comChange = () => {
  if(com.value === Child2){
    com.value = markRaw(Child);
  }else{
    com.value = markRaw(Child2);
  }
}

</script>

可以看到只有Child2組件是有緩存的,Child是有銷毀和生成的

路由不使用keep-alive

  • 組件
<template>
  <div>
    Father
    <div class="nav">
      <router-link to="/Father/Child">去Child頁面</router-link>
      <el-divider direction="vertical" />
      <router-link to="/Father/Child2">去Child2頁面</router-link>
    </div>
    <router-view></router-view>
  </div>
</template>
  • 路由index.ts
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'

const routes = [
  {
    path: '/Father',
    name: 'Father',
    component: () => import('@/views/Father.vue'),
    children: [
      {
        path: 'Child',
        name: 'Child',
        component: () => import('@/views/Child.vue'),
      },
      {
        path: 'Child2',
        name: 'Child2',
        component: () => import('@/views/Child2.vue'),
      }
    ],
  }, 
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

路由中使用

Vue Router 4(與 Vue 3 配套的路由庫)引入了一個新的 API 來實(shí)現(xiàn)路由級別的 <keep-alive>。這就是 <router-view> 組件的 v-slot API

  • 需要注意的是v-if不要加在keep-alive上,會直接銷毀keep-alive,需要加在component
  • 實(shí)現(xiàn)頁面部分刷新,頁面進(jìn)入時執(zhí)行的生命周期為:created->mounted->activated
<template>
  <div>
    Father
    <div class="nav">
      <router-link to="/Father/Child">去Child頁面</router-link>
      <el-divider direction="vertical" />
      <router-link to="/Father/Child2">去Child2頁面</router-link>
    </div>
    <router-view v-slot="{ Component }">
      <keep-alive >
        <component :is="Component" v-if="$route.meta.keepAlive"/>
      </keep-alive>
      <component :is="Component" v-if="!$route.meta.keepAlive"/>
    </router-view>
  </div>
</template>

路由index.ts

在對應(yīng)的路由上添加meta屬性來設(shè)置頁面是否要使用緩存

...
const routes = [
  {
    path: '/Father',
    name: 'Father',
    component: () => import('@/views/Father.vue'),
    children: [
      {
        path: 'Child',
        name: 'Child',
        component: () => import('@/views/Child.vue'),
      },
      {
        path: 'Child2',
        name: 'Child2',
        meta: {
          keepAlive: true,  // 需要被keep-alive
        },
        component: () => import('@/views/Child2.vue'),
      }
    ],
  }, 
]
...

keep-alive生命周期

keep-alive組件會多出兩個生命周期,分別在mounted之后和unMounted之前

onActivated(() => {
  console.log('Component is activated')
})

onDeactivated(() => {
  console.log('Component is deactivated')
})

總結(jié)

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

相關(guān)文章

  • vue3?hook自動導(dǎo)入原理及使用

    vue3?hook自動導(dǎo)入原理及使用

    最近學(xué)習(xí)了hooks,特地寫一篇文章加深一下印象,下面這篇文章主要給大家介紹了關(guān)于vue3?hook自動導(dǎo)入原理及使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • vue3實(shí)現(xiàn)高德地圖天氣小組件

    vue3實(shí)現(xiàn)高德地圖天氣小組件

    這篇文章主要為大家詳細(xì)介紹了如何使用vue3實(shí)現(xiàn)一個高德地圖天氣小組件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-10-10
  • ant-design-vue按需加載的坑的解決

    ant-design-vue按需加載的坑的解決

    這篇文章主要介紹了ant-design-vue按需加載的坑的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • vite項目的根目錄中的env.d.ts類型聲明文件里要寫什么

    vite項目的根目錄中的env.d.ts類型聲明文件里要寫什么

    這篇文章主要介紹了vite項目的根目錄中的env.d.ts類型聲明文件里要寫什么,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 使用Vue與Firebase構(gòu)建實(shí)時聊天應(yīng)用的示例代碼

    使用Vue與Firebase構(gòu)建實(shí)時聊天應(yīng)用的示例代碼

    隨著互聯(lián)網(wǎng)通訊技術(shù)的不斷進(jìn)步,實(shí)時聊天應(yīng)用現(xiàn)在已成為我們?nèi)粘I钪胁豢苫蛉钡囊徊糠?無論是社交媒體平臺、工作溝通工具還是客戶支持系統(tǒng),實(shí)時聊天都在不斷被需求,今天,我們將介紹如何使用Vue.js與Firebase來構(gòu)建一個簡單而強(qiáng)大的實(shí)時聊天應(yīng)用,需要的朋友可以參考下
    2024-11-11
  • 如何使用el-table+el-tree+el-select動態(tài)選擇對應(yīng)值

    如何使用el-table+el-tree+el-select動態(tài)選擇對應(yīng)值

    小編在做需求時,遇到了在el-table表格中加入多條數(shù)據(jù),并且每條數(shù)據(jù)要通過el-select來選取相應(yīng)的值,做到動態(tài)選擇,下面這篇文章主要給大家介紹了關(guān)于如何使用el-table+el-tree+el-select動態(tài)選擇對應(yīng)值的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • 一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對象觀測)

    一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對象觀測)

    這篇文章主要介紹了一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對象觀測),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • vue中實(shí)現(xiàn)div可編輯并插入指定元素與樣式

    vue中實(shí)現(xiàn)div可編輯并插入指定元素與樣式

    這篇文章主要給大家介紹了關(guān)于vue中實(shí)現(xiàn)div可編輯并插入指定元素與樣式的相關(guān)資料,文中通過代碼以及圖文將實(shí)現(xiàn)的方法介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用vue具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • vue自定義密碼輸入框解決瀏覽器自動填充密碼的問題(最新方法)

    vue自定義密碼輸入框解決瀏覽器自動填充密碼的問題(最新方法)

    這篇文章主要介紹了vue自定義密碼輸入框解決瀏覽器自動填充密碼的問題,通過將密碼輸入框的type設(shè)置為text,修改樣式上的顯示,來實(shí)現(xiàn)既可以讓瀏覽器不自動填充密碼,又可以隱藏密碼的效果,需要的朋友可以參考下
    2023-04-04
  • vuejs實(shí)現(xiàn)折疊面板展開收縮動畫效果

    vuejs實(shí)現(xiàn)折疊面板展開收縮動畫效果

    這篇文章主要介紹了vuejs實(shí)現(xiàn)折疊面板展開收縮動畫效果,文中通過代碼給大家分享兩種情況介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-09-09

最新評論

马边| 将乐县| 秭归县| 南涧| 陇西县| 永和县| 定南县| 嘉祥县| 都安| 石阡县| 上高县| 龙井市| 高青县| 拜泉县| 博湖县| 黄梅县| 藁城市| 西畴县| 涟水县| 东乡县| 攀枝花市| 鸡西市| 沁水县| 青田县| 慈利县| 申扎县| 荃湾区| 南投县| 泸水县| 青川县| 樟树市| 灵川县| 普安县| 仙桃市| 南宫市| 安岳县| 泗水县| 永寿县| 孝昌县| 泽普县| 虞城县|