组件的作用域(一)

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

父子组件的编译相互独立,编译时只能使用各自作用域中的属性和方法,例如,你不可以在父组件模板内,将一个指令绑定到子组件的属性或方法上。如果这么做控制台会报一个属性未定义的错误。

如果想要绑定一个指令以便控制子组件的行为,那么你可以在子组件的模板内,将一个指令绑定到子组件的属性或方法上;或者在父组件的模板内,将指令绑定到父组件的属性或方法上。

new Vue({
el: '#app-2',
data: {
makeChildShow: true
},
components: {
"component-2-1": {
template: '<span>I am an sub component.</span>',
data: function () {
return {
childIsShow: true
}
}
},
"component-2-2": {
template: '<span v-show="childIsShow">I am an sub component.</span>',
data: function () {
return {
childIsShow: true
}
}
}
}
})
<div id="app-2">
<ul>
<li>绑定到子组件属性:<component-2-1 v-show="childIsShow"></component-2-1></li>
<li>绑定到父组件属性:<component-2-1 v-show="makeChildShow"></component-2-1></li>
<li>在子组件模板内将指令绑定到子组件属性:<component-2-2></component-2-2></li>
</ul>
</div>

列表第一项,由于父组件找不到属性childIsShow,将不会显示。

默认情况下的内容分发

将父组件的内容插入子组件模板的方式,我们称为内容分发
默认情况下,在子组件中插入的父组件内容是不显示的。

new Vue({
el: '#app-1',
data: { message: 'I come from parent.' },
components: {
"component-1": {
template: '<p>I am an sub component.</p>',
}
}
})
<div id="app-1" class="demo">
<component-1>
{{ message }}
</component-1>
</div>

内容分发失败,message不会显示。

单个插口

如果想使用内容分发,将父组件内容插入到子组件的模板中,必须在子组件的模板内标记一个<slot>备选内容</slot>,父组件将找到这个<slot>备选内容</slot>标记,并将自己的内容替换<slot>备选内容</slot>
如果父组件没有待分发的内容,备选内容成为最终渲染的结果。

new Vue({
el: '#app-3',
components: {
"component-3": {
template: '\
<ul>\
<li>子组件内容</li>\
<li>子组件内容</li>\
<slot><li>插口备选内容</li></slot>\
<li>子组件内容</li>\
<li>子组件内容</li>\
</ul>'
}
}
})
<div id="app-3">
<h5>父组件标题</h5>
<component-3>
<li>父组件插入内容</li>
</component-3>
</div>

具名插口(多个插口)

单插口模式做内容分发,只能一股脑把套入子模板的内容插入到有<slot></slot>标记的地方。
而具名插口在内容和slot上都做上标记,对应的内容只能分发到对应的slot上。
标记内容用slot="tag"; 标记slot<slot name="tag">

new Vue({
el: '#app-4',
components: {
"component-4": {
template: '\
<div>\
<header>\
<slot name="header"></slot>\
</header>\
<article>\
<slot></slot>\
</article>\
<footer>\
<slot name="footer"></slot>\
</footer>\
<section><slot></slot></section>\
</div>'
}
}
})
<div id="app-4">
<component-4>
<h5 slot="header">我来组成头部</h5>
<p>没被标记的slot都我插</p>
<div slot="footer">我来组成腿部</div>
</component-4>
</div>

以上定义了两个个不具名的插口,虽然这里显示正确,但是控制台报错,说定义重复的默认插口会有不预期的错误

组件作用域(二)

根据具名插口,再来看个组件作用域的例子

new Vue({
el: '#app-7',
methods: {
parentMethod: function () {
console.log("It is the parent's method");
}
},
components:{
"component-7":{
methods:{
childMethod: function(){
console.log("It is the child's method")
}
},
template:"\
<button>\
<slot name='first'></slot>\
<span @click='childMethod'>子组件模板定义部分①|</span>\
<slot name='second'></slot>\
<span @click='childMethod'>子组件模板定义部分②</span>\
</button>"
}
}
})
<div id="app-7">
<component-7>
<span slot="first" @click="parentMethod">内容分发部分①|</span>
<span slot="second" @click="parentMethod">内容分发部分②|</span>
</component-7>
</div>


