【Vue知识点- No6.】动态组件、插槽、自定义指令、tabbar案例

动态组件、插槽、自定义指令

学习目标

1.能够了解组件进阶知识。
2.能够掌握自定义指令的创建和使用。
3.能够完成tabbar案例的开发。

1.组件进阶

1.0 动态组件

问题:如何切换2个组件,互斥的显示或者隐藏呢?
动态组件定义: 多个组件使用同一个挂载点,并动态切换。

需求: 完成一个注册功能页面, 2个按钮切换, 一个填写注册信息, 另一个填写用户简介信息。

效果如下:
动态组件

1.准备被切换的 - UserName.vue / UserInfo.vue 2个组件
2.引入到UseDynamic.vue注册
3.准备变量来承载要显示的"组件名"
4.设置挂载点<component>, 使用 is属性 来设置要显示哪个组件
5.点击按钮 – 修改comName变量里的"组件名"

  • UserName.vue / UserInfo.vue
<template>
	<div>
		<div>
			<span>用户名:</span>
			<input type="text">
		</div>
		<div>
			<span>密码:</span>
			<input type="password">
		</div>		
	</div>
</template>
  • 01_UseDynamic.vue
<template>
  <div>
      <button @click="comName = 'UserName'">账号密码填写</button>
      <button @click="comName = 'UserInfo'">个人信息填写</button>

      <p>下面显示注册组件-动态切换:</p>
      <div style="border: 1px solid red;">
      	<!--vue内置的组件component,可以动态的显示组件-->
          <component :is="comName"></component>
      </div>
  </div>
</template>

<script>
// 目标: 动态组件 - 切换组件显示
// 场景: 同一个挂载点要切换 不同组件 显示
// 1. 创建要被切换的组件 - 标签+样式
// 2. 引入到要展示的vue文件内, 注册
// 3. 变量-承载要显示的组件名
// 4. 设置挂载点<component :is="变量"></component>
// 5. 点击按钮-切换comName的值为要显示的组件名

import UserName from '../components/01/UserName'
import UserInfo from '../components/01/UserInfo'
export default {
   
    data(){
   
        return {
   
            comName: "UserName"
        }
    },
    components: {
   
        UserName,
        UserInfo
    }
}
</script>
  • 在App.vue - 引入01_UseDynamic.vue并使用显示:
<template>
	... 省略注册
</template>	
import UseDynamic from './views/01_UseDynamic'
export default {
   
	components: {
   
		UseDynamic
	}
}

总结: 1.如何使用动态组件?vue内置component组件, 配合is属性, 设置要显示的组件名字。
2.如何切换?改变is属性的值为要显示的组件名即可。

1.1 组件缓存

演示1: 可以先给UserName.vue和UserInfo.vue 注册created和destroyed生命周期事件, 观察创建和销毁过程。

注意: 组件切换会导致组件被频繁销毁和重新创建, 所以性能不高。

【解决】使用Vue内置的 keep-alive组件, 可以让包裹的组件保存在内存中不被销毁。

演示2: 使用keep-alive内置的vue组件, 让动态组件缓存而不是销毁。

  • 02_UseDynamic.vue
<div style="border: 1px solid red;">
    <!-- Vue内置keep-alive组件, 把包起来的组件缓存起来 -->
    <keep-alive>
        <component :is="comName"></component>
    </keep-alive>
</div>

总结: keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 而是触发激活和非激活的生命周期方法

1.2 激活和非激活

目标: 被缓存的组件不再创建和销毁, 而是激活和非激活。

补充2个新的生命周期方法:

  • activated – 激活时触发
  • deactivated – 失去激活状态触发

在这里插入图片描述

1.3 组件插槽

问题1:组件里的数据不确定时可以怎么做? 让组件在props里面定义一个变量,使用这个组件的时候分别传入不同的数据。
问题2:组件里的标签不确定时怎么办呢? vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽。
组件插槽: 用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容

