(1)插槽内容

Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 <slot> 元素作为承载分发内容的出口。

在父级组件里可以这样写

    <div class="slot_area">
<navigation-link v-bind:url="url">
Your Profile你的个人简介资料
</navigation-link>
</div>

然后在 <navigation-link> 组件模板中:

        Vue.component('navigation-link',{
props:['url'],
template:`<a v-bind:href="url" class="nav-link">
<span class="slot_span"></span>
<slot></slot>
</a>`
});

new Vue({
              el:'.slot_area',
              data:{
                  url:'http://www.baidu.com'
              }
          })


当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile你的个人简介资料”。

插槽内可以包含任何模板代码,包括 HTML:

        Vue.component('navigation-link',{
props:['url'],
template:`<a v-bind:href="url" class="nav-link">
<!-- 添加一个 Font Awesome 图标 -->
<span class="fa fa-user"></span>
<slot></slot>
</a>`
});

插槽也可以是其他组件

    <div class="slot_area">
<navigation-link v-bind:url="url">
Your Profile你的个人资料简介
<slot-component></slot-component>
</navigation-link>
</div> <script type="text/javascript">
Vue.component('navigation-link',{
props:['url'],
template:`<a v-bind:href="url" class="nav-link">
<!-- 添加一个 Font Awesome 图标 -->
<span class="slot_span"></span>
<slot></slot>
</a>`
});
Vue.component('slot-component',{
template:'<h4>插槽可以是其他模板</h4>'
})
new Vue({
el:'.slot_area',
data:{
url:'http://www.baidu.com'
}
})
</script>

结果:

注意:如果 <navigation-link> 没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。即如果模板中没有slot插槽元素,则在父级组件里加的内容都会被抛弃。

(2)编译作用域

父组件模板内容是在父组件作用域中编译的,子组件模板内容是在子组件里编译的。

先来个简单的案例:

<parent-scrop>
{{message}}
</parent-scrop>
Vue.component('parent-scrop',{
template:`<div>
子组件模板内容
<slot></slot>
</div>`
});
new Vue({
el:".parent_scrop",
data:{
message:"父组件模板内容"
}
});

这里的message就是一个slot,但是其绑定的是父组件的数据,而不是子组件模板的数据。

再来看个案例:

    <div class="parent_scrop">
<parent-scrop v-show="showStatus"></parent-scrop>
</div>
Vue.component('parent-scrop',{
template:`<div>
子组件模板内容
</div>`
});
new Vue({
el:".parent_scrop",
data:{
showStatus:true
}
})

这里的showStatus绑定的是父级组件的数据,如果想在子级组件上绑定,应该是

    <div class="parent_scrop">
<parent-scrop></parent-scrop>
</div>
Vue.component('parent-scrop',{
template:`<div v-show="showStatus">
子组件模板内容
</div>`,
data:function(){
return {
showStatus:false
}
}
});
new Vue({
el:".parent_scrop"
})

结果:

因此,slot分发的内容,作用域是在父组件上的。

(3)slot用法

①单个slot

在子组件内使用特殊的<slot>元素就可以为这个子组件开启一个slot(插槽),在父组件模板里,插入在父组件标签内的所有内容都将替代子组件的<slot>标签及它的内容。

demo1:

    <div class="single_slot">
<single-slot></single-slot>
</div>
Vue.component('single-slot',{
template:`
<div>
<slot>
<p>如果父组件没有插入内容,将会作为默认值出现</p>
</slot>
</div>
`
});
new Vue({
el:".single_slot"
})

结果:

demo2:父组件插入内容

    <div class="single_slot">
<single-slot>
<p>父组件插入内容</p>
<p>分发更多内容</p>
</single-slot>
</div>
Vue.component('single-slot',{
template:`
<div>
<slot>
<p>如果父组件没有插入内容,将会作为默认值出现</p>
</slot>
</div>
`
});
new Vue({
el:".single_slot"
})

结果:

(4)后备内容/备用内容

结合上例,<single-slot>模板里定义了<slot>元素,并用了<p>作为默认内容。在父组件没有使用slot即未插入内容时,会渲染这段默认文本;如果写入了slot,那么就会替换整个<slot>。

注意:子组件<slot>中的后备内容,其作用域是子组件本身。

(5)具名插槽

给<slot>元素指定一个name后,可以分发多个内容,具名插槽可以与单个插槽共存。

用法简单demo1:

父级组件里:
<solt-area>
<h2 slot="header">标题</h2>
<p slot="footer">底部</p>
</slot-area> 子级模板里:
Vue.component('slot-area',{
template:`
<div class="main_area">
<div class="header"><slot name="header"></slot></div>
<div class="footer"><slot name="footer"></slot></div>
</div>
`
})

demo2:

    <!-- 具名slot -->
<div class="slot_name">
<slot-name>
<h2 slot="header">文章标题</h2>
<p>内容展示区域1,文章具体内容1... ...</p>
<p>内容展示区域2,文章具体内容2... ...</p>
<p slot="footer">作者:Tony 发布日期:2020.6.</p>
</slot-name>
</div>
<style type="text/css">
.main_area{
padding: 20px;
background-color: rgba(,,,0.1);
}
.main_area h2{
margin: 10px ;
text-align: center;
}
.main_area .footer{
text-align: right;
font-weight: ;
margin: 10px ;
}
.main_area .main{
padding: 10px;
background-color: rgba(,,,.);
}
</style>
/* 3、具名slot */
Vue.component('slot-name',{
template:`
<div class="main_area">
<div class="header"><slot name="header"></slot></div>
<div class="main"><slot></slot></div>
<div class="footer"><slot name="footer"></slot></div>
</div>
`
})
new Vue({
el:".slot_name"
})

结果:

       

子组件里声明了3个<slot>元素,其中在<div class="main"></div>内的slot没有使用name特性,所以他将作为默认slot出现,父组件里没有使用slot特性的元素与内容都将出现在这里。

如果没有指定默认的匿名slot,父组件里多余的内容片段都将会被抛弃。在组合使用组件时,内容分发API至关重要。

注意:自2.6.0开始有所跟新,将原先的slot方法更新为v-slot 指令即

    <div class="slot_name">
<slot-name>
<template v-slot:header>
<h2>文章标题</h2>
</template>
<template v-slot:default>
<p>内容展示区域1,文章具体内容1... ...</p>
<p>内容展示区域2,文章具体内容2... ...</p>
</template>
<template v-slot:footer>
<p>作者:Tony 发布日期:2020.6.8</p>
</template>

</slot-name>
</div>

现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容。然而,如果你希望更明确一些,仍然可以在一个 <template> 中包裹默认插槽的内容,如上所示v-slot:default。

(6)作用域插槽

正常情况下,父级组件的插槽内容无法访问子级模板中的数据,例如

    <div class="scrop_slot">
<scrop-slot>
姓:{{user.firstName}},名:{{user.lastName}}
</scrop-slot>
</div>
/* 4、作用域插槽 */
Vue.component('scrop-slot',{
template:`
<div class="show_area">
<slot>
<p>姓:{{user.firstName}},名:{{user.lastName}}</p>
</slot>
</div>
`,
data:function(){
return {
user:{firstName:"邓",lastName:"超"}
};
}
})
new Vue({
el:".scrop_slot"
})
/* 4、作用域插槽 */

此时,控制台会出现报错提示

为了让 user 在父级的插槽内容可用,我们可以将 user 作为一个 <slot> 元素的特性绑定上去:

<slot v-bind:user="user">
<p>姓:{{user.firstName}},名:{{user.lastName}}</p>
</slot>

绑定在 <slot> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字:

    <div class="scrop_slot">
