功能说明
el-table中有一个操作列,每一行根据数据情况有不同数量和功能的按钮,要求超过三个按钮的行,超出按钮收起为更多按钮,鼠标移入再展示
- 每行按钮的个数不定,每个按钮的展示条件不同,且判断条件很复杂
- 按钮功能不同
- 按钮不仅有单个展示条件,还有分组条件
解决思路
- 根据按钮生成条件进行分组
- 方案1:
- 将按钮复制一份,分成外部展示和下拉展示两组
- 通过判断条件得到所有需要生成的按钮下标
- 页面中判断
- 优点:
- 页面动态渲染,不需要操作dom
- 缺点
- 判断条件太多且比较难以组合
- 每一行都要经过计算,计算量大
- 不具备通用性
- 方案1:
- 通过操作dom对按钮进行分组
- 方案2:
- 将所有按钮放到一个容器中,在按钮上绑定自定义指令
- 通过自定义指令获取生成的容器以及按钮子元素
- 根据子元素个数与内容对重新生成dom并绑定事件,然后插入到页面中
- 优点:
- 方法可各个页面复用,且只需要加上自定义指令,系统较大时改动量小
- 比较容易想到
- 缺点
- 性能消耗太大
- 方案2:
- 通过css和自定义指令对按钮显示进行控制
- 方案3:
- 将按钮复制一份,分成外部展示和下拉展示两组
- A组按钮全部进行隐藏,仅显示前三个子节点
- B组按钮隐藏前三个子节点
- 给B组按钮容器加上自定义指令,如果容器子节点少于4个,隐藏容器(更多按钮)
- B组按钮容器动态绑定key,否则el-table翻页或其它数据改变时,步骤4无法更新dom
- 优点:
- 方法可各个页面复用,且只需要加上自定义指令,系统较大时改动量小
- 对dom的操作量少
- 性能消耗较小
- 代码较前两种方法更加简洁易懂
- 缺点
- 需要生成两组按钮,有额外渲染
- 方案3:
最终选择代码
VUE
<template slot-scope="scope">
<div class="fd-link-group">
<span @click="AAA(scope.row)" class="fd-table-link">AAA</span>
<span @click="BBB(scope.row)" class="fd-table-link" v-if="a && b && c && d && e">BBB</span>
<template v-if="F">
<span @click="CCC(scope.row)" v-if="A && F" class="fd-table-link">CCC</span>
<span @click="DDD(scope.row)" v-if="!A" class="fd-table-link">CCC</span>
</template>
<span @click="EEE(scope.row, 1)" v-if="D && G && H class="fd-table-link">DDD</span>
<span @click="FFF(scope.row)" v-if="M" class="fd-table-link">EEE</span>
<span @click="GGG(scope.row)" v-if="N && H &&I" class="fd-table-link">FFF</span>
</div>
<div class="fd-link-drop" v-shwoLinkDrop :key="scope.row.cbh">
<div class="fd-link-drop-content">
<div class="fd-link-drop-body">
<span @click="AAA(scope.row)" class="fd-table-link">AAA</span>
<span @click="BBB(scope.row)" class="fd-table-link" v-if="a && b && c && d && e">BBB</span>
<template v-if="F">
<span @click="CCC(scope.row)" v-if="A && F" class="fd-table-link">CCC</span>
<span @click="DDD(scope.row)" v-if="!A" class="fd-table-link">CCC</span>
</template>
<span @click="EEE(scope.row)" v-if="D && G && H" class="fd-table-link">DDD</span>
<span @click="FFF(scope.row)" v-if="M" class="fd-table-link">EEE</span>
<span @click="GGG(scope.row)" v-if="N && H && I" class="fd-table-link">FFF</span>
</div>
</div>
</div>
</template>
LESS
.fd-link-group {
display: inline-block;
}
.fd-link-group .fd-table-link {
display: none;
&:first-child,&:nth-child(2),&:nth-child(3) {
display: inline;
}
}
.fd-link-drop {
position: relative;
z-index: 2;
display: inline-block;
width: 14px;
height: 14px;
background: url("~@/A.png") center no-repeat;
background-size: 14px 14px;
cursor: pointer;
&:hover {
z-index: 3;
.fd-link-drop-content {
display: block;
}
}
}
.fd-link-drop-content {
position: absolute;
top: 14px;
right: -25px;
display: none;
padding-top: 10px;
min-width: 126px;
.fd-link-drop-body {
border-radius: 2px;
border: 1px solid #dbdddf;
box-shadow: 0 9px 28px rgba(0, 0, 0, 0.05);
background-color: #fff;
}
.fd-table-link {
display: block;
padding-left: 10px;
width: 100%;
height: 30px;
color: rgba(0, 0, 0, 0.65);
font: 12px/30px "microsoft yahei";
&:hover {
color: #2a95ff;
background-color: #dcecff;
}
&:first-child,&:nth-child(2),&:nth-child(3) {
display: none;
}
}
}
自定义指令
// 注册一个全局自定义指令 v-shwoLinkDrop,判断是否展示【更多】列表操作按钮
Vue.directive('shwoLinkDrop', {
bind: function (el) {
if ($(el).find('.fd-table-link').length < 4) {
$(el).hide();
}
}
});
结语
虽然最终实现了,但我总感觉有更好的方案没想到,前两种方案受固有思维影响,不建议采用,第三种方案算是自己的一种另辟蹊径吧,可能实际项目中这种情况遇到的很少,更多的可能按钮可以通过data直接通过v-for进行渲染,这样的话就方便控制得多。