深入理解vue中的slot与slot-scope


Posted in Javascript onApril 22, 2019

写在前面

vue中关于插槽的文档说明很短,语言又写的很凝练,再加上其和methods,data,computed等常用选项使用频率、使用先后上的差别,这就有可能造成初次接触插槽的开发者容易产生“算了吧,回头再学,反正已经可以写基础组件了”,于是就关闭了vue说明文档。

实际上,插槽的概念很简单,下面通过分三部分来讲。这个部分也是按照vue说明文档的顺序来写的。

进入三部分之前,先让还没接触过插槽的同学对什么是插槽有一个简单的概念:插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示、以及怎样显示由父组件来决定。 实际上,一个slot最核心的两个问题这里就点出来了,是显示不显示和怎样显示。

由于插槽是一块模板,所以,对于任何一个组件,从模板种类的角度来分,其实都可以分为非插槽模板和插槽模板两大类。
非插槽模板指的是html模板,指的是‘div、span、ul、table'这些,非插槽模板的显示与隐藏以及怎样显示由插件自身控制;插槽模板是slot,它是一个空壳子,因为它显示与隐藏以及最后用什么样的html模板显示由父组件控制。但是插槽显示的位置确由子组件自身决定,slot写在组件template的哪块,父组件传过来的模板将来就显示在哪块。

单个插槽 | 默认插槽 | 匿名插槽

首先是单个插槽,单个插槽是vue的官方叫法,但是其实也可以叫它默认插槽,或者与具名插槽相对,我们可以叫它匿名插槽。因为它不用设置name属性。

单个插槽可以放置在组件的任意位置,但是就像它的名字一样,一个组件中只能有一个该类插槽。相对应的,具名插槽就可以有很多个,只要名字(name属性)不同就可以了。

下面通过一个例子来展示。

父组件:

<template>
 <div class="father">
  <h3>这里是父组件</h3>
  <child>
   <div class="tmpl">
    <span>菜单1</span>
    <span>菜单2</span>
    <span>菜单3</span>
    <span>菜单4</span>
    <span>菜单5</span>
    <span>菜单6</span>
   </div>
  </child>
 </div>
</template>

子组件:

<template>
 <div class="child">
  <h3>这里是子组件</h3>
  <slot></slot>
 </div>
</template>

在这个例子里,因为父组件在<child></child>里面写了html模板,那么子组件的匿名插槽这块模板就是下面这样。也就是说,子组件的匿名插槽被使用了,是被下面这块模板使用了。

<div class="tmpl">
 <span>菜单1</span>
 <span>菜单2</span>
 <span>菜单3</span>
 <span>菜单4</span>
 <span>菜单5</span>
 <span>菜单6</span>
</div>

最终的渲染结果如图所示:

深入理解vue中的slot与slot-scope

注:所有demo都加了样式,以方便观察。其中,父组件以灰色背景填充,子组件都以浅蓝色填充。

具名插槽

匿名插槽没有name属性,所以是匿名插槽,那么,插槽加了name属性,就变成了具名插槽。具名插槽可以在一个组件中出现N次。出现在不同的位置。下面的例子,就是一个有两个具名插槽和单个插槽的组件,这三个插槽被父组件用同一套css样式显示了出来,不同的是内容上略有区别。

父组件:

<template>
 <div class="father">
 <h3>这里是父组件</h3>
 <child>
  <div class="tmpl" slot="up">
  <span>菜单1</span>
  <span>菜单2</span>
  <span>菜单3</span>
  <span>菜单4</span>
  <span>菜单5</span>
  <span>菜单6</span>
  </div>
  <div class="tmpl" slot="down">
  <span>菜单-1</span>
  <span>菜单-2</span>
  <span>菜单-3</span>
  <span>菜单-4</span>
  <span>菜单-5</span>
  <span>菜单-6</span>
  </div>
  <div class="tmpl">
  <span>菜单->1</span>
  <span>菜单->2</span>
  <span>菜单->3</span>
  <span>菜单->4</span>
  <span>菜单->5</span>
  <span>菜单->6</span>
  </div>
 </child>
 </div>
