一开始接触vue时并不知道插槽是什么,后来看了很多文章也是一知半解。然后自己手动敲了一下,在项目中实际应用一下,实在太好用了。后来做小程序后发现也能使用slot,不单单在vue中使用。我就是这么目光短浅(QAQ)。尤其在做组件开发的时候更不能少了slot的使用。
一、对插槽的理解
对于一开始听到别人提起,这段代码中用个插槽特别方便。然而并不知什么是插槽,为什么要用插槽。后来看了很多文章,以下为个人的理解:
插槽用在子组件中,使用<slot></slot>标签。然后父组件在使用子组件的时候在子组件标签中添加的内容就能传到子组件中,<slot></slot>就是用来存放父组件在子组件标签中放置的内容的。
光说不行,读完上边的话再来看看这段代码
<div id="app"> <child>你好</child> </div> <script type="text/javascript"> //定义组件 Vue.component('child',{ template:`<div>Hello,World!</div>` }) //创建vue实例 var vm = new Vue({ el: "#app", data:{ } }) </script>
结果并没有“你好”输出。然后我们在子组件中加入一个<slot></slot>标签
<script type="text/javascript"> //定义组件 Vue.component('child',{ template:`<div> Hello,World! <slot></slot> </div>` }) //创建vue实例 var vm = new Vue({ el: "#app", data:{ } }) </script>
这样父组件中在使用<child></child>标签中加入的内容就传到了子组件中。那么,我们可以将插槽理解成:
插槽就是Vue实现的一套内容分发的API,将<slot></slot>元素作为承载分发内容的出口。插槽就相当于在子组件中留出个位置给父组件,如果父组件中有内容传进来,那么就放到slot中。
没有插槽的情况下在组件标签内些一些内容是不起任何作用的,当我在组件中声明了slot元素后,在组件元素内写的内容就会跑到它这里了!
二、具名插槽
具名插槽,就是给这个插槽起个名字
在组件中,我给插槽起个名字,一个名字叫"girl",一个名字叫"boy",还有一个不起名字
<div id="app"> <child> <template slot="girl"> 漂亮、美丽、购物、逛街 </template> <template slot="boy"> 帅气、才实 </template> <div> 无名无姓,普通的插槽 </div> </child> </div> <script type="text/javascript"> //定义组件 Vue.component('child',{ template:`<div> <slot name="girl"></slot> <div style="height:1px;background-color:red;"></div> <slot name="boy"></slot> <div style="height:1px;background-color:red;"></div> <slot></slot> </div>` }) //创建vue实例 var vm = new Vue({ el: "#app", data:{ } }) </script>
三、默认插槽
上面已经介绍过了,这里不做描述
四、作用域插槽
之前一直没搞懂作用域插槽到底是什么,该怎么用。研究发现以后,个人理解为:
在组件中绑定在slot标签上的属性,在父组件使用组件标签时可以拿到属性/值。请看如下代码:
<div id="app"> <child> <div slot-scope="a"> {{a}} </div> </child> </div> <script type="text/javascript"> //定义组件 Vue.component('child',{ template:`<div> <slot say="你好"></slot> </div>` }) //创建vue实例 var vm = new Vue({ el: "#app", data:{ } }) </script>
通过在浏览器上查看,以json对象形式展示出来,只不过它是个字符串。
<div id="app"> <child :lists="listPhone"> <div slot-scope="a"> {{a}} </div> </child> </div> <template id="temp"> <div> <ul> <li v-for="list in lists"> <slot :phone="list"></slot> </li> </ul> </div> </template> <script type="text/javascript"> //定义组件 Vue.component('child',{ props:['lists'], template:"#temp" }) //创建vue实例 var vm = new Vue({ el: "#app", data:{ listPhone:[ {id:1,brand:"苹果"}, {id:2,brand:"华为"}, {id:3,brand:"荣耀"}, {id:4,brand:"小米"} ] } }) </script>
假如我在加一些判断,对这些数据进行操作
<div id="app"> <child :lists="listPhone"> <div slot-scope="a"> <div v-if="a.phone.id===1">这是{{a.phone.brand}}</div> <div v-else>{{a.phone.brand}}</div> </div> </child> </div> <template id="temp"> <div> <ul> <li v-for="list in lists"> <slot :phone="list"></slot> </li> </ul> </div> </template> <script type="text/javascript"> //定义组件 Vue.component('child',{ props:['lists'], template:"#temp" }) //创建vue实例 var vm = new Vue({ el: "#app", data:{ listPhone:[ {id:1,brand:"苹果"}, {id:2,brand:"华为"}, {id:3,brand:"荣耀"}, {id:4,brand:"小米"} ] } }) </script>
用过element-ui的朋友们到这一步是不是很熟悉,饿了么组件表格就是这样实现的,表格的本质就是这个。