component
是vue内置组件,主要作用为动态渲染组件,基本用法如下:
<!-- 动态组件由 vm 实例的 `componentName` property 控制 -->
<component :is="componentName"></component>
其中,根据绑定的is
的值决定拿个组件被渲染。
通过动态组件的属性,除了基本的组件动态渲染以外,我们常将其用作与动态组件的切换,示例如下:
代码如下:
主页面index.vue:
<template>
<div>
<title-bar :title="title" @goBack="goback"></title-bar>
<div id="dynamic-component-demo" class="demo">
<button
v-for="tab in tabs"
:key="tab"
:class="['tab-button', { active: currentTab === tab }]"
@click="currentTab = tab"
>
{{ tab }}
</button>
<component
:is="currentTabComponent"
class="tab"
:data="propsData"
:dataA="propsDataA"
:dataB="propsDataB"
></component>
</div>
</div>
</template>
<script>
import TitleBar from "@/components/TitleBar";
import comA from "./components/comA";
import comB from "./components/comB";
export default {
name: "",
components: {
TitleBar,
comA,
comB
},
data() {
return {
title: "动态组件",
currentTab: "comA",
tabs: ["comA", "comB"],
propsData: "send data",
propsDataA: "comA send data",
propsDataB: "comB send data"
};
},
created() {
setTimeout(() => {
this.showComponent = "comA";
this.changeCom();
}, 1000);
},
computed: {
currentTabComponent() {
return this.currentTab;
}
},
methods: {
// 返回方法
goback() {
// this.$emit("GoBack");
}
}
};
</script>
<style scoped>
.demo {
font-family: sans-serif;
border: 1px solid #eee;
border-radius: 2px;
padding: 20px 30px;
margin-top: 1em;
margin-bottom: 40px;
user-select: none;
overflow-x: auto;
}
.tab-button {
padding: 6px 10px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border: 1px solid #ccc;
cursor: pointer;
background: #f0f0f0;
margin-bottom: -1px;
margin-right: -1px;
}
.tab-button:hover {
background: #e0e0e0;
}
.tab-button.active {
background: #e0e0e0;
}
.demo-tab {
border: 1px solid #ccc;
padding: 10px;
}
.tab {
margin: 20px auto;
}
</style>
组件A:
<template>
<div class="box">BOX Adiv>
template>
<style scoped>
.box {
height: 100px;
width: 100px;
background: #2a5caa;
color: #fff;
}
style>
组件B:
<template>
<div class="box">BOX B {{ data }} : {{ dataB }}</div>
</template>
<script>
export default {
props: {
data: {
type: String
},
dataB: {
type: String
}
}
};
</script>
<style scoped>
.box {
height: 100px;
width: 100px;
background: #4d4f36;
color: #fff;
}
</style>
动态组件的传值遵循基本组件传值规则,除了支持v-bind
传值以外,还支持ref
引用传值;使用引用传值需要注意的是,需要确定组件之后,再使用ref属性进行传值,否则将会无法获取应用组件的属性。使用v-bind
传值代码如上所示:
<component
:is="currentTabComponent"
class="tab"
:data="propsData"
:dataA="propsDataA"
:dataB="propsDataB"
>component>
在2.1中,若是数据需要动态渲染,组件切换之后会导致之前获得的数据丢失,这个时候,若我们想要在组件切换过程中保持这些组件的状态,以避免重复渲染导致性能问题,则可以在动态组件上使用keep-alive
来缓存组件中的数据,代码如下所示:
<template>
<div>
<title-bar :title="title" @goBack="goback">title-bar>
<component :is="showComponent">component>
<div id="dynamic-component-demo" class="demo">
<button
v-for="tab in tabs"
:key="tab"
:class="['tab-button', { active: currentTab === tab }]"
@click="currentTab = tab"
>
{{ tab }}
button>
<keep-alive>
<component
:is="currentTabComponent"
class="tab"
>component>
keep-alive>
div>
div>
template>
这样一来,我们就可以实现多个组件切换时缓存组件数据的效果了;更多关于keep-alive
的使用方法详见:vue3项目keepAlive使用方法详解