element中table操作按鈕展示與折疊的實現(xiàn)示例
先來看實現(xiàn)效果。

1.遇到問題
因為隨著功能的增多,table操作欄中的功能按鈕增多,操作列長度就增長,導致不是很美觀。所以產品要求超過三個按鈕就將多余的按鈕隱藏在一個按鈕中。點擊這個按鈕實現(xiàn)展開和折疊其余按鈕的效果。
這個需求是UI組件庫中沒有實現(xiàn)的。所以要求自己實現(xiàn)。
2.解決思路
因為以前操作欄按鈕的實現(xiàn)是直接在視圖template中寫死的。所以我想到是不是可以通過修改UI組件庫中table組件接收的數(shù)據進行處理與展示。經過研究后發(fā)現(xiàn)它是通過編譯生成VDOM處理的,所以很難直接處理VDOM,這種方式就不行了。
后來想到能不能將按鈕先定義成數(shù)據數(shù)組,通過處理后再渲染操作按鈕。通過嘗試后這種方式是可行的。一般按鈕有按鈕圖標、按鈕名稱、按鈕權限、和按鈕點擊這幾個功能。所以最后將每個按鈕定義為下面的數(shù)據結構。
[{
icon: 'edit',//圖標icon 必填 String
name: '編輯',//圖標title 必填 String
handler: function (row, scope) {},//圖標點擊操作方法,返回兩個參數(shù)行數(shù)據和scope數(shù)據 必填 Function
v_if: function (row, scope) {}//圖標是否被操作欄包含條件方法,返回兩個參數(shù)行數(shù)據和scope數(shù)據,返回值為true就被包含,false不會被包含 非必填 Function
v_noBtn: 'assetsManage_accountManage'//圖標是否被操作欄包含條件字符串
}]
其中v_if和v_noBtn是用來處理按鈕權限的。handler是點擊觸發(fā)函數(shù)。最后通過權限過濾后的按鈕個數(shù)來判斷按鈕的是否需要隱藏。大于三個和不大于三個的按鈕分別渲染為對應的視圖。這時候又遇到了一個問題,由于table組件樣式的限制導致按鈕的展示與隱藏彈出框不能超過當前列長度。超出了就隱藏。這個問題本來是想設置定位來實現(xiàn)的,但是由于UI組件一些限制沒辦法實現(xiàn)。所以最后想法是能不能將這個彈出框DOM渲染在表格或者表格外層div中。這樣就解決了這個問題。發(fā)現(xiàn)UI庫里面有個Popper組件,查看源碼后發(fā)現(xiàn)它是直接渲染在body中的,正合我意,修改下vue-popper.js,如果獲取到props就渲染在對應的元素節(jié)點中,如果沒有就渲染在body中。
if (this.appendToTable){
document.querySelector(this.appendToTable).appendChild(this.popperElm);
} else if (this.appendToBody){
document.body.appendChild(this.popperElm);
}
這樣這個需求就實現(xiàn)了。
3.用法
此組件接收三個props:btnData(操作按鈕數(shù)據對象數(shù)組)、scope(table上的scope對象)、option配置項
//默認props:
btnData:[],
option:{
isHidden:true,//是否開啟操作欄隱藏設置,默認開啟
showNum:3//如果isHidden為true時,個數(shù)大于3就會隱藏,默認是3
appendId: '.s-table',//將浮動欄添加到對應id或者class節(jié)點中。或者.xxx。傳空字符串是添加到body中。
trigger: 'click',//觸發(fā)方式,傳值可查看Popper UI組件trigger屬性
placement: 'left'//方向,傳值可查看Popper UI組件placement屬性
}
btnData數(shù)組中的對象接收5個屬性:
{
icon: 'edit',//圖標icon 必填 String
name: '編輯',//圖標title 必填 String
handler: function (row, scope) {},//圖標點擊操作方法,返回兩個參數(shù)行數(shù)據和scope數(shù)據 必填 Function
v_if: function (row, scope) {}//圖標是否被操作欄包含條件方法,返回兩個參數(shù)行數(shù)據和scope數(shù)據,返回值為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操作按鈕展示與折疊的實現(xiàn)示例的文章就介紹到這了,更多相關element table按鈕展示折疊內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue實現(xiàn)下拉框的多選功能(附后端處理參數(shù))
本文介紹了如何使用Vue實現(xiàn)下拉框的多選功能,實現(xiàn)了在選擇框中選擇多個選項的功能,文章詳細介紹了實現(xiàn)步驟和示例代碼,對于想要了解如何使用Vue實現(xiàn)下拉框多選功能的讀者具有一定的參考價值2023-08-08
elementplus?中?DatePicker?日期選擇器樣式修改無效的問題及解決方案
這篇文章主要介紹了elementplus中DatePicker日期選擇器樣式修改無效的問題,DatePicker日期選擇器彈出面板默認掛載在body上,所以在組件中添加了?scoped?屬性的?style?標簽下是修改不到其樣式的,講解了datepicker的使用方法,及常見的配置項和對應的值,需要的朋友可以參考下2024-01-01
vue通過子組件修改父組件prop的多種實現(xiàn)方式
這篇文章主要介紹了vue通過子組件修改父組件prop的幾種實現(xiàn)方式,比較常用的方式是通過Prop單向傳遞的規(guī)則,需要的朋友可以參考下2021-09-09

