### 彪哥

爱好前端

- 基础

- 组件

  - 使用组件的细节点
  - 父组件给子组件传值
  - 子组件派发事件和值给父组件
  - Prop 验证 与 非 Prop 的 Attribute
  - 自定义事件
  - 兄弟组件传值
  - 非父子组件传值
  - 父组件调用子组件方法并传入值
  - 插槽slot
    - 插槽
      - 默认值
    - 具名插槽
    - 作用域插槽
      - 作用：
    - 具名插槽的缩写
    - Demo
  - 动态组件与 v-once 指令
  - vue父子组件的生命周期顺序

- 过渡&动画

- 可复用性&组合

- 工具

- 规模化

- Vuex

- 其他

- 《Vue》笔记
- 组件

heBody
2020-02-16
目录

# 插槽slot

# # 插槽slot

API
(opens new window)

## # 插槽

    <div id="root">
        <child> <!-- 组件标签 -->
            <h1>hello</h1>
        </child>
    </div>

    <script type="text/javascript">
        Vue.component('child', { // 子组件
            template: '<div><slot></slot></div>'
        })

        var vm = new Vue({
            el: '#root'
        })
    </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

上面代码中，组件标签内的`h1`是要插入子组件内部的元素，子组件内使用`slot`标签接收父组件插入的`h1`标签。

#### # 默认值

    Vue.component('child', {
        template: '<div><slot>默认值</slot></div>'
    })

1
2
3

子组件`slot`标签内可以添加默认值，它只会在父组件没有传入内容的时候被渲染。

## # 具名插槽

注意

自 2.6.0 起有所更新。使用 `slot` attribute 的语法已废弃。

    <div id="root">
        <child>
            <div slot="header">header</div> <!--旧语法 使用template标签或其他标签都可以-->
            <div slot="footer">footer</div>
        </child>
    </div>

    <script type="text/javascript">
        Vue.component('child', {
            template: `<div>
                            <slot name="header"></slot>
                            <div>content</div>
                            <slot name="footer"></slot>
                        </div>`
        })

        var vm = new Vue({
            el: '#root'
        })
    </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

上面代码中，组件标签内有两个元素，分别添加了`slot`属性赋予不同的值，子组件内分别有两个`slot`插槽，添加了对应的`name`属性，用于分别接收父组件传入的内容。

提示

自 2.6.0 起，使用`v-slot`指令代替`slot` attribute 的语法。

    <div id="root">
        <child>
            <template v-slot:header> <!--新语法 只能使用template标签-->
                <h1>标题</h1>
            </template>
            <p>内容</p>
            <template v-slot:footer>
                <p>页脚</p>
            </template>
        </child>
    </div>
    <script type="text/javascript">
    	Vue.component('child', {
    		template: `<div>
    						<header>
    						   <slot name="header"></slot>
    						</header>
    						<main>
    						  <slot></slot>
    						</main>
    						<footer>
    						  <slot name="footer"></slot>
    						</footer>
    					</div>`
    	})

        var vm = new Vue({
            el: '#root'
        })
    </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

自2.6.0版本起，具名插槽由原来的`slot`标签属性改为`v-slot`指令，例`v-slot:header`。子组件内仍然是在`slot`插槽标签添加`name`属性用于分别接收内容。未具名的插槽接收未使用`v-slot`指定的内容。

另外，具名插槽同样可以使用默认值。

注意 `v-slot` 只能添加在 `<template` 上 (只有一种例外情况
(opens new window))，这一点和已经废弃的 `slot`attribute
(opens new window)不同。

## # 作用域插槽

注意

自 2.6.0 起有所更新。使用 `slot-scope` attribute 的语法已废弃。

    <div id="root">
        <child>
            <template slot-scope="dataObj"> <!--可使用其他标签，但注意其他标签将会被带到插槽里面-->
                <li>{{dataObj.dataItem}}</li>
            </template>
        </child>
    </div>
    <script type="text/javascript">
    	Vue.component('child', {
            data(){
                return {
                    list: [1, 2, 3, 4]
                }
            },
            template: `<div>
    						<ul>
    							<slot
    								v-for="item of list"
    								:dataItem=item
    							>
    							</slot>
    						</ul>
    					  </div>`
        })

        var vm = new Vue({
            el: '#root'
        })
    </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

上面代码中，组件标签内需要使用`template`标签并且设置`slot-scope`属性 用于接收子组件内传递的值，`template`标签内的`li`标签是传入插槽的元素，`dataObj.dataItem`数据由子组件内提供。子组件内通过`v-for`循环插入父组件提供的`li`标签，并且通过`:dataItem=item`把每个`item`数据传递出去。

> 子组件提供数据，父组件中接收数据，可以对数据处理并插入到元素，然后把元素放入子组件插槽。

#### # 作用：

数据由子组件提供，但渲染什么元素由父组件决定，并且可以对数据做二次处理。

提示

自 2.6.0 起。使用`v-slot`代替 `slot-scope` attribute 的语法。

为了让 `user` 在父级的插槽内容中可用，我们可以将 `user` 作为 `<slot>` 元素的一个 attribute 绑定上去：

    <span>
      <slot v-bind:user="user">
        {{ user.lastName }}
      </slot>
    </span>

1
2
3
4
5

绑定在 `<slot>` 元素上的 attribute 被称为插槽 prop。现在在父级作用域中，我们可以使用带值的 `v-slot` 来定义我们提供的插槽 prop 的名字：

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

1
2
3
4
5

在这个例子中，我们选择将包含所有插槽 prop 的对象命名为 `slotProps`，但你也可以使用任意你喜欢的名字。

    <div id="root">
        <child>
            <template v-slot:default="dataObj"> <!--default是默认具名，可省略。但有多个插槽时不能省略。-->
                <li>{{dataObj.dataItem}}</li>
            </template>
        </child>
    </div>

    <script type="text/javascript">
    	Vue.component('child', {
            data(){
                return {
                    list: [1, 2, 3, 4]
                }
            },
            template: `<div>
    						<ul>
    							<slot
    								v-for="item of list"
    								:dataItem=item
    							>
    							</slot>
    						</ul>
    					  </div>`
        })

        var vm = new Vue({
            el: '#root'
        })
    </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

## # 具名插槽的缩写

跟 `v-on` 和 `v-bind` 一样，`v-slot` 也有缩写，即把参数之前的所有内容 (`v-slot:`) 替换为字符 `#`。例如 `v-slot:header` 可以被重写为 `#header`：

    <base-layout>
      <template #header>
        <h1>Here might be a page title</h1>
      </template>

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

      <template #footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>

1
2
3
4
5
6
7
8
9
10
11
12

然而，和其它指令一样，该缩写只在其有参数的时候才可用。这意味着以下语法是无效的：

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

1
2
3
4

如果你希望使用缩写的话，你必须始终以明确插槽名取而代之：

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

1
2
3

## # Demo

See the Pen 插槽slot by heBody (@heBody) on CodePen.

编辑
(opens new window)
#Vue
上次更新: 2022/12/14, 19:36:42
父组件调用子组件方法并传入值
动态组件与 v-once 指令

← 父组件调用子组件方法并传入值 动态组件与 v-once 指令→

最近更新

  01
Git修改分支名
08-11

  02
CSS给table的tbody添加滚动条
06-29

  03
我做了一个手写春联小网页，祝大家虎年暴富 原创
01-28

更多文章>

Copyright © 2016-2022 Hesb | MIT License

- 跟随系统
- 浅色模式
- 深色模式
- 阅读模式