<scrop-slot v-slot:default="slotDefault">
<template>
姓:{{slotDefault.user.firstName}},名:{{slotDefault.user.lastName}}
</template>
</scrop-slot>
</div>

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

(7)独占默认插槽的缩写语法

    <div class="scrop_slot">
<scrop-slot v-slot:default="slotDefault">
<template>
姓:{{slotDefault.user.firstName}},名:{{slotDefault.user.lastName}}
</template>
</scrop-slot>
</div>

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

    <div class="scrop_slot">
<scrop-slot v-slot:default="slotDefault">
姓:{{slotDefault.user.firstName}},名:{{slotDefault.user.lastName}}
</scrop-slot>
</div>

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

    <div class="scrop_slot">
<scrop-slot v-slot="slotDefault">
姓:{{slotDefault.user.firstName}},名:{{slotDefault.user.lastName}}
</scrop-slot>
</div>

注意:注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确。如下所示

<scrop-slot v-slot="slotDefault">
姓:{{slotDefault.user.firstName}}
<template v-slot:other="otherSlot">
名:{{slotDefault.user.lastName}}
</template>
</scrop-slot>

此时,控制台出现报错:译为---为避免范围模糊,当存在其他命名槽时,默认槽也应使用<template>语法。

<scrop-slot>
<template v-slot:datault="slotDefault">
姓:{{slotDefault.user.firstName}}
</template>
<template v-slot:other="otherSlot">
名:{{otherSlot.user.lastName}}
</template>
</scrop-slot>

只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template> 的语法。

(8)解构插槽Prop

可以使用 ES2015 解构来传入具体的插槽 prop,如下:

    <div class="scrop_slot">
<scrop-slot v-slot="{user}">
{{user.firstName}}
</scrop-slot>
</div>
Vue.component('scrop-slot',{
template:`
<div class="show_area">
<slot v-bind:user="user">
<p>姓:{{user.firstName}},名:{{user.lastName}}</p>
</slot>
</div>
`,
data:function(){
return {
user:{firstName:"邓",lastName:"超"}
};
}
})
new Vue({
el:".scrop_slot"
})

这样可以使模板更简洁,尤其是在该插槽提供了多个 prop 的时候。它同样开启了 prop 重命名等其它可能,例如将 user 重命名为 person

<scrop-slot v-slot="{user:person}">
{{person.firstName}}
</scrop-slot>

