简单介绍:
通过在组件中使用保留的component标签的is属性,可以使多个组件同时挂载到一个挂载点,并通过一定的逻辑操作进行挂载组件的切换,这个效果的应用场景一般是在网页中的手动轮播图或者单页面的切换效果
子组件的内容:
<template>
<div>
<component :is="comp"></component>
<button type="button" @click="change('A')">切换到A</button>
<button type="button" @click="change('B')">切换到B</button>
<button type="button" @click="change('C')">切换到C</button>
</div>
</template>
<script>
import comA from "@/components/comA";
import comB from "@/components/comB";
import comC from "@/components/comC";
export default {
name: "DynamicComponents",
data(){
return {
comp:'comA'
}
},
methods:{
change(value){
this.comp = 'com' + value
}
},
components:{
comA,
comB,
comC
}
}
</script>
<style scoped>
</style>
子组件的子组件:表示用来切换的组件
可以将切换的组件定义在子组件内部,但是此处为了方便展示逻辑操作所以将切换用的组件分离出来
<template>
<p>组件A</p>
</template>
<script>
export default {
name: "comA"
}
</script>
<style scoped>
</style>
<template>
<p>组件B</p>
</template>
<script>
export default {
name: "comA"
}
</script>
<style scoped>
</style>
<template>
<p>组件C</p>
</template>
<script>
export default {
name: "comA"
}
</script>
<style scoped>
</style>
App组件的内容:
<template>
<div id="app">
<DynamiComponents></DynamiComponents>
</div>
</template>
<script>
import DynamiComponents from "@/components/DynamiComponents";
export default {
name: 'App',
components: {
DynamiComponents
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
注意点:
值得注意的是,component的is属性要想实现动态切换的效果必须绑定v-bind属性,在切换的时候使用的是简单的字符串拼接成组件名的形式
简单案例:在了解了动态组件如何使用之后,做一个简单的案例
案例效果:
可以看到在点击到上方的按钮的时候,下方的卡片也显示出了不同的页面效果
子组件中的内容:
<template>
<div>
<div class="border_div">
<ul>
<li class="deep" v-for="(index,item) in items" :class="{active:item === value}" @click="change(item)" v-bind:key="item" >{{index.name}}</li>
</ul>
<div class="com_div">
<component :is="comp"></component>
</div>
</div>
</div>
</template>
<script>
import com0 from "@/components/comA";
import com1 from "@/components/comB";
import com2 from "@/components/comC";
export default {
name: "DynamicComponents",
data(){
return {
comp:'com0',
value:0,
items:[
{name:'Vue'},
{name:'HTML'},
{name:'JavaWeb'},
],
}
},
methods:{
change(index){
this.comp = 'com' + index
this.value = index
}
},
components:{
com0,
com1,
com2
}
}
</script>
<style scoped>
.border_div{
border: 1px solid red;
width: 440px;
height: 300px;
}
li{
float: left;
margin: 10px;
list-style: none;
width: 100px;
height: 50px;
display: inline-block;
line-height: 50px;
cursor: pointer;
}
/*在定义的时候,背景色需要定义在变换色的前面,因为后定义的属性会覆盖掉之前定义的属性,在变化颜色的时候,需要使变化的颜色覆盖掉之前的颜色*/
.deep{
background-color: red;
}
.active{
background-color: pink;
}
.com_div{
border: 1px solid red;
display: inline-block;
width: 400px;
height: 200px;
}
</style>
这次依旧选择单独定义卡片的子组件,方便观察逻辑操作和变化
<template>
<h1>Vue很好,我很喜欢</h1>
</template>
<script>
export default {
name: "comA"
}
</script>
<style scoped>
</style>
<template>
<h1>HTML也很好,我也非常喜欢</h1>
</template>
<script>
export default {
name: "comB"
}
</script>
<style scoped>
</style>
<template>
<h1>JavaWeb那就更好了,我真是太喜欢了</h1>
</template>
<script>
export default {
name: "comC"
}
</script>
<style scoped>
</style>
App组件中的内容:
<template>
<div id="app">
<DynamiComponents></DynamiComponents>
</div>
</template>
<script>
import DynamiComponents from "@/components/DynamiComponents";
export default {
name: 'App',
components: {
DynamiComponents
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
注意点:
值得注意的是在li标签中使用了很多的标签属性,包括但不限于,v-for,v-bind绑定类选择器,以及一些HTML相关的样式知识,算是一个比较综合的案例。其中有一个特性是当我们在变换选择的颜色的时候,需要先定义背景颜色,然后再定义选中时的颜色,做到选中时的颜色可以覆盖背景颜色。以及在实现背景颜色的切换的时候,“:class===value”这个判断的含义在于只有当序号和组件的编号完全一致的时候才会应用到样式,从而达到切换样式的效果