</template>

子组件:

<template>
 <div class="child">
 // 具名插槽
 <slot name="up"></slot>
 <h3>这里是子组件</h3>
 // 具名插槽
 <slot name="down"></slot>
 // 匿名插槽
 <slot></slot>
 </div>
</template>

显示结果如图:

深入理解vue中的slot与slot-scope

可以看到,父组件通过html模板上的slot属性关联具名插槽。没有slot属性的html模板默认关联匿名插槽。

作用域插槽 | 带数据的插槽

最后,就是我们的作用域插槽。这个稍微难理解一点。官方叫它作用域插槽,实际上,对比前面两种插槽,我们可以叫它带数据的插槽。什么意思呢,就是前面两种,都是在组件的template里面写

匿名插槽

<slot></slot>

具名插槽

<slot name="up"></slot>

但是作用域插槽要求,在slot上面绑定数据。也就是你得写成大概下面这个样子。

<slot name="up" :data="data"></slot>
 export default {
 data: function(){
  return {
  data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
  }
 },
}

我们前面说了,插槽最后显示不显示是看父组件有没有在child下面写模板,像下面那样。

<child>
 html模板
</child>

写了,插槽就总得在浏览器上显示点东西,东西就是html该有的模样,没写,插槽就是空壳子,啥都没有。
OK,我们说有html模板的情况,就是父组件会往子组件插模板的情况,那到底插一套什么样的样式呢,这由父组件的html+css共同决定,但是这套样式里面的内容呢?

正因为作用域插槽绑定了一套数据,父组件可以拿来用。于是,情况就变成了这样:样式父组件说了算,但内容可以显示子组件插槽绑定的。

我们再来对比,作用域插槽和单个插槽和具名插槽的区别,因为单个插槽和具名插槽不绑定数据,所以父组件是提供的模板要既包括样式由包括内容的,上面的例子中,你看到的文字,“菜单1”,“菜单2”都是父组件自己提供的内容;而作用域插槽,父组件只需要提供一套样式(在确实用作用域插槽绑定的数据的前提下)。

下面的例子,你就能看到,父组件提供了三种样式(分别是flex、ul、直接显示),都没有提供数据,数据使用的都是子组件插槽自己绑定的那个人名数组。

父组件:

<template>
 <div class="father">
 <h3>这里是父组件</h3>
 <!--第一次使用:用flex展示数据-->
 <child>
  <template slot-scope="user">
  <div class="tmpl">
   <span v-for="item in user.data">{{item}}</span>
  </div>
  </template>
 </child>
 <!--第二次使用:用列表展示数据-->
 <child>
  <template slot-scope="user">
  <ul>
   <li v-for="item in user.data">{{item}}</li>
  </ul>
  </template>
 </child>
 <!--第三次使用:直接显示数据-->
 <child>
  <template slot-scope="user">
  {{user.data}}
  </template>
 </child>
 <!--第四次使用:不使用其提供的数据, 作用域插槽退变成匿名插槽-->
 <child>
  我就是模板
 </child>
 </div>
</template>

子组件:

<template>
 <div class="child">

 <h3>这里是子组件</h3>
 // 作用域插槽
 <slot :data="data"></slot>
 </div>
</template>

 export default {
 data: function(){
  return {
  data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
  }
 }
}

结果如图所示:

深入理解vue中的slot与slot-scope

github

以上三个demo就放在GitHub了,有需要的可以去取。使用非常方便,是基于vue-cli搭建工程。

地址点这里

最后

如果本文对你理解slot和scope-slot有帮助,请不要吝啬手中的点赞哟。

总结

