slot内容分发
vue实现了一套内容分发的API,这套API基于当前的web components规范草案,将<slot>元素作为承载分发内容的出口。
在前面的父子组件中,我们提到过,在vue中,组件实例的作用域是孤立的,默认情况下,父子组件的数据是不能共享的。所以子组件的内容应当写在子组件里面,父组件的内容应该写在父组件里面,下面的这种情况。父组件的内容将会被默认丢弃。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="box">
<aaa></aaa>
</div> <template id="aaa">
<div class="parent">
<p>父组件</p>
<bbb>
<p>测试内容1</p>
<p>测试内容2</p>
<p>测试内容3</p>
</bbb>
</div>
</template>
<script>
var vm=new Vue({
el:'#box',
data:{
a:'aaa'
},
components:{
'aaa':{
data(){
return {
msg2:'我是父组件的数据'
}
},
template:'#aaa',
components:{
'bbb':{
template:`
<div class="child">
<p>子组件</p>
</div>
`,
}
}
}
}
});
</script>
</body>
</html>

此时,如果我们希望上面的内容不被丢弃,就需要使用到一个特殊的<slot>元素作为元素内容的插槽。
匿名slot
当子组件模板中只有一个没有属性的slot时,父组件整个的内容都将插入到slot所在的位置,直接替换掉slot标签。需要注意的是,匿名slot最多只能有一个,多个匿名slot会导致程序报错。
<div id="box">
<aaa></aaa>
</div> <template id="aaa">
<div class="parent">
<p>父组件</p>
<bbb>
<p>测试内容1</p>
<p>测试内容2</p>
<p>测试内容3</p>
</bbb>
</div>
</template>
<script>
var vm=new Vue({
el:'#box',
data:{
a:'aaa'
},
components:{
'aaa':{
data(){
return {
msg2:'我是父组件的数据'
}
},
template:'#aaa',
components:{
'bbb':{
template:`
<div class="child">
<p>子组件</p>
<slot></slot>
</div>
`,
}
}
}
}
});
</script>

我们可以在slot标签中添加任何内容作为默认值,在上面我们说的是,父组件的整个内容会替换到slot,所以,如果父组件中是有需要插入的内容是,这些默认值会随着slot被替换而替换掉,只有当父组件里面没有内容时,才会显示这些默认值。
<div id="box">
<aaa></aaa>
</div>
<template id="aaa">
<div class="parent">
<p>父组件</p>
<bbb></bbb>
</div>
</template>
<script>
var vm=new Vue({
el:'#box',
data:{
a:'aaa'
},
components:{
'aaa':{
data(){
return {
msg2:'我是父组件的数据'
}
},
template:'#aaa',
components:{
'bbb':{
template:`
<div class="child">
<p>子组件</p>
<slot><div>我是默认值</div></slot>
</div>
`,
}
}
}
}
});
</script>

实名slot
有匿名slot,自然就像到了不是匿名的slot,这一类slot可以用一个特殊的属性name来配置内容分发,根据name来匹配内容片段中有对应slot特性的元素。可以有多个不同名字的slot同时存在,并且此时也可以有一个匿名slot,作为找不到匹配的内容片段的备用插槽。
<div id="box">
<aaa></aaa>
</div> <template id="aaa">
<div class="parent">
<p>父组件</p>
<bbb>
<p slot="my-header">我是头部</p>
<p slot="my-footer">我是尾部</p>
<p>我是主体1</p>
<p>我是主体2</p>
<p>我是主体3</p>
</bbb>
</div>
</template>
<script>
var vm=new Vue({
el:'#box',
data:{
a:'aaa'
},
components:{
'aaa':{
data(){
return {
msg2:'我是父组件的数据'
}
},
template:'#aaa',
components:{
'bbb':{
template:`
<div class="child">
<p>子组件</p>
<slot name="my-header">头部默认值</slot>
<slot name="my-body">主体默认值</slot>
<slot name="my-footer">尾部默认值</slot>
<slot></slot>
</div>
`,
}
}
}
}
});
</script>

我们来分析一下上面代码的执行过程。
- 首先是名字为"my-header"的slot在父组件中寻找对应的slot,即<p slot="my-header">我是头部</p>并进行渲染。
- 接着是名字为"my-body"的slot在父组件中寻找对应的slot,并没有找到,所以显示的是自己的默认值。
- 然后是名字为"my-footer"的slot在父组件中寻找,同第一步一样。
- 此时,所有实名的slot都已经寻找完了,如果没有匿名slot,那么父组件中剩余没有匹配的内容都会被丢弃,但这个里面是有一个匿名slot的,所以它会寻找到父组件中所有不带slot属性的元素,然后替换自己,进行渲染。
- 最后,在父组件中还有一个有slot属性却没有匹配的slot的元素,将会被丢弃。
在上面的例子中,当我们将最后的匿名slot删除,那么所有没有slot属性的元素也都会被丢弃。

