slot的使用
默认插槽
假设子组件<son>
组件的模版如下:
1 2 3 4 5 6 7 8 9 10 11
| <div class="container"> <header> <h1>头部</h1> </header> <main> <slot></slot> </main> <footer> <h1>w尾部</h1> </footer> </div>
|
利用slot特性,我们可以在一个父组件<father>
中向<son>
提供内容,如下:
1 2 3 4 5 6 7 8 9
| <son> <template v-slot:default> <h1> n内容区 </h1> </template> </son>
|
具名插槽
假设子组件<son>
组件的模版如下:
1 2 3 4 5 6 7 8 9 10 11
| <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
|
在父组件<father>
可使用v-slot分别向插槽放置对应的内容
1 2 3 4 5 6 7 8 9 10 11 12
| <son> <template v-slot:header> <h1>Here might be a page title</h1> </template>
<p>A paragraph for the main content.</p> <p>And another one.</p>
<template v-slot:footer> <p>Here's some contact info</p> </template> </son>
|
作用域插槽
使用作用域插槽可让插槽内容能够访问子组件中才有的数据
能够用于父子通信
假设我想从父组件<father>
访问子组件<son>
的username属性,可以这样做
在子组件<son>
内部的slot元素上动态绑定一个username属性:
1 2 3 4 5 6 7
| <div class="container"> <span> <slot :user="user"> {{ user.username }} </slot> </span> </div>
|
在父组件<father>
中,可以通过v-slot来访问user数据:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <son> <template v-slot:default="slotProps"> {{ slotProps.user.username }} </template> </son>
<son> <template v-slot:default="{ user }"> {{ user.username }} </template> </son>
|
如果插槽传递的数据为引用类型(如:对象),父组件还可以对它进行修改,父元素也可以往插槽内的元素绑定事件(在父元素中触发),代码如下:
子组件<son>
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <template> <div> <slot :user="userInfo"></slot> </div> </template>
<script> export default { data(){ return { userInfo:{username:'zhangs',userage:18} } } } </script>
|
父组件<father>
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <son> <template v-slot:default="{ user }"> <button @click="getDataFromSon(user)"></button> </template> </son> </template>
<script> export default { methods:{ getDataFromSon(obj){ //可以修改子组件的引用类型数据,但只限于该子组件,对其他组件没有影响 this.$set(obj,'username','lisi') //使用this.$set修改为响应式 } } } </script>
|
简写
在vue中,v-slot和v-on、v-bind类似,v-slot也有简写,用#代替v-slot。例如:v-slot:header简写成 # header
值得注意:当你使用template和v-slot声明某个插槽后,就不能再重复声明了,以下情况就会报错
1 2 3 4 5 6 7
| <template v-slot:default> <span>{{date}}</span> </template>
<template v-slot:default> <span>{{date}}</span> </template>
|
怎样使用slot
假设我要制作的一个回复框组件,作者的回复框和其他人的回复框有些内容或功能不一样(如下图:第一个个为作者回复框,第二个为其他人的回复框),像这种情况就可以使用插槽
子组件UseSlot代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <template> <div class="container"> <div class="topic-post"> <div class="avatar-box"> <img src="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png" alt=""> </div> <div class="topic-body"> <div class="info"> <span>{{userInfo.username}}</span> <slot></slot> </div> <div class="article"> <p>请教一下大家,有谁知道像vue官方文档,或者elementUI在线文档是怎么做出来的吗</p> </div> <slot name="author" ></slot> </div> </div> </div> </template>
|
父组件App.vue代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div class="app"> <UseSlot> <template v-slot:default> <span>{{date}}</span> </template>
<template v-slot:author> <div class="post-menu"> <button >回复</button> <div class="actions"> <button>点赞</button> <button>分享</button> </div> </div> </template> </UseSlot>
<UseSlot > <template v-slot:default> <span>⬇</span> </template> </UseSlot> </div> </template>
|