深入理解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 相关文章推荐
JQuery 无废话系列教程(一) jquery入门 [推荐]
Jun 23 Javascript
document.body.scrollTop 值总为0的解决方法 比较常见的标准问题
Nov 30 Javascript
锋利的jQuery 要点归纳(一) jQuery选择器
Mar 21 Javascript
JQuery实现级联下拉框效果实例讲解
Sep 17 Javascript
JavaScript使用DeviceOne开发实战(三)仿微信应用
Dec 02 Javascript
使用JavaScript实现ajax的实例代码
May 11 Javascript
微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义实例
Dec 08 Javascript
Vue利用canvas实现移动端手写板的方法
May 03 Javascript
基于Vue实现关键词实时搜索高亮显示关键词
Jul 21 Javascript
解决bootstrap模态框数据缓存的问题方法
Aug 10 Javascript
微信小程序实现蒙版弹窗效果
Nov 01 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
Nov 13 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函数超时处理方法
2016/02/14 PHP
PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】
2017/01/13 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
php curl优化下载微信头像的方法总结
2018/09/07 PHP
javascript eval和JSON之间的联系
2009/12/31 Javascript
小议Javascript中的this指针
2010/03/18 Javascript
jQuery hover 延时器实现代码
2011/03/12 Javascript
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
2013/12/26 Javascript
JavaScript结合AJAX_stream实现流式显示
2015/01/08 Javascript
javascript中Date()函数在各浏览器中的显示效果
2015/06/18 Javascript
JS中dom0级事件和dom2级事件的区别介绍
2016/05/05 Javascript
详解如何用babel转换es6的class语法
2018/04/03 Javascript
Vue面试题及Vue知识点整理
2018/10/07 Javascript
vue 兄弟组件的信息传递的方法实例详解
2019/08/30 Javascript
JavaScript 类的封装操作示例详解
2020/05/16 Javascript
[02:20]2014DOTA2西雅图邀请赛 MVP外卡赛首胜采访
2014/07/09 DOTA
[22:59]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
使用python搭建Django应用程序步骤及版本冲突问题解决
2013/11/19 Python
浅谈PySpark SQL 相关知识介绍
2019/06/14 Python
pycharm设置默认的UTF-8编码模式的方法详解
2020/06/01 Python
纯css3实现宠物小鸡实例代码
2018/10/08 HTML / CSS
Java多态性的定义以及类型
2014/09/16 面试题
写给保洁员表扬信
2014/01/08 职场文书
检察官就职演讲稿
2014/01/13 职场文书
护理中职生求职信范文
2014/02/24 职场文书
幼儿园的门卫岗位职责
2014/04/10 职场文书
《槐乡五月》教学反思
2014/04/25 职场文书
在教室放鞭炮的检讨书
2014/09/28 职场文书
正风肃纪查摆剖析材料
2014/10/10 职场文书
家长学校教学计划
2015/01/19 职场文书
2015年公务员工作总结
2015/04/24 职场文书
2015年酒店服务员工作总结
2015/05/18 职场文书
红色故事汇观后感
2015/06/18 职场文书
青年人初次创业的“五不要”
2019/08/23 职场文书
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers