【Vue3.x】动态组件与KeepAlive的配合

动态组件


<component>,一个用于渲染动态组件或元素的载体。

<component> 是vue内置特殊元素,和<slot>一样属于模板语法。但它们并非真正的组件,同时在模板编译期间会被编译掉。因此,它们通常在模板中用小写字母书写。

<component>要完成动态组件,要配合is一起完成。要渲染的组件由

// `is`后面可以跟字符串或者组件
interface DynamicComponentProps {
  is: string | Component
}

这里要注意的是,使用组合式Api setup语法,只能给is传入组件。如果使用vue2的optionsApi写法是可以传入组件名的字符串的

动态组件与keepAlive组件

动态组件切换时,会进行组件的创建与销毁,影响性能。如果使用<keepAlive>组件将其包裹,可以进行优化性能。

以下案例是对动态组件完成一个动态tab页的需求(tab页切换,用于输入内容被缓存),使用KeepAlive对其进行性能优化和完成保留用户输入的需求,vue3中keepAlive的用法其实和vue2相似,可以参考vue2中的写法。

🚩【Vue2.x Vue3.x】keep-alive组件和:is

<template>
    <div>
        <h1>动态组件-缓存示例</h1>
        <button @click="change(item.name)" v-for="item in data">切换{{item.name}}组件</button>
        <KeepAlive :exclude="['input1']">
            <component :is="currentCom.comName"></component>
        </KeepAlive>
    </div>
</template>
<script setup lang='ts'>
import { ref, reactive, markRaw } from 'vue';
import input1 from "./input1.vue";  // input1组件为表单或任意输入框,以检验页面是否被缓存
import input2 from "./input2.vue";
import input3 from "./input3.vue";

interface Tabs {
    name: string,
    comName: any
}

type Com = Pick<Tabs, 'comName'>

// data为动态数据
// reactive会对组件也使用proxy代理,这是不必要且浪费性能的,控制台警告使用markRaw跳过代理以节省性能. 
const data = reactive<Tabs[]>([
    {
        name: '我是一号',
        comName: markRaw(input1)
    },
    {
        name: '我是二号',
        comName: markRaw(input2)
    },
    {
        name: '我是三号',
        comName: markRaw(input3)
    },
])

let currentCom = reactive<Com>({
    comName : data[0].comName
})


const change = (params:string): void => {
    currentCom.comName = data.find(item => item.name===params)?.comName
    console.log(currentCom.comName);    // 打印组件实例发现__v_skip: true 即为开启markRaw,会跳过proxy代理,失去响应式
}
</script>
posted @ 2022-10-05 22:40  wanglei1900  阅读(446)  评论(0编辑  收藏  举报