admin管理员组

文章数量:821216

Vue(14)slot插槽的使用

slot(插槽)

  • 在生活中很多地方都有插槽,电脑usb的插槽,插板当中的电源插槽
  • 插槽的目的是为了让我们原来的设备具备更多的扩展性
  • 比如电脑的USB我们可以插入U盘,手机,鼠标,键盘等等
     

组件中的插槽

  • 组件的插槽也是为了让我们的组件更具有扩展性
  • 让使用者决定组件内部的一些内容到底展示什么
     

例子

  • 移动开发中,几乎每个页面都有导航栏
  • 导航栏我们必然封装成一个插件
  • 一旦有了这个组件,我们就可以在多个页面中复用了
     

如何封装这类组件(slot)

  • 最好的封装方式就是将共性抽取到组件中,将不同的部分暴露为插槽
  • 一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容
  • 是搜索框,是文字,是按钮,由调度者自己决定
     

插槽的案例

HTML

<div id="app"><cpn><button>按钮</button></cpn><cpn><p>hello world</p></cpn><cpn><p>666</p></cpn>
</div>
<template id="cpn"><div><h2>我是组件</h2>// 插槽预留的位置,方便使用者自己填写<slot></slot></div>
</template>
<script src="../js/vue.js"></script>
<script>const app = new Vue({el: "#app",components: {"cpn": {template: `#cpn`,}}})
</script>

上述代码干了以下事情
1.定义了子组件cpn,然后在子组件中预留了一个插槽,插槽的内容由用户填写
2.父组件中使用了3次子组件,3个子组件分别给插槽填写了不同的内容

最后展示效果如下

 

插槽默认值

如果我们需要大量使用这个组件,而且组件预留的插槽,我们大多数都是填写的返回按钮,只有极少数填写其他的,那么这种情况就可以为插槽设置一个默认值

HTML

<div id="app"><cpn></cpn><cpn></cpn><cpn></cpn>
</div>
<template id="cpn"><div><slot><button>返回</button></slot></div>
</template>

我们在子组件中设置了一个默认值为返回按钮的插槽,那么父组件在使用时如果不填写任何内容,那么默认就是返回按钮
 

具名插槽

有时我们需要多个插槽。例如对于一个带有如下模板的组件:

HTML

<template id="cpn"><div><slot name="header"><span>头部</span></slot><slot name="main"><span>中间</span></slot><slot name="footer"><span>页脚</span></slot></div>
</template>

我们在组件中预留了3个插槽,但是这里指定了3个名字,后续父组件使用v-slot指定name属性后就能填写自己的内容,比如如下代码

HTML

<div id="app"><cpn><template v-slot:header><p>header头部</p></template><template v-slot:footer><p>footer页脚</p></template></cpn>
</div>

使用了cpn组件,然后指定了插槽name属性为headerfooter的内容,指定后自己填写的内容就会替换默认的内容。
注意:这里的语法格式是固定的,必须在使用template标签上绑定v-slot:插槽的名字
 

编译作用域

通过外面传给组件的变量,在以后使用插槽的时候是不能使用的

HTML

<div id="app"><cpn v-show="isShow"></cpn>
</div>
<template id="cpn"><p>hello</p>
</template>
<script src="../js/vue.js"></script>
<script>const app = new Vue({el: "#app",data: {isShow: true},components: {"cpn": {template: `#cpn`,data(){return{isShow: false}}}}})
</script>

上面我们定义了子组件cpn,子组件中有属性isShow,app实例中也定义了属性isShow,最后使用子组件cpn时使用了v-show,当值为true显示,值为false不显示
问题:v-show中的isShow的值是实例中的true还是子组件中的false
答案:true,因为你使用的时候是在app实例范围内,所以isShow会去从实例中的data去查找,虽然你是在cpn子组件中绑定的,但是这里的cpn你只需要把他当做普通的标签即可,如果你想让isShow的值为false,那么你只需要在子组件的template模板中使用<p v-show="isShow">hello</p>
 

作用域插槽

默认在插槽中的代码只能使用全局Vue中的属性,如果想要使用自定义组件中的属性,那么需要在定义slot的时候使用v-bind来进行绑定。

HTML

<div id="app"><cpn><template v-slot:default="slot">{{slot.data.firstName}}</template></cpn>
</div>
<template id="cpn"><div><slot :data="user">{{user.lastname}}</slot></div>
</template>
<script src="../js/vue.js"></script>
<script>const app = new Vue({el: "#app",components: {"cpn": {template: `#cpn`,data(){return{"user": {"firstName": "甲","lastname": "壳虫"}}}}}})
</script>

www.meipian/3i94gjcm?share_depth=1
www.jianshu/p/865c60c303ea
www.meipian/3i9flprt?share_depth=1
weibo/ttarticle/p/show?id=2309404621206866493694
www.meipian/3id29995?share_depth=1
www.bilibili/read/cv10662381
www.meipian/3imc22dd?share_depth=1
www.meipian/3io2ii9c?share_depth=1
www.bilibili/read/cv10680290
baike.1688/doc/view-d47460764.html?self_ask=yes
bbs.elecfans/home.php?mod=space&amp;uid=4434872&amp;do=profile
www.mafengwo/u/86925342.html
q.jinsom/author/21653
didi.seowhy/siteInfo-2804616.html
www.zhihu/zvideo/1363154216299618304
www.acfun/v/ac27540008
www.meipian/3ip5yzar?share_depth=1
www.360doc/content/21/0407/17/74567251_971063780.shtml
www.meipian/3iqex6mc?share_depth=1
www.meipian/3iqj10gc?share_depth=1
www.jianshu/p/e5cd55434338
yunlitongxin.lofter
v.qq/x/page/y3238yctg5i.html
www.zhihu/collection/658467235
www.zhihu/collection/658466918
www.zhihu/collection/658466119
www.zhihu/collection/658465909
www.zhihu/collection/658465073
www.zhihu/collection/658464749
www.zhihu/collection/658464516
www.zhihu/collection/658463856
www.zhihu/collection/658463519
www.zhihu/collection/658463245
www.zhihu/collection/658462260
www.zhihu/collection/658459752
 

上述代码做了如下几件事情
1.定义了子组件cpn,在子组件中定义了user
2.在子组件cpn的模板的插槽中绑定了属性data,且插槽的默认值为user.lastname
3.在html中使用了子组件,并使用v-slot绑定了插槽Prop对象,这样就可以通过对象名称.子组件中绑定的属性名称(slot.data),来访问子组件中的数据

本文标签: Vue(14)slot插槽的使用