(9)动态插槽名(待验证

(10)具名插槽缩写

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

    <div class="slot_name">
<slot-name>
<template #header>
<h2>文章标题</h2>
</template>
<template #default>
<p>内容展示区域1,文章具体内容1... ...</p>
<p>内容展示区域2,文章具体内容2... ...</p>
</template>
<template #footer>
<p>作者:Tony 发布日期:2020.6.</p>
</template>
</slot-name>
</div>

.

vue组件---插槽的更多相关文章

  1. vue组件插槽

    vue中子组件内容如何定义为可扩展的呢,就是用slot插槽来实现.如下图 如果<slot></slot>标签有内容,那就默认显示里面的内容,父组件传了就会覆盖此默认的内容.

  2. [Vue]组件——插槽:slot(匿名插槽,具名插槽)与slot-scope(作用域插槽)

    1.单个插槽 | 匿名插槽 1.1<navigation-link> 子组件定义为: <a v-bind:href="url" class="nav-l ...

  3. vue组件插槽与编译作用域

    <!DOCTYPE html> <html> <head> <title></title> </head> <script ...

  4. 极客时间_Vue开发实战_07.Vue组件的核心概念(3):插槽

    07.Vue组件的核心概念(3):插槽 严格来的说在2.0之后已经不分区这两种插槽的概念了. 因为它底层的实现已经趋向于相同了. 2.6为了兼容2.5的版本,现在依然可以用这两种写法 作用域插槽就是多 ...

  5. Vue组件之作用域插槽

    写作用域插槽之前,先介绍一下Vue中的slot内容分发: 如果<child-component></child-component>标签之间没有插入那两个p标签的话,页面会显示 ...

  6. 三、深入Vue组件——Vue插槽slot、动态组件

    一.插槽slot() 1.1简单插槽slot [功能]用于从父组件中,通过子组件写成双标签,向子组件中放入自定的内容 parent.vue [1]首先把child写成双标签样式,把要插入的内容放双标签 ...

  7. 04 . Vue组件注册,数据交互,调试工具及组件插槽介绍及使用

    vue组件 组件(Component)是 Vue.js 最强大的功能之一. 组件可以扩展 HTML 元素,封装可重用的代码. 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的 ...

  8. 04 . Vue组件注册,组件间数据交互,调试工具及组件插槽介绍及使用

    vue组件 组件(Component)是 Vue.js 最强大的功能之一. 组件可以扩展 HTML 元素,封装可重用的代码. 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的 ...

  9. Vue 组件化开发之插槽

    插槽的作用 相信看过前一篇组件化开发后,你对组件化开发有了新的认识. 插槽是干什么的呢?它其实是配合组件一起使用的,让一个组件能够更加的灵活多变,如下图所示,你可以将组件当作一块电脑主板,将插槽当作主 ...

随机推荐

  1. dumpdecrypted进行砸壳

    1.下载源码git clone git://github.com/stefanesser/dumpdecrypted/ 2.进行编译生成 dumpdecrypted.dylibmake 3.将dump ...

  2. 容器与容器编排实战系列 1 -- Docker 安装

    CentOS7.4 下安装Docker 详细步骤 第一步:安装Docker yum install -y yum-utils device-mapper-persistent-data lvm2 yu ...

  3. [计算机联网故障]WIFI接入正常,但是上网不正常(两种情况)

    今天同事拿来一个笔记本,说是连接WIFI都正常,但是就是无法上网.换了单位的wifi和他自己的手机共享wifi都是无法上网. 我首先检查了一下IP地址设置,看是否指定了IP.没有. 然后取消IPv6. ...

  4. 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) S Surf

    SurfNow that you've come to Florida and taken up surng, you love it! Of course, you've realized that ...

  5. 美国诚实签经验——我们准备了XX万的存款,这足以应付我预算表中涉及的所有开支,如果有意外情况我们的资金不足以应付,我们双方的父母也会支援我们,绝对不会占用美国的任何福利

    闲话少絮,直接分享本人诚实签的经验,希望对有此打算的朋友有帮助! 个人经验有限,经历仅供参考~~ 第一步:决定赴美生子. 第二步:选择诚实签. 第三步:填写DS160表格(网址https://ceac ...

  6. 红米note怎么打开USB调试模式

    红米note到货后,打开USB调试模式是一些新手很棘手的问题,所以要手机助手成功识别红米note,你必须打开红米note的USB调试模式.在安卓4.2版本中,系统的USB调试模式不是非常简单地被打开的 ...

  7. php语法错误导致服务器错误(500)解决

    PHP编码出错不提示,而是提示500错误,这对于开发来说,是很不方便的.下面讲解如何开启错误提示步骤: 1. 打开php.ini文件.以我的ubuntu为例,这个文件在: /etc/php5/apac ...

  8. Runtime ----- 带你上道

    在IOS开发和学习过程中,我们经常会接触到一个词: Runtime  .很多开发者对之既熟悉又陌生,基本都是浅尝辄止,达不到灵活使用的水平(话说开发中也确实不经常用..)本文和大家一起研究一下,Run ...

  9. bzoj 1621: [Usaco2008 Open]Roads Around The Farm分岔路口【dfs】

    模拟就行--讲道理这个时间复杂度为啥是对的??? #include<iostream> #include<cstdio> using namespace std; int k, ...

  10. [Swift通天遁地]一、超级工具-(19)制作六种别具风格的动作表单

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...