VUE3组件 (3) 关于 slot 插槽

前言

以下代码和内容的使用都是在setup中,未使用TS。

<script setup>
script>

VUE3组件 (1) 关于defineProps()

VUE3组件 (2) 关于defineEmits()

VUE3组件 (4) 关于 Provide Inject 依赖注入


插槽使用

标题插口

在组件中除了将数据值当作props传入组件。有时需要将 模版传入到组件中,就需要使用 slot 插槽。
直接上代码
父组件中:

<section>
   <SlotItem><p>this is bodyp>SlotItem> 
section>

子组件

 <section>
    <p>this is itemp>
    <slot>slot>
 section>

语法
在子组件中 使用 作为插槽的插口,父元素中的插槽内容将会渲染的位置。
上述代码最后会渲染成

 <section>
    <p>this is itemp>
    <p>this is bodyp>
 section>

插槽内容可以是任意合法的模板内容,包括文本、标签节点、自定义组件甚至是渲染函数的组件。
插槽内容可以是多层的

<section>
   <SlotItem>
	   <p>this is bodyp>
	   <customElement />
	   {{info}}
   SlotItem> 
section>
<script setup>
  import { CustomDiv } from '@/component/hElement';
  import SlotItem from './slotItem.vue';
  import { ref } from 'vue';
  const info = ref('this is text');
script>

渲染作用域

插槽内容无法访问子组件的数据,请牢记一条规则:

任何父组件模板中的东西都只被编译到父组件的作用域中。
而任何子组件模板中的东西都只被编译到子组件的作用域中。

解释
如果上述的 info 是定义在 SlotItem 中的变量,则在父组件中无法使用 {{info}} 的方式调用,即使是在插槽内容也不行。
只有在父组件中定义的变量才能在父组件使用。这点不会因为slot而改变。

默认内容

子组件

<section>    
    <slot>confirmslot>
section>

父组件中

<section>    
    <SlotItem>SlotItem>
section>

如上 如果在子组件中有插槽接口,但是在父组件中并没有传递插槽内容,则在渲染时,会将 confirm 渲染到页面上。
如果在父组件的插槽内容有值。

<SlotItem>CancelSlotItem>

则在渲染时,会将 Cancel 渲染到页面上。

具名插槽

当一个组件需要多个插槽内容(如不同的渲染位置,不同的渲染样式)时,需要使用到 具名插槽。 语法:v-slot 指令,对应简写 #
代码:
子组件中

<section>
    <p>this is itemp>
    <slot>slot>
    <slot name="title">slot>
    <slot name="body">slot>
section>

父组件中:

<section>
	<SlotItem>
      	<p>this is defaultp>
      	<template #title>this is titletemplate>
      	<template #body>
        	<p>this is bodyp>
      	template>
      	<p>this is default2p>
    SlotItem>
section>

在子组件中,还是使用slot 做为插口。只是在添加了 name 属性表示插槽名。并且在父组件中使用 template 来包裹插槽内容。关系为:
子中的 插槽接口接收
父中
同理 body 也是如此渲染。
所以上述代码最后会渲染成。

this is item
this is default1
this is default2
this is title
this is body

发现上述代码和父组件中的书写顺序并不一样?this is default2 位置为什么会到 title 插槽之前呢?
因为 当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非