element中table操作按钮展示与折叠的实现示例
作者:My_Bells 发布时间:2024-05-02 16:35:35
先来看实现效果。
1.遇到问题
因为随着功能的增多,table操作栏中的功能按钮增多,操作列长度就增长,导致不是很美观。所以产品要求超过三个按钮就将多余的按钮隐藏在一个按钮中。点击这个按钮实现展开和折叠其余按钮的效果。
这个需求是UI组件库中没有实现的。所以要求自己实现。
2.解决思路
因为以前操作栏按钮的实现是直接在视图template中写死的。所以我想到是不是可以通过修改UI组件库中table组件接收的数据进行处理与展示。经过研究后发现它是通过编译生成VDOM处理的,所以很难直接处理VDOM,这种方式就不行了。
后来想到能不能将按钮先定义成数据数组,通过处理后再渲染操作按钮。通过尝试后这种方式是可行的。一般按钮有按钮图标、按钮名称、按钮权限、和按钮点击这几个功能。所以最后将每个按钮定义为下面的数据结构。
[{
icon: 'edit',//图标icon 必填 String
name: '编辑',//图标title 必填 String
handler: function (row, scope) {},//图标点击操作方法,返回两个参数行数据和scope数据 必填 Function
v_if: function (row, scope) {}//图标是否 * 作栏包含条件方法,返回两个参数行数据和scope数据,返回值为true就被包含,false不会被包含 非必填 Function
v_noBtn: 'assetsManage_accountManage'//图标是否 * 作栏包含条件字符串
}]
其中v_if和v_noBtn是用来处理按钮权限的。handler是点击触发函数。最后通过权限过滤后的按钮个数来判断按钮的是否需要隐藏。大于三个和不大于三个的按钮分别渲染为对应的视图。这时候又遇到了一个问题,由于table组件样式的限制导致按钮的展示与隐藏弹出框不能超过当前列长度。超出了就隐藏。这个问题本来是想设置定位来实现的,但是由于UI组件一些限制没办法实现。所以最后想法是能不能将这个弹出框DOM渲染在表格或者表格外层div中。这样就解决了这个问题。发现UI库里面有个Popper组件,查看源码后发现它是直接渲染在body中的,正合我意,修改下vue-popper.js,如果获取到props就渲染在对应的元素节点中,如果没有就渲染在body中。
if (this.appendToTable){
document.querySelector(this.appendToTable).appendChild(this.popperElm);
} else if (this.appendToBody){
document.body.appendChild(this.popperElm);
}
这样这个需求就实现了。
3.用法
此组件接收三个props:btnData(操作按钮数据对象数组)、scope(table上的scope对象)、option配置项
//默认props:
btnData:[],
option:{
isHidden:true,//是否开启操作栏隐藏设置,默认开启
showNum:3//如果isHidden为true时,个数大于3就会隐藏,默认是3
appendId: '.s-table',//将浮动栏添加到对应id或者class节点中。或者.xxx。传空字符串是添加到body中。
trigger: 'click',//触发方式,传值可查看Popper UI组件trigger属性
placement: 'left'//方向,传值可查看Popper UI组件placement属性
}
btnData数组中的对象接收5个属性:
{
icon: 'edit',//图标icon 必填 String
name: '编辑',//图标title 必填 String
handler: function (row, scope) {},//图标点击操作方法,返回两个参数行数据和scope数据 必填 Function
v_if: function (row, scope) {}//图标是否 * 作栏包含条件方法,返回两个参数行数据和scope数据,返回值为true就被包含,false不会被包含 非必填 Function
v_noBtn: 'assetsManage_accountManage'//图标是否 * 作栏包含条件字符串
},
其中v_if和v_noBtn只要有一个返回值为false当前行操作栏中就不包含。
4.实例
此处代码和element标签上有些差异。是因为对element进行了二次处理。除了标签改变外,其余大多是没改变的。组件可以参考下,按照上面的思路和具体需求自己去写一个。
<s-table>
<s-table-column label="操作" fixed="right">
<template slot-scope="scope">
<button-set :scope="scope" :btnData="btnData()" :option="tableOption"></button-set>
</template>
</s-table-column>
</s-table>
<script>
import buttonSet from '@/components/tableHandleHidden/buttonSet';
export default {
components: {
buttonSet
}
data() {
return {
tableOption: {
isHidden: true,
showNum: 3,
appendId: '#realpagetable_1',
trigger: 'click',
placement: 'left'
}
}
},
methods: {
btnData() {
let vm = this;
return [
{
icon: 'eye',
name: '查看资产详情',
v_noBtn: 'assetsManage_viewAsset',
handler: function (row, scope) {
vm.gotoAssetDetail(row)
}
},
{
icon: 'edit',
name: '编辑',
handler: function (row, scope) {
vm.curUuid = scope.row.uuid;
vm.$router.push(`assets_list/assetEdit/${vm.curUuid}/0`);
},
v_if: function (row, scope) {
return vm.isConfigAdminCheck(scope.row.monitorItcomp) || vm.judgeRoleBtn('assetsManage_editAsset')
}
}
]
}
}
}
</script>
@/components/tableHandleHidden/buttonSet组件:
<template>
<div class="buttonSet_all">
<div v-if="data.length===1">
<i v-for="(item, index) in data[0]" :key="index" :class="`iconfont icon-${item.icon}`" @click="item.handler(scope.row,scope,$event)" :title="item.name"></i>
</div>
<div v-else-if="data.length>1">
<i v-for="(obj, index) in data[0]" :key="index" :class="`iconfont icon-${obj.icon}`" @click="obj.handler(scope.row,scope,$event)" :title="obj.name"></i>
<s-popover
popper-class="buttonSet_style"
:append-to-table="option.appendId?option.appendId:''"
:ref="'popover'+scope.row.uuid"
:placement="option.placement?option.placement:'left'"
:trigger="option.trigger?option.trigger:'click'"
>
<ul class="s-dropdown-menu button-set-box" style="width:120px;">
<li style="overflow:hidden;text-overflow: ellipsis; white-space: nowrap; padding-left: 10px; padding-right: 10px;" class="s-dropdown-item" v-for="(obj, index) in data[1]" :key="index" @click="obj.handler(scope.row,scope,$event)">
<i :class="`iconfont icon-${obj.icon}`" :title="obj.name" style="font-size:14px; margin-right: 3px; color: #199FED"></i>
<span :title="obj.name">{{obj.name}}</span>
</li>
</ul>
<i class="iconfont icon-more" slot="reference"></i>
</s-popover>
</div>
</div>
</template>
<script>
// import {chunk} from 'lodash';
export default {
props: {
btnData: {
type: Array,
default: function() {
return []
}
},
scope: {
type: Object
},
option: {
type: Object,
default: function() {
return {
isHidden: true,
showNum: 3,
appendId: '.s-table',
trigger: 'click',
placement: 'left'
}
}
}
},
data() {
return {
data: []
}
},
computed: {},
created() {
this.init();
},
watch: {
scope(val) {
this.init();
}
},
methods: {
init() {
let arr = [];
this.btnData.map(item => {
if (item.v_if && item.v_noBtn) {
if (item.v_if(this.scope.row, this.scope) && this.permissionJudge(item.v_noBtn))arr.push(item);
} else if (item.v_if && !item.v_noBtn) {
if (item.v_if(this.scope.row, this.scope))arr.push(item);
} else if (!item.v_if && item.v_noBtn) {
if (this.permissionJudge(item.v_noBtn))arr.push(item);
} else {
arr.push(item);
}
})
if (arr.length > this.option.showNum && this.option.isHidden) {
this.data = [arr.slice(0, this.option.showNum), arr.slice(this.option.showNum)];
} else {
this.data = [arr];
}
},
permissionJudge(value) {
let authMenu = this.$store.getters.authMenu;// 获取所有一级目录
for (let item of authMenu) {
if (item.keyWord === value) {
return true;
}
}
return false;
}
},
beforeDestroy() {
// eslint-disable-next-line no-undef
$('.buttonSet_style').remove()
}
}
</script>
<style lang="stylus">
.buttonSet_style{
padding:10px 0;
}
.button-set-box .s-dropdown-item:hover > i{
color #fff!important
}
// .buttonSet_style{
// padding:6px 8px;
// color: #199FED;//#6da0cb
// background:#fff;//#19232e;
// .popper-arrow:after{
// border-left-color:#fff !important;
// }
// .iconfont{
// font-size: 20px;
// cursor:pointer;
// margin:0 2px;
// }
// }
</style>
来源:https://blog.csdn.net/qwe435541908/article/details/103242502


