因为当前行的某些状态或者操作权限,每一行的操作按钮可能展示的数量不同。
所以我们需要找出当前table页,按钮最多的那一行row,并计算出这个row中操作栏的所需宽度,用这个宽度来设置最后一列操作栏的宽度
(按钮分为文字和图标,所以有两版)
columnWidth.js 【按钮是文字版】(当按钮是文字时,用这个)
export default {
data() {
return {
minWidth: 100
}
},
watch: {
minWidth() {
this.setWidth()
}
},
methods: {
setWidth() {
if (this.headerData) {
this.$set(this.headerData[this.headerData.length - 1], 'width', this.minWidth)
}
},
// 获取列表数据后,调用此方法
getTextWidth(ref) {
const trArr = []
const operateTd = []
const buttonNumArr = []
let isContainMore = false // 是否含有'更多'按钮,因为‘更多’后面有个尖括号
this.$nextTick(() => {
// 获取当前table的所有tr
let tr = []
if (ref && this.$refs[ref]) {
tr = this.$refs[ref].$el.querySelectorAll('tbody tr')
} else {
tr = document.querySelectorAll('tbody tr')
}
// console.log(tr)
if (tr.length) {
tr.forEach((item, index) => {
const t = trArr.find(t => t.rowIndex === item.rowIndex)
if (!t) trArr.push(item)
})
}
// 获取每一行tr中操作栏的按钮数量(操作栏在最后一列)
trArr.forEach(item => {
const span = document.createElement('span')
span.classList.add('getColumnWidth')
const td = item.querySelector('td:last-child .cell')
const allSpan = td.querySelectorAll('span')
const textArr = []// 存放每一行的按钮文字
// console.log(btns.length)
allSpan.forEach(b => {
if (b.innerHTML) {
const str = b.innerHTML + ''
const text = str.replace(/<[^>]+>/g, '')
if (text.indexOf('更多') !== -1) {
isContainMore = true
}
if (textArr.indexOf(text) === -1) {
textArr.push(text)
}
}
})
buttonNumArr.push(textArr.length)
// const cloneTd = btns.cloneNode(true)
if (td) {
span.innerHTML = textArr.join(',')
// span.appendChild(cloneTd)
document.body.appendChild(span)
operateTd.push(span.offsetWidth)
document.querySelector('.getColumnWidth').remove()
}
})
// 获取长度最大的操作栏
const width = Math.max(...operateTd)
// 获取按钮数量最多的操作栏
const buttonNum = Math.max(...buttonNumArr)
if (buttonNumArr.length < 1 || width < 29) {
this.minWidth = 63
} else {
let base = 35
if (isContainMore) {
base = base + 12
}
this.minWidth = width + (buttonNum - 1) * 10 + base
}
})
}
}
}
columnWidth.js 【按钮是图标版】(当按钮是图标时用这个,用这个)
export default {
data() {
return {
minWidth: 100
}
},
watch: {
minWidth() {
this.setWidth()
}
},
methods: {
setWidth() {
if (this.headerData) {
this.$set(this.headerData[this.headerData.length - 1], 'width', this.minWidth)
}
},
// 获取列表数据后,调用此方法
getTextWidth(ref) {
const trArr = []
// const operateTd = []
const buttonNumArr = []
// const isContainMore = false // 是否含有'更多'按钮,因为‘更多’后面有个尖括号
this.$nextTick(() => {
// 获取当前table的所有tr
let tr = []
if (ref && this.$refs[ref]) {
tr = this.$refs[ref].$el.querySelectorAll('tbody tr')
} else {
tr = document.querySelectorAll('tbody tr')
}
if (tr.length) {
tr.forEach((item, index) => {
const t = trArr.find(t => t.rowIndex === item.rowIndex)
if (!t) trArr.push(item)
})
}
// 获取每一行tr中操作栏的按钮数量(操作栏在最后一列)
trArr.forEach(item => {
const span = document.createElement('span')
span.classList.add('getColumnWidth')
const td = item.querySelector('td:last-child .cell')
const allIcon = td.querySelectorAll('i')
buttonNumArr.push(allIcon.length)
})
// 获取长度最大的操作栏
const buttonNum = Math.max(...buttonNumArr)
if (buttonNumArr.length < 1) {
this.minWidth = 50
} else {
//10是图标之间的间隔距离 22是图标的宽度 20表格一个col左边的内边距之和
this.minWidth = (buttonNum - 1) * 10 + buttonNum * 22 + 20
}
})
}
}
}
buttonGroup.vue 【按钮组件】
<template>
<div>
<el-button v-for="item in list" :key="item.label" type="text" @click="btnClick(item.row,item.funcMethod)">{{ item.label }}</el-button>
<el-dropdown v-if="extraList.length>0">
<el-button type="text">
更多<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="item in extraList" :key="item.label" @click.native="btnClick(item.row,item.funcMethod)">{{ item.label }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
export default {
props: {
btnGroup: {
type: Array,
default: () => []
}
},
data() {
return {
btnNumber: 3,
list: [],
extraList: []
}
},
watch: {
btnGroup: {
immediate: true,
deep: true,
handler(val) {
if (val && val.length) {
const result = val.filter(item => {
return !item.hide
})
if (result.length === this.btnNumber) {
this.list = result.slice(0, this.btnNumber)
this.extraList = []
} else if (result.length >= this.btnNumber + 1) {
this.list = result.slice(0, this.btnNumber - 1)
this.extraList = result.slice(this.btnNumber - 1)
} else {
this.list = result
this.extraList = []
}
}
}
}
},
methods: {
btnClick(row, funcMethod) {
this.$emit('clickTableBtn', { row, funcMethod })
}
}
}
</script>
<style lang="scss">
.el-button + .el-dropdown{
margin-left: 7px;
}
</style>
tablePage.vue 【代码没抄全。但是主要代码都在】
<template>
<el-table
:data="tableData"
style="width: 100%"
max-height="250"
>
<el-table-column
fixed
prop="date"
label="日期"
/>
<el-table-column
prop="name"
label="姓名"
/>
<el-table-column
prop="province"
label="省份"
/>
<el-table-column
prop="city"
label="市区"
width="120"
/>
<el-table-column
prop="address"
label="地址"
/>
<el-table-column
prop="zip"
label="邮编"
/>
<el-table-column
fixed="right"
label="操作"
:width="minWidth"
>
<template slot-scope="{row}">
<buttonGroup
:btn-group="dealGroup(row)"
@clickTableBtn="clickTableBtn"
/>
<!-- <el-button
type="text"
size="small"
@click.native.prevent="deleteRow(scope.$index, tableData)"
>
移除
</el-button> -->
</template>
</el-table-column>
</el-table>
</template>
<script>
import columnWidth from '@/mixins/columnWidth'
import buttonGroup from './buttonGroup.vue'
export default {
components: {
buttonGroup
},
mixins: [columnWidth],
data() {
return {
tableData: []
}
},
created() {
this.getDataList()
},
mounted() {
},
methods: {
dealGroup(row) {
return [
{
'label': '编辑',
'type': 'primary',
'hide': row.name !== '王小虎1',
'row': row,
'funcMethod': 'edit'
},
{
'label': '查看',
'row': row,
'funcMethod': 'see'
},
{
'label': '解锁',
'type': 'danger',
'hide': !this.$hasPermission('UNLOCK_TASK'),
'row': row,
'funcMethod': 'unlock'
},
{
'label': '取消',
'type': 'danger',
'hide': !this.$hasPermission('CANCLE_TASK'),
'row': row,
'funcMethod': 'cancel'
}
]
},
getDataList() {
this.tableData = [{
date: '2016-05-03',
name: '王小虎1',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}, {
date: '2016-05-02',
name: '王小虎2',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}, {
date: '2016-05-04',
name: '王小虎3',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}, {
date: '2016-05-01',
name: '王小虎4',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}, {
date: '2016-05-08',
name: '王小虎5',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}, {
date: '2016-05-06',
name: '王小虎6',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}, {
date: '2016-05-07',
name: '王小虎7',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}]
this.getTextWidth()
},
edit(row) {
console.log('bianji', row)
},
see(row) {
console.log('see', row)
},
unlock(row) {
console.log('unlock', row)
},
cancel(row) {
console.log('cancel', row)
},
clickTableBtn(data) {
this[data.funcMethod](data.row)
},
deleteRow(index, rows) {
rows.splice(index, 1)
}
}
}
</script>