插槽例子:
插槽例子
案例: 以前的折叠面板案例, 想要实现不同内容显示, 我们把折叠面板里的Pannel组件, 添加组件插槽的方式:
在这里插入图片描述
语法口诀:
1.组件内不确定的标签处用 <slot></slot> 占位。
2.使用此组件,<组件名>传入具体标签</组件名>

  • src/components/03/Pannel.vue - 插槽 <slot></slot> 的使用。
<template>
  <div>
    <!-- 按钮标题 -->
    <div class="title">
      <h4>芙蓉楼送辛渐</h4>
      <span class="btn" @click="isShow = !isShow">
        {
   {
    isShow ? "收起" : "展开" }}
      </span>
    </div>
    <!-- 下拉内容 -->
    <div class="container" v-show="isShow">
    	<slot>默认显示内容</slot>
    </div>
  </div>
</template>

<script>
export default {
   
  data() {
   
    return {
   
      isShow: false,
    };
  },
};
</script>

<style scoped>
h3 {
   
  text-align: center;
}

.title {
   
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: 1px solid #ccc;
  padding: 0 1em;
}

.title h4 {
   
  line-height: 2;
  margin: 0;
}

.container {
   
  border: 1px solid #ccc;
  padding: 0 1em;
}

.btn {
   
  /* 鼠标改成手的形状 */
  cursor: pointer;
}

img {
   
  width: 50%;
}
</style>
  • src/views/03_UserSlot.vue - 使用组件(原始代码)
<template>
  <div id="container">
    <div id="app">
      <h3>案例:折叠面板</h3>
    </div>
  </div>
</template>

<script>
export default {
   
};
</script>

<style>
#app {
   
  width: 400px;
  margin: 20px auto;
  background-color: #fff;
  border: 4px solid blueviolet;
  border-radius: 1em;
  box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
  padding: 1em 2em 2em;
}
</style>
  • src/views/03_UseSlot.vue - 组件插槽使用
<template>
  <div id="container">
    <div id="app">
      <h3>案例:折叠面板</h3>
      <Pannel>
          <img src="../assets/mm.gif" alt="">
          <span>我是内容</span>
      </Pannel>
      <Pannel>
          <p>寒雨连江夜入吴,</p>
          <p>平明送客楚山孤。</p>
          <p>洛阳亲友如相问,</p>
          <p>一片冰心在玉壶。</p>
      </Pannel>
      <Pannel></Pannel>
    </div>
  </div>
</template>

<script>
import Pannel from "../components/03/Pannel";
export default {
   
  components: {
   
    Pannel,
  },
}
</script>
  • src/App.vue
<template>
	<div>
		<UseSlot></UseSlot>
	</div>	
</template>
<script>
import UseSlot from './views/03_UseSlot'
export default {
   
	components: {
   
		UseSlot
	}
}

总结: 1.当组件内某一部分标签不确定时怎么办?用插槽技术。
2.插槽具体如何使用? ①先在组件内用slot占位。②使用组件时,用具体的标签插入。
3.插槽运行效果? 传入的标签会替换掉slot显示。

1.4 插槽默认内容

问题: 使用组件时,如果不给slot传标签怎么办?可否设置默认内容?
口诀: <slot> 内放置内容, 作为默认显示内容。
效果:不给组件传标签,slot内容原地显示。如果给组件内传标签,则slot整体被替换掉。

<slot>默认内容</slot>

1.5 具名插槽

场景: 多个slot需要区分。传入的标签可以分别派发给不同的slot位置。

要求: v-slot一般和template标签使用 (template是html5新出标签内容模板元素, 不会渲染到页面上, 一般被vue解析的内部标签)

  • components/04/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>
  • views/04_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>
      <Pannel>
        <template #title>
          <span style="color: red;">我是标题</span>
        </template>
        <template #content>
          <p>寒雨连江夜入吴,</p>
          <p>平明送客楚山孤。</p>
          <p>洛阳亲友如相问,</p>
          <p>一片冰心在玉壶。</p>
        </template>
      </Pannel>
    </div>
  </div>
</template
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值