多个组件使用同一个挂载点,并动态切换,这就是动态组件。
内置component组件, 配合is属性, 设置要显示的组件名字
<template>
<div>
//点击不同的按钮显示不同的组件,通过改变组件名来实现
<button @click="comName = 'UserName'">账号密码填写</button>
<button @click="comName = 'UserInfo'">个人信息填写</button>
<p>下面显示注册组件-动态切换:</p>
<div style="border: 1px solid red;">
<component :is="comName"></component>
</div>
</div>
</template>
<script>
import UserName from '../components/01/UserName'
import UserInfo from '../components/01/UserInfo'
export default {
data(){
return {
comName: "UserName"
}
},
components: {
UserName,
UserInfo
}
}
</script>
组件切换会导致组件被频繁销毁和重新创建, 性能不高
使用Vue内置的keep-alive组件, 可以让包裹的组件保存在内存中不被销毁
keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 触发激活和非激活的生命周期方法
<div style="border: 1px solid red;">
<!-- Vue内置keep-alive组件, 把包起来的组件缓存起来 -->
<keep-alive>
<component :is="comName"></component>
</keep-alive>
</div>
vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽:通过 slot 标签(是在子组件中), 可以接收到写在组件标签内的内容
v-bind可以省略成: v-on: 可以省略成@ 那么v-slot: 可以简化成#
总结: slot的name属性起插槽名, 使用组件时, template配合#插槽名传入具体标签
插槽的使用
1.在组件内先用slot标签占位
2.使用组件时,传入具体标签插入
关于界面的显示注意:
1、如果子组件没有放slot标签,父组件中
中*不会显示在界面中;
2、如果子组件有放slot标签且有默认内容,
中有内容,则会显示组件和**;
没有内容,则显示组件的同时,加载
默认内容的默认内容。
//Pannel.vue - 留下具名slot
<template>
<div>
<!-- 按钮标题 -->
<div class="title">
<slot name="title"></slot>
<span class="btn" @click="isShow = !isShow">
{{ isShow ? "收起" : "展开" }}
</span>
</div>
<!-- 下拉内容 -->
<div class="container" v-show="isShow">
<slot name="content"></slot>//注意看这里,父组件使用时,的内容放在这里显示***************************************
</div>
</div>
</template>
//UseSlot.vue使用组件的位置
<template>
<div id="container">
<div id="app">
<h3>案例:折叠面板</h3>
<Pannel>
<template v-slot:title>//等同于
<h4>芙蓉楼送辛渐</h4>
</template>
<template v-slot:content>
<img src="../assets/mm.gif" alt="">
<span>我是内容</span>
</template>
</Pannel>
</div>
</div>
</template>
<script>
import Pannel from "../components/04/Pannel";//注意要导入组件并注册
export default {
components: {
Pannel,
},
};
</script>
默认内容
v-slot一般用跟template标签使用 (template是html5新出标签内容模板元素, 不会渲染到页面上, 一般被vue解析内部标签)
//Pannel.vue(子组件)
<template>
<div>
<!-- 按钮标题 -->
<div class="title">
<slot name="title"></slot>
<span class="btn" @click="isShow = !isShow">
{{ isShow ? "收起" : "展开" }}
</span>
</div>
<!-- 下拉内容 -->
<div class="container" v-show="isShow">
<slot name="content"></slot>
</div>
</div>
</template>
//UseSlot.vue(父组件)
<template>
<div id="container">
<div id="app">
<h3>案例:折叠面板</h3>
<Pannel>
<template #title>//将 中的内容放在 的位子显示
<span style="color: red;">我是标题</span>
</template>
<template #content>
//将 放在 的位子
//注意************:如果子组件没有 ,则 整段内容不显示,因为没有插槽位子
<p>寒雨连江夜入吴,</p>
<p>平明送客楚山孤。</p>
<p>洛阳亲友如相问,</p>
<p>一片冰心在玉壶。</p>
</template>
</Pannel>
</div>
</div>
</template>
<script>
import Pannel from "../components/04/Pannel";
export default {
components: {
Pannel,
},
};
</script>
{{ scope.row.defaultTwo }}
//记住是 scope.row.defaultTwo不是 scope.defaultTwo
//Pannel.vue - 定义组件, 和具名插槽, 给slot绑定属性和值
<template>
<div>
<!-- 按钮标题 -->
<div class="title">
<h4>芙蓉楼送辛渐</h4>
</div>
<!-- 下拉内容 -->
<div class="container" v-show="isShow">
<slot :row="defaultObj">{{ defaultObj.defaultOne }}</slot>
</div>
</div>
</template>
<script>
// 目标: 作用域插槽
// 场景: 使用插槽, 使用组件内的变量
// 1. slot标签, 自定义属性和内变量关联:案例中row绑定了defaultObj的数据
// 2. 使用组件, template配合v-slot="变量名",scope接受了子组件插槽中 row的数据
// 变量名会收集slot身上属性和值形成对象
export default {
data() {
return {
isShow: false,
defaultObj: {
defaultOne: "无名氏",
defaultTwo: "小传同学"
}
};
},
};
</script>
//UseSlot.vue父组件
<template>
<div id="container">
<div id="app">
<h3>案例:折叠面板</h3>
<Pannel>
<!-- 需求: 插槽时, 使用组件内变量 -->
<!--********* scope变量: {row: defaultObj} ,显示的结果是<p>{{ scope.row.defaultTwo }}</p>而不是子组件的默认内容-->
<template v-slot="scope"> //scope接受了子组件插槽中 row的数据
<p>{{ scope.row.defaultTwo }}</p>
</template>
</Pannel>
</div>
</div>
</template>
<script>
import Pannel from "../components/05/Pannel";
export default {
components: {
Pannel,
},
};
</script>