猜你喜欢
- 本文实例讲述了JS实现TITLE悬停长久显示效果。分享给大家供大家参考,具体如下:<!DOCTYPE html PUBLIC &quo
- Linux系统自带Python,且根据系统自带资源来对python配置mysql;安装需要已配置好正确的yum源;在python未配置mys
- 看代码,再做解释<?php $array=array('a','b','c','
- Windows版mysql 8.0.28安装图解,供大家参考,具体内容如下1.官网下载最新版第一步双击打开 选择server only(因为
- 使用场景当需要进行vuex进行数据状态管理的时候,会使用到mapGetters,mapState,还有自身的计算属性的时候,这个时候就会用到
- 本文实例讲述了php版本CKEditor 4和CKFinder安装及配置方法。分享给大家供大家参考,具体如下:下载并解压CKEditor 4
- 利用python 写一些网络服务的时候,当网络状况不好,或者资源占用过多,任务拥塞的情况下,总会抛出一些异常,当前任务就被终止了,可以很好的
- 首先安装解析的第三方包:go get gopkg.in/yaml.v2示例:package main import ( "os&q
- 本文提供了三种不同的方式在Python(IPython Notebook)中调用ggplot。在大数据时代,数据可视化是一个非常热门的话题。
- 今天星期天,因数据库太慢,最后决定将数据库进行重新整理. (假定数据库名称为:DB_ste) 1、根据现在的数据库的脚本创建一个脚本文件(F
- 本文实例讲述了Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息。分享给大家供大家参考,具体如下:说明:此代码用于接
- (一)原理 小偷程序实际上是通过了XML中的XMLHTTP组件调用其它网站上的网页。比如新闻小偷程序,
- python保留两位小数:In [1]: a = 5.026In [2]: b = 5.000In [3]: round(a,2)Out[3
- 本文实例讲述了python删除特定文件的方法。分享给大家供大家参考。具体如下:#!/usr/bin/python# -*- coding:
- 导语大家以前应该都听说过一个游戏:叫做走四棋儿这款游戏出来到现在时间挺长了,小时候的家乡农村条件有限,附近也没有正式的玩具店能买到玩具,因此
- 网上有不少生成缩略图的ASP组件。若你的虚拟空间不支持注册新组件,可能会感觉自己的网站失色不少。心晴不才,结合网上资源写了个无组件生成缩略图
- 一、数据集爬取现在的深度学习对数据集量的需求越来越大了,也有了许多现成的数据集可供大家查找下载,但是如果你只是想要做一下深度学习的实例以此熟
- 本文实例为大家分享了pygame实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下为了简化起见,游戏素材暂定为两张简单的图片(文中用的是30
- 本文实例为大家分享了python获取本机所有IP地址的具体代码,供大家参考,具体内容如下import socket# 查看当前主机名prin
- for 循环本系列前面 “探索 Python,第 5 部分:用 Python 编程” 一文讨论了 if 语句和 while 循环,讨论了复合