前言
本人在项目中需要批量加载组件,使用到动态组件 component,以此记录。
component 元素
1、特殊的 is 属性:
- 被注册的组件名
- 导入的组件对象
<component :is="componentName"></component>
2、可创建一般HTML元素
<components is="h1">你好</components>
3、原生HTML元素的v-model 无效
v-model 无效,可以替换成属性或事件
<components is="input" v-model="content"></components> //无效
4、KeepAlive组件缓存组件状态
切换组件就不会被卸载
<template>
<div>
<button
v-for="(key, tab) in tabs"
:key="tab"
:class="['tab-button', { active: currentTab === tab }]"
@click="currentTab = tab"
>
{{ tab }}
</button>
<KeepAlive>
<components is="tabs[currentTab]"></components>
</KeepAlive>
</div>
</template>
<script>
import Home from './Home.vue'
import Posts from './Posts.vue'
import Archive from './Archive.vue'
export default{
name:'view',
data(){
return{
tabs : { Home: 'Home', Posts: 'Posts', Archive: 'Archive' },
currentTab : 'Home'
}
},
components:{
Home,Posts,Archive
}
}
</script>
批量加载图标组件
使用element plus图标为例
npm install @element-plus/icons-vue
1、不使用setup语法糖
<template>
<div style="display: flex;flex-wrap: wrap">
<div v-for="(key,name) in icons" :key="key" style="cursor: pointer;padding: 1rem">
<component :is="name" style="width: 2rem;height: 2rem">
</component>
</div>
</div>
</template>
<script>
// 批量使用element plus图标组件
import * as ElIcons from '@element-plus/icons-vue'
export default {
name: 'Icon',
props: {
iconName: String
},
components: {
...ElIcons
},
data() {
return {
icons: {}
}
},
created() {
this.getData()
},
methods: {
getData() {
for (const name in ElIcons) {
Reflect.set(this.icons, name, name)
}
},
}
}
</script>
2、使用setup语法糖
<template>
<div style="display: flex;flex-wrap: wrap">
<div v-for="(key,name) in icons" :key="key" style="cursor: pointer;padding: 1rem">
<component :is="name" style="width: 2rem;height: 2rem">
</component>
</div>
</div>
</template>
<script setup>
// 批量使用element plus图标组件
import * as ElIcons from '@element-plus/icons-vue'
import { ref, markRaw } from "vue";
let icons = markRaw({})
// 方法
const getData = () => {
for (const name in ElIcons) {
Reflect.set(icons, name, name)
}
}
getData()
</script>
扩展
在vue3中动态组件也可以是异步的,需要用defineAsyncComponent进行注册,有兴趣可以去了解下。