以上所述是小编给大家介绍的vue中的slot与slot-scope,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
jQuery live( type, fn ) 委派事件实现
Oct 11 Javascript
给事件响应函数传参数的四种方式小结
Dec 05 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
Oct 12 Javascript
Bootstrap 组件之按钮(二)
May 11 Javascript
JS+CSS3实现超炫的散列画廊特效
Jul 16 Javascript
node.js实现博客小爬虫的实例代码
Oct 08 Javascript
微信小程序 wxapp内容组件 progress详细介绍
Oct 31 Javascript
浅谈JavaScript的innerWidth与innerHeight
Oct 12 Javascript
bootstrap Table的一些小操作
Nov 01 Javascript
Vue进度条progressbar组件功能
Apr 17 Javascript
浅谈Vue的响应式原理
May 30 Javascript
详解Nuxt.js 实战集锦
Nov 19 Javascript
浅析vue插槽和作用域插槽的理解
Apr 22 #Javascript
详解50行代码,Node爬虫练手项目
Apr 22 #Javascript
Vue匿名插槽与作用域插槽的合并和覆盖行为
Apr 22 #Javascript
详解Vue 匿名、具名和作用域插槽的使用方法
Apr 22 #Javascript
详解Node.js一行命令上传本地文件到服务器
Apr 22 #Javascript
使用 vue 实例更好的监听事件及vue实例的方法
Apr 22 #Javascript
Angular中使用ng-zorro图标库部分图标不能正常显示问题
Apr 22 #Javascript
You might like
正义联盟的终局之战《天启星战争》将成为DC动画宇宙的最后一部
2020/04/09 欧美动漫
php 什么是PEAR?
2009/03/19 PHP
通过5个php实例细致说明传值与传引用的区别
2012/08/08 PHP
php 反斜杠处理函数addslashes()和stripslashes()实例详解
2016/12/25 PHP
thinkphp实现附件上传功能
2017/05/26 PHP
JQuery困惑—包装集 DOM节点
2009/10/16 Javascript
JavaScript 保存数组到Cookie的代码
2010/04/14 Javascript
基于JQuery的类似新浪微博展示信息效果的代码
2012/07/23 Javascript
Javascript学习笔记之 函数篇(二) : this 的工作机制
2014/06/24 Javascript
ionic2懒加载配置详解
2017/09/01 Javascript
React 使用browserHistory项目访问404问题解决
2018/06/01 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
2018/08/22 Javascript
JavaScript fetch接口案例解析
2018/08/30 Javascript
Vue 通过自定义指令回顾v-内置指令(小结)
2018/09/03 Javascript
详解javascript对数组和json数组的操作
2019/04/15 Javascript
python 正则表达式 概述及常用字符
2009/05/04 Python
python实现报表自动化详解
2017/11/16 Python
python中datetime模块中strftime/strptime函数的使用
2018/07/03 Python
python用插值法绘制平滑曲线
2021/02/19 Python
python实现flappy bird游戏
2018/12/24 Python
Python socket聊天脚本代码实例
2020/01/02 Python
Django-xadmin+rule对象级权限的实现方式
2020/03/30 Python
python如何调用java类
2020/07/05 Python
PyCharm 2020.1版安装破解注册码永久激活(激活到2089年)
2020/09/24 Python
Python字典实现伪切片功能
2020/10/28 Python
利用python爬取有道词典的方法
2020/12/08 Python
10张动图学会python循环与递归问题
2021/02/06 Python
CSS3 实现的缩略图悬停效果
2020/12/09 HTML / CSS
英国排名第一的礼品体验公司:Red Letter Days
2018/08/16 全球购物
台湾全方位线上课程与职能学习平台:TibaMe
2019/12/04 全球购物
煤矿安全生产标语
2014/06/06 职场文书
刑事辩护授权委托书格式
2014/10/13 职场文书
群众路线个人整改措施
2014/10/24 职场文书
《吃水不忘挖井人》教学反思
2016/02/22 职场文书
浅谈Python数学建模之线性规划
2021/06/23 Python
JavaWeb Servlet开发注册页面实例
2022/04/11 Java/Android