vue中slot插槽的使用

1.看看官网怎么说?

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和
slot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。
Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 <slot> 元素作为承载分发内容的出口。

2.分为哪几种?

2.1默认插槽

木有name的就是默认插槽,捕获所有未被匹配的内容。

   <slot>这是默认的slot</slot>

定义一个子组件

Vue.component("test1", {
  template: `<div>
    Hello,苏苏!
    <slot>这是默认的slot</slot>
   </div>`,
});

父组件中

<test1></test1>

此时的结果是:

Hello,苏苏!这是默认的slot

<test1>这是苏苏来了</test1>

此时的结果是:

Hello,苏苏!这是苏苏来了

当插槽有默认值的时候,重新定义的内容将会覆盖默认内容,反之显示默认内容。

2.2具名插槽

有时我们需要多个插槽,<slot> 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽,一个不带 name 的 <slot> 出口会带有隐含的名字“default”。
在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称,(原语法为slot="定义的名称")

定义一个子组件

Vue.component("test1", {
  template: `<div>
    Hello,苏苏!
    <slot name="name" ></slot>
    <slot name="age"></slot>
    <slot >这是默认的slot</slot>
   </div>`,
});

父组件

<test1 style="margin: 20px"
      >eg:具名插槽的使用 <template slot="name">苏苏小苏苏111</template
      ><template slot="age">18岁</template></test1>

输入内容:

Hello,苏苏!苏苏小苏苏11118岁eg:具名插槽的使用

2.3作用域插槽

有时让插槽内容能够访问子组件中才有的数据是很有用的,绑定在 <slot> 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字。

定义一个子组件

Vue.component("test1", {
  template: `<div>
    Hello,苏苏!
    <slot name="name" play="玩游戏"></slot>
    <slot name="age"></slot>
    <slot play="玩耍">这是默认的slot</slot>
    <slot say="说哈">这是默认的slot</slot>
   </div>`,
});

父组件:

    <test1 style="margin: 20px"
      >eg:作用域插槽使用
      <template slot="name" slot-scope="play">Suunto{{ play }}</template></test1
    >

输出:

Hello,苏苏! Suunto{ "play": "玩游戏" } eg:作用域插槽使用 eg:作用域插槽使用
父组件:

  <test1 style="margin: 20px"
      >eg:作用域插槽使用
      <template slot="name" slot-scope="{play}">Suunto{{ play }}</template></test1
    >

输出:

Hello,苏苏! Suunto玩游戏 eg:作用域插槽使用 eg:作用域插槽使用

3.v-slot的使用

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope

注意 v-slot 只能添加在 template 上 (或者独占默认插槽的缩写语法),这一点和已经废弃的 slot attribute 不同。

 <test1 style="margin: 20px">
    <template v-slot:name>这是v-slot使用的具名插槽</template></test1
  >
<test1 style="margin: 20px">
     <template v-slot:default="{ play }"
       >这是v-slot使用的作用域插槽 {{ play }}</template
     ></test1
   >
 <test1 style="margin: 20px" v-slot:default="{ play }">
    独占默认插槽的缩写语法:当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用---{{ play}}
 </test1>

注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确,只要出现多个插槽,请始终为所有的插槽使用完整的基于template 的语法

4. 解构插槽 Prop

定义一个子组件

Vue.component("test2", {
  props: ["lists"],
  template: `
            <div>
                <ul>
                    <li v-for="item in lists">
                        <slot :item="item"></slot>
                    </li>
                </ul>
            </div>
        `,
});

父组件

<test2 :lists="list" style="margin: 20px">
    <template v-slot="{ item }"> 解构: {{ item }} </template>
  </test2>

输出:

解构: { "name": "苏苏1" }
解构: { "name": "苏苏2" }
解构: { "name": "苏苏3" }
解构: { "name": "苏苏4" }

父组件:重命名

 <test2 :lists="list" style="margin: 20px">
    <template v-slot="{ item: user }"> 重命名: {{ user.name }} </template>
  </test2>

输出:

重命名: 苏苏1
重命名: 苏苏2
重命名: 苏苏3
重命名: 苏苏4

父组件:定义后备内容,用于插槽 prop 是 undefined 的情形

<test2 :lists="list" style="margin: 20px">
 <template v-slot="{ item = { name: '2332' } }">
     定义后备内容,用于插槽 prop 是 undefined 的情形: {{ item.name }}
   </template>
 </test2>

5.动态插槽名

动态指令参数也可以用在 v-slot 上,来定义动态的插槽名

 <test1 style="margin: 20px">
     <template v-slot:[dynamicSlotName]> 动态插槽名--sss </template>
 </test1>
 ...
 dynamicSlotName: "name",

输出:

Hello,苏苏! 动态插槽名--sss 这是默认的slot 这是默认的slot

6.具名插槽的缩写

具名插槽的缩写,跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header,然而,和其它指令一样,该缩写只在其有参数的时候才可用,你希望使用缩写的话,你必须始终以明确插槽名取而代之,以#default=开始

7.完整代码

<template>
  <div class="contentBox">
    <List>
      <ListItem>
        <ListItemMeta
          :avatar="src"
          title="什么是插槽"
          description="插槽就是Vue实现的一套内容分发的API,将<slot></slot>元素作为承载分发内容的出口,没有插槽的情况下在组件标签内些一些内容是不起任何作用"
        />
      </ListItem>
      <ListItem>
        <ListItemMeta
          :avatar="src"
          title="什么是默认插槽"
          description=" 木有name的就是默认插槽,捕获所有未被匹配的内容"
        />
      </ListItem>
      <ListItem>
        <ListItemMeta
          :avatar="src"
          title="什么是具名插槽"
          description="具名插槽,就是给这个插槽起个名字,如起名一个为name,一个为age,一个不命名"
        />
      </ListItem>
      <ListItem>
        <ListItemMeta
          :avatar="src"
          title="什么是作用域插槽"
          description="组件上的属性,可以在组件元素内使用,如为slot定义一个play属性,使用组件时候添加属性slot-scope"
        />
      </ListItem>
      <ListItem>
        <ListItemMeta
          :avatar="src"
          title="什么是解构插槽 Prop"
          description="作用域插槽的内部工作原理是将你的插槽内容包裹在一个拥有单个参数的函数里,可以使用 ES2015 解构来传入具体的插槽 prop"
        />
      </ListItem>
    </List>
    <test1 style="margin: 20px"></test1>
    <test1 style="margin: 20px">eg:插槽的使用</test1>
    <test1 style="margin: 20px"
      >eg:具名插槽的使用 <template slot="name">苏苏小苏苏111</template
      ><template slot="age">18岁</template></test1
    >
    <test1 style="margin: 20px"
      >eg:作用域插槽使用
      <template slot="name" slot-scope="play">Suunto{{ play }}</template></test1
    >
    <test1 style="margin: 20px"
      >eg:作用域插槽使用
      <template slot="name" slot-scope="{ play }"
        >Suunto{{ play }}</template
      ></test1
    >
    <div style="margin: 20px; font-weight: bold; font-size: 25px">
      作用域插槽使用
    </div>
    <test2 :lists="list" style="margin: 20px">
      <template slot-scope="item">
        {{ item }}
      </template>
    </test2>
    <test2 :lists="list" style="margin: 20px">
      <template slot-scope="{ item }">
        {{ item.name }}
      </template>
    </test2>
    <test2 :lists="list" style="margin: 20px">
      <template slot-scope="{ item }">
        <div v-if="item.name == '苏苏1'">数据1</div>
        <div v-else>其他数据</div>
      </template>
    </test2>
    <div style="margin: 20px; font-weight: bold; font-size: 25px">
      v-slot的使用
    </div>
    <div style="margin: 20px; font-weight: bold; font-size: 20px">
      注意 v-slot 只能添加在 template 上
      (或者独占默认插槽的缩写语法),这一点和已经废弃的 slot attribute 不同。
    </div>
    <test1 style="margin: 20px">
      <template v-slot:name>这是v-slot使用的具名插槽</template></test1
    >
    <test1 style="margin: 20px">
      <template v-slot:default="{ play }"
        >这是v-slot使用的作用域插槽 {{ play }}</template
      ></test1
    >
    <test1 style="margin: 20px" v-slot:default="{ play }">
      独占默认插槽的缩写语法:当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用------{{
        play
      }}
    </test1>
    <test1 style="margin: 20px" v-slot="{ play }">
      独占默认插槽的缩写语法:不带参数的 v-slot 被假定对应默认插槽 -------{{
        play
      }}
    </test1>
    <div style="margin: 20px; font-weight: bold; font-size: 20px">
      注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确,只要出现多个插槽,请始终为所有的插槽使用完整的基于
      template 的语法
    </div>
    <div style="margin: 20px; font-weight: bold; font-size: 20px">
      解构插槽 Prop
    </div>
    <test2 :lists="list" style="margin: 20px">
      <template v-slot="{ item }"> 解构: {{ item }} </template>
    </test2>
    <test2 :lists="list" style="margin: 20px">
      <template v-slot="{ item: user }"> 重命名: {{ user.name }} </template>
    </test2>
    <test2 :lists="list" style="margin: 20px">
      <template v-slot="{ item = { name: '2332' } }">
        定义后备内容,用于插槽 prop 是 undefined 的情形: {{ item.name }}
      </template>
    </test2>
    <div style="margin: 20px; font-weight: bold; font-size: 20px">
      动态插槽名
    </div>
    <test1 style="margin: 20px">
      <template v-slot:[dynamicSlotName]> 动态插槽名--sss </template>
    </test1>
    <div style="margin: 20px; font-weight: bold; font-size: 20px">
      具名插槽的缩写,跟 v-on 和 v-bind 一样,v-slot
      也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如
      v-slot:header 可以被重写为
      #header,然而,和其它指令一样,该缩写只在其有参数的时候才可用,你希望使用缩写的话,你必须始终以明确插槽名取而代之,以#default=开始
    </div>
  </div>
</template>

<script>
// 在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute
import Vue from "vue";
Vue.component("test1", {
  template: `<div>
    Hello,苏苏!
    <slot name="name" play="玩游戏"></slot>
    ---这是米----
    <slot name="age"></slot>
    <slot play="玩耍">这是默认的slot</slot>
    <slot say="说哈">这是默认的slot</slot>
   </div>`,
});

// 绑定在 <slot> 元素上的 attribute 被称为插槽 prop
Vue.component("test2", {
  props: ["lists"],
  template: `
            <div>
                <ul>
                    <li v-for="item in lists">
                        <slot :item="item"></slot>
                    </li>
                </ul>
            </div>
        `,
});
export default {
  data() {
    return {
      dynamicSlotName: "name",
      src: require("@/assets/img/susu.jpg"),
      list: [
        {
          name: "苏苏1",
        },
        {
          name: "苏苏2",
        },
        {
          name: "苏苏3",
        },
        {
          name: "苏苏4",
        },
      ],
    };
  },
};
</script>

<style>
</style>

8.完整代码,关注公众号 苏苏的bug,更多vue相关,尽在苏苏的码云如果对你有帮助,欢迎你的star+订阅!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容