本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
lement中table操作按钮展示与折叠的实现示例
BilyLiang · 324浏览 · 发布于2022-04-26 +关注

因为随着功能的增多,table操作栏中的功能按钮增多,这时候就需要折叠,本文主要介绍了element中table操作按钮展示与折叠的实现示例,具有一定的参考价值,感兴趣的可以了解一下

先来看实现效果。

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>     <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;" 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> .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>


 


相关推荐

RN开发环境的npm私库本地debug调试

manongba · 688浏览 · 2019-05-09 17:03:46
你不知道的浏览器渲染原理

追忆似水年华 · 1362浏览 · 2019-05-09 22:47:56
基于iview的router常用控制方式

追忆似水年华 · 980浏览 · 2019-06-03 10:39:21
编程小知识之 JavaScript 文件读取

manongba · 708浏览 · 2019-06-10 09:16:16
10个省时间的 PyCharm 技巧 赶快收藏!

· 691浏览 · 2019-06-10 09:32:01
加载中

0评论

评论
我是湖南最靓仔的那条仔,希望来到这里能够交道志同道合的朋友,一起学习,不断进步!!!
分类专栏
小鸟云服务器
扫码进入手机网页