VUE的插槽(slot和slot-scope)
前言
在之前的获取当前行数据中,最终的方案是使用了slot-scope="scope"的方式获取了当前行的数据,当时对slot-scope是个什么东东不了解。这两天查看了好多资料,有点明白了这个插槽是个什么东西。但是理解的不深,可能有错,先记下来,就当是整理一下思路。
什么是插槽
Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将
<slot>
元素作为承载分发内容的出口。
这是官方文档对插槽的介绍,看了介绍后,还是忍不住想问:这TM是什么玩意儿。结合官方文档中对插槽的介绍和demo,我自己有了一点理解,不过在说我的理解之前,还需要先说说几个概念。
首先就是组件。在VUE中,一个.vue文件就是一个组件,一个标签也是一个组件。不同之处就在于:.vue文件是自己写的组件,用Java做个对照,就如同你写的一个.java文件,比如叫个Student.java或者Teacher.java;标签是官方定义的组件,在Java中,就好像是String、Integer、Character这样的存在。
然后就是父组件和子组件。这个就简单了:A组件里面引用了B组件,那么A就是父组件,B就是子组件。
再接着说插槽。在我的理解中,插槽就是要将父组件中的内容渲染到子组件中。就好像是在子组件中留了一个空的位置(就像小霸王上的插卡口),然后把父组件中的内容插进去(你的游戏卡盘)。
A.vue把B.vue注册成为新的组件当做标签用,并在B标签中写了一些内容,然后在B.vue中用<slot></slot>
把A.vue中B标签里的内容渲染出来。
插槽详解
准备工作
首先我准备了两个组件:defaultSlot.vue和childSlot.vue。
defaultSlot.vue中注册了childSlot.vue:
<script>import ChildSlot from '../../views/slot/childSlot'export default {name: "defaultSlot",components: {ChildSlot}}
</script>
在官方文档中,插槽有三种:单个插槽、具名插槽、作用域插槽。
单个插槽
光从现象上来看,单个插槽(或者叫默认插槽,或者叫匿名插槽)和具名插槽是比较好理解的。
我已经在defaultSlot.vue中新注册了一个childSlot组件,现在我要在这个标签中写一点东西:
defaultSlot.vue中的代码
<template><div style="width: 600px; text-align: left;"><div style="background: peru">这段话也是来自defaultSlot.vue,但它写在<code>ChildSlot</code>标签上面,因此,虽然他会有一个棕色的背景色,但不会被红色边框圈起来。</div><ChildSlot><div style="background: aquamarine">这是插槽的练习。这段话来自defaultSlot.vue,且会有一个浅绿色的背景色。本页面引入了childSlot.vue;而childSlot.vue中有一个<code>slot</code>标签,因此,在这段话的上面,还会显示childSlot.vue中的内容。而如果注释掉childSlot.vue中的<code>slot</code>标签,则本段内容不显示。因为这段话写在<code>ChildSlot</code>标签中,因此,它也会被一个红色的边框圈起来。</div></ChildSlot><div style="background: gray">这段话也是来自defaultSlot.vue,但它写在<code>ChildSlot</code>标签下面,因此,虽然他会有一个灰色的背景色,但不会被红色边框圈起来。</div></div> </template> <script>import ChildSlot from '../../views/slot/childSlot'export default {name: "defaultSlot",components: {ChildSlot}} </script>
在childSlot.vue中,添加了一个插槽slot
:
childSlot.vue中的代码
<template><div style="border: 2px solid red;">这是childSlot.vue中的内容,他会被一个红色的边框圈起来<br/></div> </template> <script>export default {name: "childSlot"} </script>
那么在浏览器中的渲染结果是这样的:
可以发现,defaultSlot.vue中ChildSlot
标签中的内容并没有被渲染出来。为什么呢?很简单,childSlot.vue中还没有使用插槽。现在我们就添加一个插槽:
<template><div style="border: 2px solid red;">这是childSlot.vue中的内容,他会被一个红色的边框圈起来<br/><slot></slot></div>
</template>
然后再看页面:
defaultSlot.vue中ChildSlot
标签中的内容被渲染了。
让我们来总结一下:
defaultSlot.vue中注册了新的标签ChildSlot
,并在该标签中写入了内容。而在ChildSlot
标签的模板文件childSlot.vue中,使用了<slot></slote>
标签作为插槽,来渲染加载ChildSlot标签中的内容。
而上面这个<slot></slote>
标签,就叫做单个插槽。
具名插槽
具名插槽,就是对slot
标签设置name属性,从而来渲染指定的内容。
怎么玩呢?首先,要对defaultSlot.vue中ChildSlot
里的内容进行分块,每一个块都用一个dom装载;然后,给这些装载了内容的dom设置一个slot属性;最后,在childSlot.vue中,给slot
标签设置name属性,其属性值对应defaultSlot.vue中dom的slot属性值,这样,就会在这个slot
标签中渲染指定的那个dom块中的内容。如果defaultSlot.vue中没有对dom设置slot属性,则默认为slot=“default”,在childSlot.vue中,会被渲染在没有name属性的slot
标签的位置上。换句话说,下面这两行代码是等价的:
<slot></slot>
<slot name="default"></slot>
具名插槽的示例代码如下:
defaultSlot.vue中的代码:
<template><div style="width: 600px; text-align: left;"><div style="background: peru" id="test1">1. 这段话也是来自defaultSlot.vue,但它写在<code>ChildSlot</code>标签上面,因此,虽然他会有一个棕色的背景色,但不会被红色边框圈起来。</div><ChildSlot url="你猜猜看"><div style="background: darkgreen" id="test2">kankan</div><div style="background:deeppink" slot="aaa" id="test3">4. aaa这段话写在另一个<code>ChildSlot</code>标签里,会有一个粉色的背景色。</div><div style="background: aquamarine" slot="show" id="test4">2. 这是插槽的练习。这段话来自defaultSlot.vue,且会有一个浅绿色的背景色。本页面引入了childSlot.vue;而childSlot.vue中有一个<code>slot</code>标签,因此,在这段话的上面,还会显示childSlot.vue中的内容。而如果注释掉childSlot.vue中的<code>slot</code>标签,则本段内容不显示。因为这段话写在<code>ChildSlot</code>标签中,因此,它也会被一个红色的边框圈起来。</div><div style="background: beige" id="test5">5. 我就看看怎么显示我</div></ChildSlot><div style="background: gray" id="test6">6. 这段话也是来自defaultSlot.vue,但它写在<code>ChildSlot</code>标签下面,因此,虽然他会有一个灰色的背景色,但不会被红色边框圈起来。</div><ChildSlot><div id="test7">呵呵呵</div></ChildSlot></div> </template>
childSlot.vue中的代码:
<template><div style="border: 2px solid red;"><slot name="show"></slot><span id="test8">3. 这是childSlot.vue中的内容,他会被一个红色的边框圈起来<br/></span><slot name="aaa"></slot><slot></slot></div> </template>
页面的渲染结果如下图:
让我们来整理一下加载顺序:
首先,页面主要渲染的是defaultSlot.vue。因此,根据从上到下的渲染顺序,首先加载的就是id="test1"的div;
然后会加载<ChildSlot>
标签中的内容,所以要看childSlot.vue中具体是什么样的:
在childSlot.vue中,首先要加载的是name属性为show的部分,也就是id=test4的内容;
然后是id=test8的内容;
然后是name属性为aaa的部分,也就是id=test3的内容;
然后就是默认的slot,在这个<ChildSlot>
标签中,就指的是id=test2和id=test5的部分;
这时候,第一个<ChildSlot>
标签就渲染结束了,接下来就会加载id=test6的内容;
然后又是一个<ChildSlot>
标签,但这次这个标签中,并没有定义show和aaa,所以只显示默认的内容,因为<slot></slot>
写在<span>
标签下面,因此,先加载id=test8,再加载id=test7;
整个页面就加载完了,而具名插槽和单个插槽的区别应该也能理解了。
作用域插槽
作用域插槽,是为了从父组件中,通过使用注册的子组件标签,并对其属性slot-scope进行定义,从而使用子组件中绑定的数据。
比如我们先在childSlot.vue中,将数据绑定在<slot></slot>
标签上:
<template><div style="border: 2px solid red;"><slot :data="data"></slot></div>
</template>
<script>export default {name: "childSlot",data(){return{data:['张三','李四','王五','赵六','钱一','孙二']}}}
</script>
然后,我们就可以在defaultSlot.vue中,通过使用<ChildSlot></ChildSlot>
标签,来使用子组件中绑定的数据:
<template><div><ChildSlot><template slot-scope="s" slot="aaa"><ul><li v-for="item in s.data" :key="item">{{item}}</li></ul></template></ChildSlot></div></div>
</template>
<script>import ChildSlot from '../../views/slot/childSlot'export default {name: "defaultSlot",components: {ChildSlot}}
</script>
页面中的渲染结果如下:
让我们来总结一下:
首先在子组件中绑定数据;
然后在父组件中,通过slot-scope来把这个绑定的数据对象进行重命名;
这样就可以在父组件中使用子组件的数据了。
获取当前行的说明
那么再让我们回过头来看看此前获取当前行数据时,最后是怎么处理的:
<el-table-column label="操作" width="300" fixed="right"><template slot-scope="scope"><el-button type="text" @click="checkDetail(scope.row)">查看详情</el-button><el-button type="text" @click="editDengmi(scope.row)">编辑</el-button><el-button type="text" @click="deleteDengmi(scope.row)">删除</el-button></template>
</el-table-column>
结合前文所述,可以知道,这里是使用了作用域插槽,通过**slot-scope=“scope”**将el-table-column
标签中绑定的当前行的数据对象重命名为scope,进而再通过scope.row来获取当前行的数据。
查看el-table-column
的源文件,在加载之前,对变量其进行了初始化的操作:
然后在加载数据时,对row进行了赋值:
VUE的插槽(slot和slot-scope)相关推荐
- Vue中插槽-----特殊特性slot、slot-scope与指令v-slot的使用方法
1.slot作用/概念:预先将将来要使用的内容进行保留: 2.具名插槽:给slot起个名字 3.slot.slot-scope已经被废弃推荐使用vue2.6.0中的v-slot:但是这边还是对新旧方法 ...
- Vue.js插槽slot和作用域插槽slot-scope学习小结
一般来说,在Vue项目中使用父子组建时,都是把通用的HTML结构提取出来写成一个子组件,需要动态展示的数据用过prop属性传递,不过有时候我们可能想给子组件传递一个HTML代码,这个时候用prop不太 ...
- Vue —— 进阶插槽(slot)(默认插槽、具名插槽和作用域插槽)
Vue全家桶 系列文章目录 内容 参考链接 Vue2.x - 基础 Vue2.x - 基础 Vue2.x - 进阶(零) 初始化脚手架 Vue2.x - 进阶(一) refs属性.props配置项 V ...
- Vue的插槽slot的理解
Vue中插槽slot的理解 1.什么是插槽 2.插槽分类 单个插槽 具名插槽 作用域插槽 3.版本升级后 v-slot的用法 默认插槽还是使用,没有变化 具名插槽 作用域插槽 本文将从之前的slot. ...
- Vue中插槽slot的使用
插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示.以及怎样显示由父组件来决定. 实际上,一个slot最核心的两个问题在这里就点出来了,是显示不显示和怎样显示. 由于插槽是一块模板,所 ...
- slot属性值_深入理解vue中的slot与slot
作者/云荒杯倾 写在前面 vue中关于插槽的文档说明很短,语言又写的很凝练,再加上其和methods,data,computed等常用选项使用频率.使用先后上的差别,这就有可能造成初次接触插槽的开发者 ...
- 【Vue全家桶】细说slot
[Vue全家桶]细说slot 文章目录 [Vue全家桶]细说slot 前言 一.认识插槽Slot 1.1 插槽的基本使用 二.插槽的使用 2.1 默认内容 2.2 剧名插槽 2.3 作用域插槽 前言 ...
- 【Vue】Vue全家桶(三)Vue组件通信+Vue组件插槽+动画与过渡+使用vue-cli解决Ajax跨域问题
1 Vue组件通信 1.1 组件间通信基本原则 不要在子组件中直接修改父组件的状态数据 数据在哪, 更新数据的行为(函数)就应该定义在哪 1.2 vue 组件间通信方式 props vue 的自定义事 ...
- 【props单个数据绑定和多个数据绑定+vue默认插槽的基本使用+具名插槽的写法(2种)+插槽作用域3】
单个数据可以不用冒号,多个数据的传输需要用冒号,例如: <template><div class="layat"><Category :listDat ...
最新文章
- 20162325 金立清 S2 W8 C17
- Python3之多线程学习
- redis中执行lua脚本命令
- offsetLeft 解析
- SAP Cloud for Customer Lead OData服务的ETAG字段
- 2015年10月13日
- flash java 6,为Flash构建 Java WebService
- FusionInsight MRS:你的大数据“管家”
- AI绘画升温、AI写作降温,AIGC玩“变脸”
- 语音计算机在线算使用方法,计算器在线计算
- 参与流片是一种怎样的体验
- 从哪些方面评价一款在线客服系统产品
- ilo找不到服务器,云计算服务器忘记iLO登录账号的解决方法
- Error running SecureCardJavaApp. Command line is too long. Shorten the command line and rerun.
- 多CPU 多核CPU | 多进程 多线程 | 并行 并发
- Linux-002-常用命令02
- 教你如何在软文中设置关键词
- 公交线路图查询系统c语言,c语言公交最优路径查询数据结构(附设计报告_完整代码).doc...
- 北京非一卡通公司异型卡遭禁
- [白馬下載器] MiPony 1.2.0 多语言免费版
热门文章
- 87个C#帮助类,各种功能性代码(转载自微信公众号:dotNET全栈开发)
- 今日雨水——草木萌動
- Springboot整合ES地理位置查询
- 圣诞来袭,学编程的小伙伴收到圣诞老人礼物了?
- 云主机安全加固最佳实践指导书
- skynet框架应用 (一) skynet介绍
- matlab给图像加网格,matlab把图像进行网格化,或者是在图像中画网格
- G-Lexicographically Minimum Walk[CF-Gym-102391][2019-2020 XX Open Cup, Grand Prix of Korea]
- WinGate 6.0 build 984铪铪铪
- MySQL获取 查询上周的周一 查询上周的周日(星期日)查询本周的周一(星期一) 查询本周的周日(星期日)