element中table操作按钮展示与折叠的实现示例

目录
  • 先来看实现效果。
  • 1.遇到问题
  • 2.解决思路
  • 3.用法
  • 4.实例

先来看实现效果。

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>

到此这篇关于element中table操作按钮展示与折叠的实现示例的文章就介绍到这了,更多相关element table按钮展示折叠内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue Element前端应用开发之根据ABP后端接口实现前端展示

    概述 ABP(ASP.NET Boilerplate)框架主要是基于.net core 进行的后端Web API的开发,结合Swagger的管理界面我们可以看到发布的 API 的接口明细信息,这样前端技术人员可以很容易整合前端的API应用.Vue + Element的前端应用,是目前较为流行的前端技术整合,Vue提供了前端框架很好的支持,Element提供了非常不错的界面组件封装和处理,通过ABP后端API接口和前端Vue+Element的整合,可以很好实现前后端的分离处理,同时又极大提高各自开

  • Vue Element前端应用开发之表格列表展示

    1.列表查询界面效果 在介绍任何代码处理逻辑之前,我们先来做一个感官的认识,贴上一个效果图,在逐一介绍其中处理的步骤和注意事项. 常规的列表展示界面,一般分为几个区域,一个是查询区域,一个是列表展示区域,一个是底部的分页组件区域.查询区域主要针对常规条件进行布局,以及增加一些全局或者批量的操作,如导入.导出.添加.批量添加.批量删除等按钮:而其中主体的列表展示区域,是相对比较复杂一点的地方,需要对各项数据进行比较友好的展示,可以结合Tag,图标,按钮等界面元素来展示,其中列表一般后面会包括一些对

  • elementUI同一页面展示多个Dialog的实现

    要实现的效果如下: 首先官方文档是这样描述的: 但是我写了个小demo发现并不能直接平级放置即可,一样会存在先后顺序不同造成的覆盖以及遮罩层导致不能点击被遮盖的dialog. 原因如下:因为dialog先后顺序不同z-index设置的层级不同,所以必定会覆盖遮挡 那么我们要实现一个这样的效果不仅仅平级放置即可,就要用到里面的一个属性:modal 下面贴上代码: 总的思路就是:dialog先后顺序重叠问题,使用便宜去让它们错开:然后就是遮罩层导致不能点击z-index层级低的弹框,就要用到moda

  • element中table操作按钮展示与折叠的实现示例

    目录 先来看实现效果. 1.遇到问题 2.解决思路 3.用法 4.实例 先来看实现效果. 1.遇到问题 因为随着功能的增多,table操作栏中的功能按钮增多,操作列长度就增长,导致不是很美观.所以产品要求超过三个按钮就将多余的按钮隐藏在一个按钮中.点击这个按钮实现展开和折叠其余按钮的效果.这个需求是UI组件库中没有实现的.所以要求自己实现. 2.解决思路 因为以前操作栏按钮的实现是直接在视图template中写死的.所以我想到是不是可以通过修改UI组件库中table组件接收的数据进行处理与展示.

  • element中table高度自适应的实现

    1.开发环境 vue+element 2.电脑系统 windows10专业版 3.在开发的过程中,我们经常会使用到 element中的table,但是我们也发现了在table的配置中,只能设置 具体的高度不能设置百分比,怎么实现table高度自适应呢?方法如下: 4.在对应的vue模板中添加如下代码: <el-table :data="tableData" row-key="id" sortable style="width: 96%" :

  • Element中table组件按照属性执行合并操作详解

    在实际开发中,要求使用elementUI的table组件对表格数据上下行相邻相同的数据进行合并,在elem官网上查看到是有对应的组件和合并方法 <el-table :data="tableData" :span-method="objectSpanMethod"> <el-table-column prop="id" label="ID" width="180"> </el-t

  • vue+Element中table表格实现可编辑(select下拉框)

    最近在工作中遇到一个问题,需要在表格中实现数据可编辑状态,具体情况是需要在单元格里加入下拉框:并且每个下拉框的数组数据是不一样的,具体是根据当前行前面数据的id查询而来,前面的是数据是动态生成的,后面的下拉框数据也是根据id动态生成的,内容不同:有点类似于树形二级状态,后面的下拉框数据来源并没有在前面内容里,而是另外一个接口查询,具体操作如下: HTML代码: 1.在处理人列加入一个下拉框模板,其中v-model必须要scope.row.proJbruserValue来绑定,意思是这个值绑定到当

  • antd中table展开行默认展示,且不需要前边的加号操作

    如下所示: 前边不显示+,并且详细信息默认展开 在table中配置 <Table expandedRowKeys={this.store.chargeTableData.map(item => item.key)} //展开的行 expandIconAsCell={false} expandIconColumnIndex={-1} bordered //展示边框 defaultExpandAllRows={true} //初始时展开所有行 pagination={{ pageSize: 5 }

  • Element UI中table单元格合并的解决过程

    目录 引言 解决思路: 1.格式化后台返回的数据(根据实际数据格式处理) 2.在 data 中定义数据,需要合并几列就定义几个数组和索引 3.定义合并函数 4.table 组件属性 span-method 的单元格合并方法: 完整代码: 总结 引言 项目中遇到表格单元格合并的需求,在此记录整个解决过程. 项目使用的是 Element UI,表格使用的是 table 组件.Element UI 的 table 表格组件中对单元格进行合并,需要使用 table 组件的 span-method 属性.

  • vuejs+element UI table表格中实现禁用部分复选框的方法

    有时候我们构建这样带一列复选框的表格 然后希望根据条件禁用某个列表项的选择框,可以这样写 HTML: JS: 以上这篇vuejs+element UI table表格中实现禁用部分复选框的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • vue element 中的table动态渲染实现(动态表头)

    通过在vue中使用element的table表格,实现数据动态渲染,并且动态渲染表头.通过在父组件中引入子组件表格,然后向子组件传递表格数据和表头数据. 子组件table中template模板 <el-table :data="this.tableData" height="400px" max-height="400px" size="small" row-class-name="row" cell

  • Vue中Element的table多选表格如何实现单选

    目录 Element的table多选表格实现单选 vue table单选逻辑 Element的table多选表格实现单选 效果图 1.在多选表格的基础上进行处理, 呈现单选表格的作用 2.主要使用的是ElementUI多选表格中的方法 链接 2.1 select 事件 当用户手动勾选数据行的 Checkbox 时触发的事件 参数selection, row 2.2 row-click 事件 当某一行被点击时会触发该事件 参数 row, column, event 2.3 selection-ch

  • Element UI table参数中的selectable的使用及遇到坑

    Element UI table参数中的selectable的使用中遇到的坑:页面: <el-table-column :selectable='selectable' type="selection" :reserve-selection="true"> </el-table-column> 网上搜了说这样: selectable(row,index) { if(row.id==="10001"){ return fal

随机推荐