vue动态组件和插槽的使用

本文介绍了如何在Vue应用中实现注册功能页面的动态组件切换,包括UserName和UserInfo组件,并探讨了如何利用keep-alive组件提升性能,避免组件频繁销毁和重建的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求: 完成一个注册功能页面, 2个按钮切换, 额外封装两个组件:一个填写注册信息, 一个填写用户简介信息

目标: 多个组件使用同一个挂载点,并可以动态切换,这就是动态组件

目录结构

根组件
├── App.vue
└── components
    ├── UserName.vue # 用户名和密码输入框
    └── UserInfo.vue # 人生格言和自我介绍框

格式

<component :is="comName"></component> 

UserName.vue

<template>
  <div>
    <h2>UserName</h2>
    <p>用户名:<input /> </p>
    <p>密码:<textarea /> </p>
  </div>
</template>

<script>
export default {

}
</script>

UserInfo.vue 

<template>
  <div>
    <h2>UserInfo</h2>
    <p>人生格言:<input /> </p>
    <p>自我介绍:<textarea /> </p>
  </div>
</template>

<script>
export default {

}
</script>

 在父组件App.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>
import UserName from "./UserName";
import UserInfo from "./UserInfo";
export default {
  data() {
    return {
      comName: "UserName",
    };
  },
  components: {
    UserName,
    UserInfo,
  },
};
</script>

注意 

  • is只能是动态属性 => :is="组件注册后的标签名字符串或data变量"
  • 不能直接拿注册标签名赋值使用

 组件进阶-keep-alive组件

背景

组件切换会导致组件被频繁销毁和重新创建, 大多数情况下是有自己的意义的,但也可能会导致不必要的性能损耗

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

keep-alive

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

格式

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

补充生命周期:

  • activated - 激活
  • deactivated - 失去激活状态
<keep-alive>
    <!-- vue内置的组件component, 可以动态显示组件 -->
    <component :is="comName"></component>
</keep-alive>

好处 

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

组件进阶-keep-alive组件-指定缓存

目标

掌握keep-alive的include属性的用法

语法

  1. include="组件名1,组件名2..."
  2. :include="['组件名1', '组件名2']"
<keep-alive include="name1,name2">
    <!-- vue内置的组件component, 可以动态显示组件 -->
    <component :is="comName"></component>
</keep-alive>

注意:

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)

 组件进阶 - 默认插槽

vue中的插槽

  1. 组件通过插槽传入自定义结构
  2. 用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容
  3. vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽

格式
在定义组件时,在template中用slot来占个坑;
使用时,将组件之间的内容来填坑;

组件进阶-具名插槽

目标

掌握具名插槽的使用

背景

当一个组件内有2处以上需要外部传入标签的地方

格式

定义: <slot name="xxx">

使用:

  • <template #xxx></template>;
  • <template v-slot:xxx></template>

 

 注意 :

  1. 传入的标签可以分别派发给不同的slot位置
  2. v-slot一般跟template标签使用 (template是html5新出标签内容模板元素, 不会渲染到页面上, 一般被vue解析为内部标签)

子组件:

<div class="container" v-show="isShow">
    <slot name="one"></slot>
    <slot name="two"></slot>
</div>

 

父组件

v-slot可以简化成 # 使用

v-bind可以省略成:    

v-on: 可以省略成@  

v-slot: 可以简化成#

方式一 :

<Pannel2>
    <template v-slot:one>
		<img src="../assets/mm.gif" alt="" />
    </template>
    <template v-slot:two>
		<span>我是文字哦</span>
    </template>
</Pannel2>

 方式二 :

<Pannel2>
    <!-- 简化写法 -->
    <template #one>
		<div>
            <p>纵有相思入骨</p>
        </div>
    </template>
    <template #two>
		<img src="../assets/mm.gif" alt="" />
    </template>
</Pannel2>

注意 : 

  1. slot有可以设置多个
  2. 定义组件时:slot的name属性起插槽名
  3. 使用组件时, template配合#插槽名传入具体html标签或组件

组件进阶-作用域插槽 

目标 : 

 子组件中的数据, 在给插槽赋值时在父组件环境下使用=> 子传父=>传数据

步骤 : 

  • 创建子组件, 准备slot, 在slot上绑定属性和子组件值
  • 使用子组件, 传入自定义标签, 用template和v-slot="自定义变量名"
  • 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置

子组件

<template>
  <div style="border:1px solid #ccc; margin:5px;padding:5px">
    <h2>子组件</h2>
    <!-- 给slot上补充自定义的属性 -->
    <slot name="content" :a="1" :b="2">
      默认内容
    </slot>
  </div>
</template>

<script>
export default {
}
</script>

父组件

<template>
  <div style="border:1px solid #ccc; margin:5px;padding:5px">
    <h1>45-插槽-作用域插槽</h1>

    <MyCom>
      <!-- 
        v-slot:插槽名="对象" 
      对象会自动接收这个插槽传递回来自定义属性
      -->
      <template v-slot:content="scope">
        <!-- <h1>自定义的内容,填坑, {{scope}}</h1> -->
        <h3>{{scope.a}}</h3>
        <p>{{scope.b}}</p>
      </template>
    </MyCom>
  </div>
</template>

<script>

// 父传子
//  1.传数据。 自定义属性    (父)  props(子)
//  2.传结构。 在组件中写内容(父)  slot (子)

import MyCom from './MyCom.vue'
export default {
  components: { MyCom }
}
</script>

<style scoped>
.content{
background-color: #ccc;
}
</style>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值