美文网首页
vue中的slot(插槽)

vue中的slot(插槽)

作者: 3e2235c61b99 | 来源:发表于2020-12-15 19:51 被阅读0次
什么是插槽
  • 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。
  • 插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制
默认插槽-1
<!--子组件-->
<template>
    <div>
        <slot></slot>
        <div>slot固有内容</div>
    </div>
</template>
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot></named-slot>
    </div>
</template>

当父组件不在插槽中写入任何数据时,会只显示父组件和子组件的默认内容:


默认插槽-1
默认插槽-2
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            我是父组件中的匿名插槽内容
            <div style="color: red">我是父组件中的匿名插槽内容</div>
            <el-button>插槽按钮</el-button>
        </named-slot>
    </div>
</template>

当需要在子组件slot位置显示内容时,可以在父组件引入的子组件中写入想要现实的内容(可以直接写入内容,或者使用标签,或者使用其他组件)


默认插槽-2
默认插槽-3

也可以为插槽设置具体的默认内容,它只会在没有提供内容的时候被渲染

<!--子组件-->
<template>
    <div>
        <slot>子组件插槽默认内容</slot>
        <div>slot固有内容</div>
    </div>
</template>
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot></named-slot>
    </div>
</template>

父组件没有提供内容时,显示子组件的插槽默认内容:


默认插槽-3
默认插槽-4
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            我是父组件中的插槽内容,我会替换子组件slot中的默认内容
        </named-slot>
    </div>
</template>

父组件提供内容时,子组件的默认内容被父组件提供的内容替换:


默认插槽-4
具名插槽-1

有时候我们需要多个插槽,以把不同的内容显示在需要的地方
一个不带 name<slot> 出口会带有隐含的名字“default”。

<!--子组件-->
<template>
    <div>
        <slot name="header"></slot>
        <div>slot固有内容</div>
        <slot></slot>
        <div>slot固有内容</div>
        <slot name="footer"></slot>
    </div>
</template>
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <div>默认插槽1</div>
            <div slot="footer">底部插槽</div>
            <div slot="header">顶部插槽</div>
            <div>默认插槽2</div>
            <div slot="default">默认插槽3</div>
        </named-slot>
    </div>
</template>

上面的代码显示内容如下:


具名插槽-1
具名插槽-2

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称
注意 v-slot 只能添加在 <template> 上 (只有一种例外情况)
所以父组件的写法也可以是这样:

<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template>默认插槽1</template>
            <template v-slot:footer>底部插槽</template>
            <template v-slot:header>顶部插槽</template>
            <template>默认插槽2</template>
        </named-slot>
    </div>
</template>

显示如下:


具名插槽-2.1

或者写成这样:

<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template v-slot:footer>底部插槽</template>
            <template v-slot:header>顶部插槽</template>
            <template v-slot:default>默认插槽3</template>
        </named-slot>
    </div>
</template>

显示如下:

具名插槽-2.2
当使用v-slot时,只会显示最后一个带有v-slot<template>元素中的内容
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template v-slot:default>默认插槽1</template>
            <template v-slot:footer>底部插槽</template>
            <template v-slot:header>顶部插槽</template>
            <template v-slot:default>默认插槽2</template>
            <template>默认插槽3</template>
        </named-slot>
    </div>
</template>

以上代码显示:


具名插槽-2.3
具名插槽的缩写

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

<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template #default>默认插槽1</template>
            <template #footer>底部插槽</template>
            <template #header>顶部插槽</template>
        </named-slot>
    </div>
</template>

上面代码显示为:

具名插槽的缩写
然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:
(官网写会触发警告,我的页面直接报错了......)
<!-- 这样会触发一个警告 -->
<named-slot>
    <template #>顶部插槽</template>
</named-slot>

所以如果想使用缩写的话,还是老老实实地写清楚插槽名称吧

编译作用域

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
当你想在一个插槽中使用数据时,例如下例,想在父组件中使用子组件的数据是访问不到的:

<!--子组件-->
<template>
    <div>
        <slot></slot>
        <div>slot固有内容: {{ child }}</div>
    </div>
</template>

<script>
    export default {
        name: "mySlot",
        data() {
            return {
                child: "子组件属性"
            }
        }
    }
</script>
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <div>我是父组件中的匿名插槽内容: {{ child }}</div>
        </named-slot>
    </div>
</template>
作用域插槽

有时让插槽内容能够访问子组件中才有的数据是很有用的。

