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.用法

  1. 此組件接收三個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屬性
}
  1. 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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章