Vue 插槽slot

5 篇文章 0 订阅

在 vue 中,组件化是极其重要的特征,我们使用不同的组件来实现页面。但是也会经常需要将父组件的内容分发到子组件,这就需要用到slot(插槽);

 

// 父组件
<father>this is slot content</father>

// 子组件
<a>
    <slot></slot>
</a>

这样父组件中的内容就会默认插入到slot标签中。

 

1.slot的默认值

 

我们可以设置slot 的默认值。当父级组件中使用这个组件不提供任何插槽内容时,子组件便会显示slot的默认值

 

// 定义一个带默认solt的组件<submit-button>
<button type="submit">
  <slot>Submit</slot>
</button>

// 当我们使用这个组件并且不提供和任何插槽内容时
// 父组件
<submit-button></submit-button>

// 默认内容就会被渲染
<button type="submit">
  Submit
</button>

// 当我们提供插槽内容时
// 父组件
<submit-button>
  Save
</submit-button>

// 插槽的默认内容会被替换
<button type="submit">
  Save
</button>

2.slot 的 name(具名插槽)

 

当我们需要多个 slot 时,子级组件的 slot 标签中有 name 属性定义了该插槽的名字,我们可以在父级组件中通过 v-slot(简写为#)来定义该 slot 内容或插入到哪个 slot 标签中(或者通过 slot 属性来标明该内容应该被插入到哪里,该语法自2.6.0之后被废弃)。自己组件中没有定义 name 属性的 slot 标签的 name 值默认为 default 。

// 父级组件,可以通过 template 标签来包裹代码块
<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

// 子级组件<base-layout>;通过 name 属性定义 slot 标签的名字
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

 

3.父级组件获取子级组件的值(作用域插槽)

 

如果我们想在父级组件里面获取子级组件里面的值,就得用到作用域插槽

        1.最初级用法

 

// 子级组件<current-user>
<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

// 父级组件
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>
  • 我们在子级组件的 slot 标签中通过 v-bind(简写为:)绑定了子级组件中的 user ,传递给父级组件;
  • 在父级组件中,通过 v-slot 指令获取到子级组件里绑定的 user ;
  • 父级组件中 v-slot 指令只能用在 component 的根标签或者是将插槽的所有内容应 tamplate 标签包裹后放在 tamplate 标签中;
  • 父级组件中 v-slot 指令的 arg(参数,上面的例子中的就是 default ),和子级组件中的 slot 名称意义对应,上面的例子中子级组件的 slot 默认是 default ,所以子级组件中的 v-slot 的参数也是 default ;
  • 当 arg 不是 default 时,可以用#来简写 v-slot ;
  • 父级组件中的 v-slot 指令的 value(上面例子中的 slotProps )就是包含所有插槽 prop 的对象,可以通过该对象拿到你想传递过来的子级组件的值;

         2.升级用法

// 子组件
<span>
  <slot :user="user" name="foo"></slot>
  <slot :user="user" name="boo"></slot>
</span>

// 父组件
<current-user>
  <template #foo="slotProps">
    {{ slotProps.user.firstName }}
  </template>
  <template #boo="slotProps">
    {{ slotProps.user.lastName }}
  </template>
</current-user>

 

 

  • 子级组件中,我们通过 name 属性命名不同的 slot 标签;
  • 父级组件中,通过 v-slot(上面例子中用#简写)的 arg 来指定不同的 name ,从而指定该 slot 的内容在子级组件的位置;

        3.注意事项(默认插槽的写法)

  • 只有当父级组件提供的内容只有默认插槽时,才可以将v-slot指令直接用在组件的标签上
<current-user v-slot:default="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

// 上面的default可以省略,就是默认插槽的写法
<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

 

 

  • 默认插槽的写法不能和具名插槽混用,这回导致作用域不明确
<!-- 无效,会导致警告 -->
<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
  <template v-slot:other="otherSlotProps">
    slotProps is NOT available here
  </template>
</current-user>
  • 出现多个插槽时,请始终为所有的插槽用 tampalte 标签包裹;
<current-user>
  <template #foo="slotProps">
    {{ slotProps.user.firstName }}
  </template>
  <template #boo="slotProps">
    {{ slotProps.user.lastName }}
  </template>
</current-user>

        4.作用域插槽的解构

 

<current-user>
  <template v-slot="{ user }">
    {{ user.firstName }}
  </template>
</current-user>

        5.具名插槽的缩写

 

  • "v-slot:" 可以被简写为 "#"
// v-slot:header 可以被重写为 #header
<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>
  <template #footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
  • 和其他指令一样,缩写必须是得有参数的时候才可用。以下的写法无效

<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
  {{ user.firstName }}
</current-user>

<!-- 有效 -->
<current-user #default="{ user }">
  {{ user.firstName }}
</current-user>

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值