<!--子组件-->
<template>
    <div>
        <slot :data="user"></slot>
        <div>slot固有内容: {{ user.name }}</div>
    </div>
</template>

<script>
    export default {
        name: "mySlot",
        data() {
            return {
                user: {
                    name: "明妃",
                    age: "18"
                }
            }
        }
    }
</script>
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template slot-scope="slotProps">我是父组件中的匿名插槽内容: {{ slotProps.data.name }}</template>
        </named-slot>
    </div>
</template>

其中子组件中:data="user"用来把子组件中的user绑定到data
父组件中slotProps用来接收子组件传过来的数据,slotProps.data即是子组件传递过来的user
上面代码显示如下:

作用域插槽
自2.6.0之后,slot-scope已弃用,所以也可以下面的写法:
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template v-slot:default="slotProps">我是父组件中的匿名插槽内容: {{ slotProps.data.name }}</template>
        </named-slot>
    </div>
</template>
独占默认插槽的缩写语法

在上述情况下,当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 v-slot 直接用在组件上:

<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot v-slot:default="slotProps">
            我是父组件中的匿名插槽内容: {{ slotProps.data.name }}
        </named-slot>
    </div>
</template>

这种写法还可以更简单。就像假定未指明的内容对应默认插槽一样,不带参数的 v-slot 被假定对应默认插槽:

<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot v-slot="slotProps">
            我是父组件中的匿名插槽内容: {{ slotProps.data.name }}
        </named-slot>
    </div>
</template>

这两种写法都可以获得跟上面一样的效果:

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

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

<!--子组件-->
<template>
    <div>
        <slot name="header"></slot>
        <div>slot固有内容</div>
        <slot></slot>
        <div>slot固有内容</div>
        <slot name="footer"></slot>
    </div>
</template>
<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template v-slot:[slotNameC]>看看插槽位置</template>
        </named-slot>
    </div>
</template>

data() {
    return{
        slotNameC: "footer",    // footer,header,default
    }
},

slotNameC赋不同的值,插槽内容会显示在对应位置
但是下面的写法会报错:

<!--父组件-->
<template>
    <div class="content">
        <div>我是父组件</div>
        <named-slot>
            <template v-slot:[slotNameA]>默认插槽</template>
            <template v-slot:[slotNameB]>顶部插槽</template>
            <template v-slot:[slotNameC]>底部插槽</template>
        </named-slot>
    </div>
</template>

data() {
    return{
        slotNameA: "default",
        slotNameB: "header",
        slotNameC: "footer",    // footer,header,default
    }
},

只有注释掉上面两行才可以正常显示,注释掉第三行不能正常显示(只剩第一行或第二行都不行),目前还不知道原因,希望知道原因的小伙伴告诉一下

相关文章

  • Vue之深入理解插槽—slot, slot-scope, v-s

    Vue 2.6.0 以前Vue 2.6.0 以后具名插槽 slot具名插槽 v-slot作用域插槽 slot-sc...

  • vue中的slot(插槽)

    vue中的插槽————slot 什么是插槽? 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定...

  • vue插槽

    vue插槽slot的理解与使用 vue slot插槽的使用介绍及总结

  • 18、Vue3 作用域插槽

    作用域插槽:让插槽内容能够访问子组件中,vue2中作用域插槽使用slot-scope,vue3中使用v-slot ...

  • vue 插槽的使用

    vue 插槽手册 深入理解vue中的slot与slot-scope 插槽的使用其实是很简单首先要明白插槽是使用在子...

  • Vue中Slot的渲染过程

    Vue在通过compiler解析模版中的slot, slot是组件中的插槽,通过解析slot,把slot的name...

  • 2020-07-23 一次性讲明白vue插槽slot

    vue插槽slot 一、前言 vue官方文档中在"组件基础"内容中提到组件可以通过插槽分发内容,那插槽是怎么使用的...

  • vue插槽slot

    vue插槽slot 一、前言 vue官方文档中在"组件基础"内容中提到组件可以通过插槽分发内容,那插槽是怎么使用的...

  • Vue3.0 组件的核心概念_插槽

    Vue 在 2.6 版本中,对插槽使用 v-slot 新语法,取代了旧语法的 slot 和 slot-scope,...

  • slot是什么?有什么作用?原理是什么?

    slot又名插槽,是Vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是...

网友评论

      本文标题:vue中的slot(插槽)

      本文链接:https://www.haomeiwen.com/subject/buywgktx.html