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两部分,但渲染不出来,请问有其他什么方法吗。
或者说不用这个思路,要做这种类型的组件,大家觉得应该怎么写,才能让使用者用起来最方便
回复
1个回答

test
2024-07-14
首先理下需求,如上图,有一个按钮组,里面最多有N个按钮(按不同条件显示不同按钮),当显示的按钮超过3个时,只显示前3个,然后在左侧或者右侧显示一个更多按钮,点击后弹出剩下的按钮。
这里有如下两次使用方法。第一种使用方法我觉得太繁琐了。
1.我需要维护额外一个btnList变量,如果是一个任务列表,每条任务都有一个这种按钮组,那么我就需要在向后台请求到每一页任务的数据后,都要先循环任务数组,在每条任务的json中创建一个btnList变量,然后再渲染页面。
2.把按钮的样式封装进btns组件我感觉也不是很好,如果我想加功能,比如 改里面按钮的样式,或者在按钮上加一个badge小徽标 都不是很方便,需要在btnList数组里加新字段,然后改h-btns组件源码。
3.需要在子组件的@click事件中统一判断点击的是哪个按钮,这里感觉也不方便。
所以优先考虑第二种写法。
用法1
let 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个以后的按钮
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容