组件列表
slot还能被用作一个可以重复使用的模板来渲染列表,此时需要在子组件中将数据传递到slot插槽中,然后在父组件中使用带scope的<template>元素作为模板,其中的scope则是被用来接收从子组件中传递过来的数据,然后就可以实现循环渲染列表了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="box">
<aaa></aaa>
</div> <template id="aaa">
<div class="parent">
<p>父组件</p>
<bbb>
<template slot="item" scope="props">
<li>{{ props.text }}</li>
</template>
</bbb>
</div>
</template>
<script>
var vm=new Vue({
el:'#box',
data:{
a:'aaa'
},
components:{
'aaa':{
data(){
return {
msg2:'我是父组件的数据'
}
},
template:'#aaa',
components:{
'bbb':{
template:`
<ul>
<slot name="item" v-for="item in items" :text="item.text">默认值</slot>
</ul>
`,
data(){
return{
items:[
{id:1,text:'苹果'},
{id:2,text:'香蕉'},
{id:3,text:'葡萄'},
]
}
}
}
}
}
}
});
</script>
</body>
</html>

slot内容分发的更多相关文章
- Vue中slot内容分发
<slot>元素是一个内容分发API,使用多个内容插槽时可指定name属性 <!DOCTYPE html> <html> <head> <meta ...
- vue slot内容分发
当需要让组件组合使用,混合父组件的内容和子组件的模板的时候,就会用到slot.这个过程就叫内容分发. 最为常用的是两种slot:一种是匿名slot, 一种是具名slot. 匿名 很好理解: 就是默认, ...
- 玩转vue的slot内容分发
vue的内容分发非常适合"固定部分+动态部分"的组件的场景,固定部分可以是结构固定,也可以是逻辑固定,比如下拉loading,下拉loading只是中间内容是动态的,而拉到底部都会 ...
- Vue中的slot内容分发
①概述: 简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示.不显示.在哪个地方显示.如何显示,就是slot分发负责的活. ②默认情况下 父组件在子组件内套的内容,是不显示的. 例如 ...
- Vuejs——(11)组件——slot内容分发
版权声明:出处http://blog.csdn.net/qq20004604 目录(?)[+] 本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...
- Vuejs——slot内容分发
①概述: 简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示.不显示.在哪个地方显示.如何显示,就是slot分发负责的活. ②默认情况下父组件在子组件内套的内容,是不显示的. 例如代 ...
- vue2.0 之 slot 内容分发
前提:父组件模板的内容在父组件作用域内编译:子组件模板的内容在子组件作用域内编译.被分发的内容会在父作用域内编译. 一.单个插槽 // 子组件模板 child-component <div> ...
- Vue内容分发slot
前面的话 为了让组件可以组合,需要一种方式来混合父组件的内容与子组件自己的模板.这个过程被称为 内容分发 (或 “transclusion” ).Vue实现了一个内容分发 API,参照了当前 Web ...
- Vue一个案例引发「内容分发slot」的最全总结
今天我们继续来说说 Vue,目前一直在自学 Vue 然后也开始做一个项目实战,我一直认为在实战中去发现问题然后解决问题的学习方式是最好的,所以我在学习一些 Vue 的理论之后,就开始自己利用业余时间做 ...
随机推荐
- draw graph
http://www.icl.pku.edu.cn/member/yujs/bsdfiles/html/mpost.htmlUNIX下绘图面面观 http://www.tug.org/metapost ...
- AangularJS入门总结一
CRUD(增加Create.查询Retrieve.更新Update.删除Delete) 一.angularjs是为了克服HTML在构建应用上的不足而设计的: 二.AngularJS的出众之处: 构建一 ...
- 求两个数之间的质数 -----------基于for循环 算法思想
前端代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.as ...
- LG4091 【[HEOI2016/TJOI2016]求和】
前置:第二类斯特林数 表示把\(n\)个小球放入\(m\)个不可区分的盒子的方案数 使用容斥原理分析,假设盒子可区分枚举至少有几个盒子为空,得到通项: \[S(n,m)=\frac{1}{m!}\su ...
- LG4213 【【模板】杜教筛(Sum)】
sum\(\mu\)求法 设 \[S(n)=\sum_{i=1}^n \mu(i)\] 回顾公式 \[\sum_{d|n}\mu(d)=[n=1]\] 对\(n\)求和 \[\sum_{i=1}^n\ ...
- linux 文件管理操作入门
mkdir -p /root/kali/bp/shell 一路创建文件夹直到生成文件夹shell,中间没有kali文件夹的话也会自动创建生成 tar解压缩 范例一:将整个 /etc 目录下的文件全部 ...
- vernemq 集群 docker-compose 搭建简单试用
vernemq 是一款开源的mqtt broker, 支持cluster 模式部署,而且部署比较简单 以下是一个使用docker-compose 搭建环境的demo 环境准备 docker-compo ...
- C#窗体模拟键盘按键(组合键)产生事件 ---- 通过keybd_event()函数
如何模拟键盘按键触发产生的事件,比如模拟按下Alt + F4 关闭当前程序,Ctrl+Shift 切换输入法等 可以通过win32api 键盘事件 keybd_event() 来实现 1.定义键盘按键 ...
- xlsx 库 知识点
官方github地址:https://github.com/SheetJS/js-xlsx xlsx 用webpack打包后体积太大: vue-cli构建的项目,优化办法:https://segmen ...
- java标识字
JAVA中,标识符, 指用于给变量.类.方法名 等命名的名称. 1,标识以数字,字符,下划线,以及美元$符组成.(不能包括@.%.空格等),不能以数字开头. 2,不能与JAVA关键字重复 3,严格区分 ...