深入理解vue中slot与slot-scope的具体使用


Posted in Javascript onJanuary 26, 2018

写在前面

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搭建工程。

地址点这里

最后

希望本文所述对你有所帮助,vue中slot与slot-scope的具体使用就给大家介绍到这里了。希望大家继续关注我们的网站!

Javascript 相关文章推荐
js当一个变量为函数时 应该注意的一点细节小结
Dec 29 Javascript
JQuery表单验证插件EasyValidator用法分析
Nov 15 Javascript
学习jQuey中的return false
Dec 18 Javascript
jQuery 3.0 的变化及使用方法
Feb 01 Javascript
JS键盘版计算器的制作方法
Dec 03 Javascript
JavaScript实现弹窗效果代码分析
Mar 09 Javascript
关于Node.js的events.EventEmitter用法介绍
Apr 01 Javascript
Vue中定义全局变量与常量的各种方式详解
Aug 23 Javascript
JS表单传值和URL编码转换
Mar 03 Javascript
mpvue中配置vuex并持久化到本地Storage图文教程解析
Mar 15 Javascript
判断iOS、Android以及PC端的示例代码
Nov 15 Javascript
原生JS无缝滑动轮播图
Oct 22 Javascript
从零开始最小实现react服务器渲染详解
Jan 26 #Javascript
微信小程序模版渲染详解
Jan 26 #Javascript
微信小程序如何获取用户信息
Jan 26 #Javascript
vue实现前进刷新后退不刷新效果
Jan 26 #Javascript
Vue2.5 结合 Element UI 之 Table 和 Pagination 组件实现分页功能
Jan 26 #Javascript
微信小程序实现图片压缩功能
Jan 26 #Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
Jan 25 #Javascript
You might like
PHP调用VC编写的COM组件实例
2014/03/29 PHP
php session实现多级目录存放实现代码
2016/02/03 PHP
php intval函数用法总结
2019/04/14 PHP
php输出形式实例整理
2020/05/05 PHP
调用js时ie6和ie7,ff的区别
2009/08/19 Javascript
JS 事件绑定函数代码
2010/04/28 Javascript
原创javascript小游戏实现代码
2010/08/19 Javascript
关于javascript中this关键字(翻译+自我理解)
2010/10/20 Javascript
jQuery+.net实现浏览更多内容(改编php版本)
2013/03/28 Javascript
avascript中的自执行匿名函数应用示例
2014/09/15 Javascript
jQuery之DOM对象和jQuery对象的转换与区别分析
2015/01/08 Javascript
JavaScript中数据类型转换总结
2016/12/25 Javascript
基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式
2018/01/17 Javascript
用vue写一个仿简书的轮播图的示例代码
2018/03/13 Javascript
Vue中的混入的使用(vue mixins)
2018/06/01 Javascript
看看“疫苗查询”小程序有温度的代码
2018/07/31 Javascript
vue列表单项展开收缩功能之this.$refs的详解
2019/05/05 Javascript
微信小程序在ios下Echarts图表不能滑动的问题解决
2019/07/10 Javascript
js设置默认时间跨度过程详解
2019/07/17 Javascript
Layui 带多选框表格监听事件以及按钮自动点击写法实例
2019/09/02 Javascript
vue学习笔记之slot插槽基本用法实例分析
2020/02/01 Javascript
[26:50]2018完美盛典DOTA2表演赛
2018/12/17 DOTA
python opencv 直方图反向投影的方法
2018/02/24 Python
tensorflow 加载部分变量的实例讲解
2018/07/27 Python
Python GUI编程 文本弹窗的实例
2019/06/11 Python
python和c语言的主要区别总结
2019/07/07 Python
Python3实现mysql连接和数据框的形成(实例代码)
2020/01/17 Python
python删除某个目录文件夹的方法
2020/05/26 Python
简单了解Python多态与属性运行原理
2020/06/15 Python
建筑个人求职信范文
2014/01/25 职场文书
金融学专科生自我鉴定
2014/02/21 职场文书
老同学聚会感言
2014/02/23 职场文书
小学语文课后反思精选
2014/04/25 职场文书
工作失误检讨书(经典集锦版)
2014/10/17 职场文书
2015年国庆节广播稿
2015/08/19 职场文书
Python机器学习三大件之一numpy
2021/05/10 Python