vue 怎么拆分默认插槽中的数据?

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两部分,但渲染不出来,请问有其他什么方法吗。

或者说不用这个思路,要做这种类型的组件,大家觉得应该怎么写,才能让使用者用起来最方便


回答:

vue 怎么拆分默认插槽中的数据?vue 怎么拆分默认插槽中的数据?

首先理下需求,如上图,有一个按钮组,里面最多有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个以后的按钮


回答:

将插槽分成两个,例如

<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

回到顶部