内容分发部分属于父组件作用域,因此点击按钮的内容分发部分,会调用父组件方法,输出"It is the parent's method"
子组件模板定义属于子组件作用域,点击这个部分,会调用子组件方法,输出"It is the child's method"

插口作用域

在内容分发的过程中,父组件分发的内容可以使用定义在子组件模板<slot>上的属性(即插口作用域上定义的属性)。如<slot slotval="值"></slot>,在父组件分发内容上,可以通过slot-scope="obj"获取到所有在插口上定义的属性,通过{{obj.slotval}}就可以在slot-scope内部使用这个数据。
特殊的,在<template>标签中使用slot-scope<template>自身是不会在页面上显示,只起到传递数据媒介的作用。

new Vue({
el: '#app-5',
components: {
"component-5":{
template: '<div class="child">\
<slot slotvala="a、来自插口作用域上的数据" slotvalb="b、来自插口作用域上的数据"></slot>\
</div>'
}
}
})
<div id="app-5">
<component-5>
<!--这里可以是其他标签,但会被渲染到页面,如<div slot-scope="">-->
<template slot-scope="slot_data_obj">
<span>{{slot_data_obj.slotvala}}</span>
<span>{{slot_data_obj.slotvalb}}</span>
</template>
</component-5>
</div>

由于slot-scope的值本质上只是个javascript对象,因此可以使用es6的解构语法进行<slot>属性的映射。
以上又可以怎么写

<template slot-scope="{slotvala,slotvalb}">
<span>{{slotvala}}</span>
<span>{{slotvalb}}</span>
</template>

插口作用域应用在列表上

插口不仅可以通过自身属性传递数据给分发的内容,还可以在其上定义v-for指令,从而将迭代的特性也传递给分发的内容。

new Vue({
el: '#app-6',
components: {
"component-6":{
data:function(){
return {
items: [
{id:1,text:"哪都通快递"},
{id:2,text:"龙虎山天师府"},
{id:3,text:"曜星社"}
]
}
},
template: '\
<ul>\
<slot name="item" v-for="item in items" v-bind:text="item.text" v-bind:id="item.id"></slot>\
</ul>'
}
}
})
<div id="app-6">
<component-6>
<li slot="item" slot-scope="{text,id}">
{{ id+"、"+text }}
</li>
</component-6>
</div>

内容分发中的<li>被插入slot中,并且因为slot中的v-for指令而进行迭代,迭代之后通过slot-scope获取slot上的属性数据。

内联模板

当使用子组件的内联特性——inline-template时,父组件的内容分发部分就被解释为子组件的模板,而子组件的template属性也将被这个部分取代(取代后template失效),并且作用域也属于子组件。

new Vue({
el:'#app-8',
components:{
'component-8':{
template:'...'//全部被替换
data:function(){
return {
childMsg:'child\'s data'
}
} }
}
})
<div id="app-8">
<component-8 inline-template>
<div>
<p>这些将作为组件自身的模板。</p>
<p>而非父组件透传进来的内容。</p>
<p>子组件数据: {{ childMsg }}</p>
</div>
</component-8>
</div>

"child's data"来自子组件的childMsg

由于其特点,在使用内联模板时,最容易产生的误区就是混淆作用域。

