vue 插槽

一、什么是插槽

插槽(slot)是 vue 为 组件的封装者 提供的能力。允许开发者在封装组件时,把 不确定的希望由用户指定的部分 定义为插槽。
可以把插槽认为是组件封装期间,为用户预留的 内容的占位符

二、插槽分类

1. 默认插槽

vue 官方规定:每一个 slot 插槽,都要有一个 name 名称,如果省略了 slot 的 name 属性,则有一个默认名称叫做 default

子组件中:

<template>
  <div>
    <h1>分类名称</h1>
    <slot>插槽默认内容...</slot>
  </div>
</template>

父组件中:

<template>
  <div>
    <my-category>
      <ul>
        <li
          v-for="(item, index) in 10"
          :key="index"
        >分类{{ item }}</li>
      </ul>
    </my-category>
  </div>
</template>
注意事项
  1. 没有预留插槽的内容会被丢弃(也就是说子组件中未提供插槽,而父组件在使用插槽时无效)
  2. 如果组件的使用者没有为插槽提供任何内容,则 slot 标签中的内容会默认展示

2. 具名插槽

如果在封装组件时需要预留多个插槽节点,则需要为每个插槽 slot 指定具体的 name 名称。这种带有具体名称的插槽叫做 具名插槽

子组件中:

<template>
  <div>
    <!-- 头部 -->
    <header>
      <slot name="header"></slot>
    </header>

    <!-- 主体 -->
    <main>
      <slot name="main"></slot>
    </main>

    <slot></slot>

    <!-- 页脚 -->
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

父组件中:

<template>
  <div>
    <my-layout>
      <!-- 新推出的语法 -->
      <template v-slot:header>页头</template>

      <!-- v-slot: 的简写方式 -->
      <template #main>主体</template>

      <div slot="footer">页脚</div>

      <template #default>
        <h1>默认插槽</h1>
      </template>
    </my-layout>
  </div>
</template>
注意事项
  1. 没有指定 name 名称的插槽,会有隐含的名称叫做 default
  2. v-slot: 只能使用在 template 标签上,注意 v-slot: 后不需要加引号
  3. # 后面加插槽名称,是 v-slot: 的简写方式,类似于事件绑定(v-on = @),规则与 v-slot: 一样
  4. slot="" 可以使用在 template 或 其他标签上

3. 作用域插槽

数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。

子组件中:

<template>
  <div>
    <slot :title="title" :list="list"></slot>

    <slot name="content" :content="content"></slot>
  </div>
</template>

<script>
export default {
  name: 'MyCategory',
  data() {
    return {
      title: '美食分类',
      list: [
        {
          id: 1,
          name: '分类1'
        },
        {
          id: 2,
          name: '分类2'
        },
        {
          id: 3,
          name: '分类3'
        },
      ],
      content: '美食简介内容...'
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

父组件中:

<template>
  <div>
    <my-category>
      <template scope="category">
        <h1>{{ category.title }}</h1>
        <ul>
          <li
            v-for="item in category.list"
            :key="item.id"
          >{{ item.name }}</li>
        </ul>
      </template>
    </my-category>
    <my-category>
      <template #default="category">
        <h1>{{ category.title }}</h1>
        <ul>
          <li
            v-for="item in category.list"
            :key="item.id"
          >{{ item.name }}</li>
        </ul>
      </template>
    </my-category>

    <!-- 可以使用更简洁的结构赋值语法 -->
    <my-category>
      <template scope="{list, title}">
        <h1>{{ title }}</h1>
        <ol>
          <li
            v-for="item in list"
            :key="item.id"
          >{{ item.name }}</li>
        </ol>
      </template>
    </my-category>
    <my-category>
      <template #default="{list, title}">
        <h1>{{ title }}</h1>
        <ol>
          <li
            v-for="item in list"
            :key="item.id"
          >{{ item.name }}</li>
        </ol>
      </template>
    </my-category>

    <!-- 新推出的语法 -->
    <my-category>
      <template slot-scope="{list, title}">
        <h1>{{ title }}</h1>
        <ol>
          <li
            v-for="item in list"
            :key="item.id"
          >{{ item.name }}</li>
        </ol>
      </template>
    </my-category>


    <!-- 具名插槽的作用域插槽使用 -->
    <my-category>
      <template v-slot:content="{content}">
        <div>{{content}}</div>
      </template>
    </my-category>
    <my-category>
      <template #content="{content}">
        <div>{{content}}</div>
      </template>
    </my-category>
  </div>
</template>
注意事项
  1. 不管哪种写法,必须使用 template 标签才行
  2. 可以选一种作为日常常用的写法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值