vue 怎么拆分默认插槽中的数据?
如上,我想做一个组件,里面有N个按钮(会根据不同状态显隐),当按钮数量小于3个时 全部显示出来,当按钮数量大于3个时 只显示前3个,然后自动显示一个更多按钮,点击更多后以弹框的形式显示其他按钮。
本来是想不用插槽,通过json数组的方式把按钮数据传到组件里,在组件里生成按钮,但是这样用起来不是很方便。
改成插槽后的写法:
父组件<btns>
<btn v-if="false">1</btn1>
<btn v-if="false">2</btn1>
<btn v-if="true">3</btn1>
<btn v-if="false">4</btn1>
<btn v-if="true">5</btn1>
<btn v-if="true">6</btn1>
<btn v-if="true">7</btn1>
</btns>
子组件this.$slots["default1"] = this.$slots.default.slice(0, 3);
this.$slots["default2"] = this.$slots.default.slice(3);
<slot name="default1"></slot>
<slot name="default2"></slot>
我想把默认插槽里面的数据拆分成default1和default2两部分,但渲染不出来,请问有其他什么方法吗。
或者说不用这个思路,要做这种类型的组件,大家觉得应该怎么写,才能让使用者用起来最方便
回答:
首先理下需求,如上图,有一个按钮组,里面最多有N个按钮(按不同条件显示不同按钮),当显示的按钮超过3个时,只显示前3个,然后在左侧或者右侧显示一个更多按钮,点击后弹出剩下的按钮。
这里有如下两次使用方法。
第一种使用方法我觉得太繁琐了。
1.我需要维护额外一个btnList变量,如果是一个任务列表,每条任务都有一个这种按钮组,那么我就需要在向后台请求到每一页任务的数据后,都要先循环任务数组,在每条任务的json中创建一个btnList变量,然后再渲染页面。2.把按钮的样式封装进btns组件我感觉也不是很好,如果我想加功能,比如 改里面按钮的样式,或者在按钮上加一个badge小徽标 都不是很方便,需要在btnList数组里加新字段,然后改h-btns组件源码。
3.需要在子组件的@click事件中统一判断点击的是哪个按钮,这里感觉也不方便。
所以优先考虑第二种写法。
用法1let btnList = [{text:'按钮1',class:'aaa'}{text:'按钮2',class:'bbb'},...];
<h-btns :btns='btnList' @click="在这里统一判断点击的是哪个按钮"></h-btns>
用法2
<h-btns>
<h-btn v-if="true" class='' @click=''>按钮1</h-btn>
<h-btn v-if="false" class='' @click=''><badge value="23">按钮2</badge></h-btn>
<h-btn v-if="true" class='' @click=''>按钮3{{item.num}}</h-btn>
<h-btn v-if="true" class='' @click=''>按钮4</h-btn>
<h-btn v-if="false" class='' @click=''>按钮5</h-btn>
<h-btn v-if="true" class='' @click=''>按钮6</h-btn>
<h-btn v-if="true" class='' @click=''>按钮7</h-btn>
</h-btns>
然后第二种写法的核心问题就是怎么把插槽里面的按钮拆分成 默认显示的 和 更多弹框中 的两部分。
这里没找到很好的方法,然后我想到了用css变相解决
源码<div class="btns">
<!--默认显示部分-->
<slot name="default"></slot>
<div class="btns_moreBox">
<a href="javascript:;" class="btns_moreBtn">更多</a>
<!--更多弹框-->
<div class="btns_moreContent">
<slot name="default"></slot>
</div>
</div>
</div>
编译后
<div class="btns">
<!--默认显示部分-->
<btn>按钮1</btn>
<btn>按钮2</btn>
<btn>按钮3</btn>
<btn>按钮4</btn>
<btn>按钮5</btn>
<btn>按钮6</btn>
<div class="btns_moreBox">
<a href="javascript:;" class="btns_moreBtn">更多</a>
<!--更多弹框-->
<div class="btns_moreContent">
<btn>按钮1</btn>
<btn>按钮2</btn>
<btn>按钮3</btn>
<btn>按钮4</btn>
<btn>按钮5</btn>
<btn>按钮6</btn>
</div>
</div>
</div>
CSS核心部分
btn{flex:1;}
.btns_moreBox{none;}
btn:nth-child(3) ~ btn{display:none;} //外部只显示前3个按钮
btn:nth-child(4) ~ .btns_moreBox{display:block;} //超过3个显示更多按钮
.btns_moreContent btn{display:none;}
.btns_moreContent btn:nth-child(3) ~ btn{display:block;} //更多弹层中只显示第3个以后的按钮
回答:
将插槽分成两个,例如
<btns> <template slot="default1">
<btn v-if="false">1</btn1>
<btn v-if="false">2</btn1>
<btn v-if="true">3</btn1>
<btn v-if="false">4</btn1>
</template>
<template slot="default2">
<btn v-if="true">5</btn1>
<btn v-if="true">6</btn1>
<btn v-if="true">7</btn1>
</template>
</btns>
回答:
直接在父级里面把你想要形式都处理好就行了呀?
比如说只显示3个,其他的折叠起来,那么在父级的时候就直接按照你设想的写好就行了,为什么要在子组件里面处理?
但是这样的话复用性就会很差劲,如果你在很多页面中都用到了这个组件。
所以猜测你的想法是想要在父级里面 slot
一些按钮进去,但是这些按钮在父级页面有绑定对应的事件。
其实这样可以用 props
把你的按钮列表以数组的形式传递进去,然后在子组件里面按照你的业务逻辑处理成想要的布局并渲染。不同按钮的点击事件你就统一用 $emit('click', btnName)
传递给父级,然后在父级分发处理就好。
以上是 vue 怎么拆分默认插槽中的数据? 的全部内容, 来源链接: utcz.com/p/933377.html