组件(4):使用slot进行内容分发的更多相关文章

  1. Vue slot插槽内容分发

    slot插槽使用 使用场景,一般父组件中又一大段模板内容需要运用到子组件上.或者更加复杂的,子组件需要运用到父组件大段模板内容,而子组件却不知道挂载的内容是什么.挂载点的内容是由父组件来决定的. Sl ...

  2. vue组件4 利用slot将内容传递给组件

    除了将数据作为prop传入到组件中,vue也允许传入HTML 父组件中的子组件:<custom-button>点我<custom-button/> custom-button子 ...

  3. Vuejs——(11)组件——slot内容分发

    版权声明:出处http://blog.csdn.net/qq20004604   目录(?)[+]   本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...

  4. 044——VUE中组件之使用内容分发slot构建bootstrap面板panel

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Vue内容分发slot

    前面的话 为了让组件可以组合,需要一种方式来混合父组件的内容与子组件自己的模板.这个过程被称为 内容分发 (或 “transclusion” ).Vue实现了一个内容分发 API,参照了当前 Web ...

  6. Vue一个案例引发「内容分发slot」的最全总结

    今天我们继续来说说 Vue,目前一直在自学 Vue 然后也开始做一个项目实战,我一直认为在实战中去发现问题然后解决问题的学习方式是最好的,所以我在学习一些 Vue 的理论之后,就开始自己利用业余时间做 ...

  7. Vue中的slot内容分发

    ①概述: 简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示.不显示.在哪个地方显示.如何显示,就是slot分发负责的活. ②默认情况下 父组件在子组件内套的内容,是不显示的. 例如 ...

  8. slot内容分发

    vue实现了一套内容分发的API,这套API基于当前的web components规范草案,将<slot>元素作为承载分发内容的出口. 在前面的父子组件中,我们提到过,在vue中,组件实例 ...

  9. Vue 内容分发slot

    1.概述 内容分发:混合父组件的内容与子组件自己的模板. 2.单个插槽 当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,并替换掉插槽标签本身. 最初在  ...

随机推荐

  1. 03-Java的基础语法

    一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.下面简要介绍下类.对象.方法和实例变量的概念. 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个对象,它的 ...

  2. Rx系列---响应式编程

    Rx是ReactiveX的简称,翻译过来就是响应式编程 首先要先理清这么一个问题:Rxjava和我们平时写的程序有什么不同.相信稍微对Rxjava有点认知的朋友都会深深感受到用这种方式写的程序和我们一 ...

  3. 吴裕雄--天生自然 JAVASCRIPT开发学习:JavaScript 对象 实例

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. LeetCode No.82,83,84

    No.82 DeleteDuplicates 删除排序链表中的重复元素 II 题目 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 输入: 1->2 ...

  5. CentOS换yum源和epel源为国内源

    CentOS换源 YUM源 备份原来的repo文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bac ...

  6. django的orm介绍以及静态文件介绍

    1 django中app的概念 大学:----------------- 项目 信息学院 ----------app01 物理学院-----------app02*强调:创建了app,要在配置文件中注 ...

  7. 渗透利器-BadUSB 控制外网主机详解 Teensy2.0++

    准备工作 一块 Teensy2.0++ 的板子(淘宝一搜就有) Arduino编译器 1.8.7版本下载连接:arduino下载地址 Teensy插件 下载连接:Teensy下载地址 [外链图片转存失 ...

  8. Adam项目展示微软研究院人工智能领域新突破

    编者按:在美国时间7月14日举行的2014年微软教育峰会上,Adam项目面对牵上台的3只小狗,一一准确地报出了它们的品种.Adam项目代表了微软研究院在机器学习和人工智能领域的前沿进展.它可不仅仅认得 ...

  9. mudbox安装未完成,某些产品无法安装的解决方法

    mudbox提示安装未完成,某些产品无法安装该怎样解决呢?,一些朋友在win7或者win10系统下安装mudbox失败提示mudbox安装未完成,某些产品无法安装,也有时候想重新安装mudbox的时候 ...

  10. 常胜将军的深思变局:OPPO的渐变释放了怎样的行业信号?

    在经过了前几年的狂飙突进后,当下手机行业已经步入了自身的"十年之痒"阶段.利润贴地飞行.T型格局已定且竞争者实力愈强.创新不明显导致消费者换新驱动力降低.全球化竞争趋势凸显-- 也 ...