在利用element-ui Table编写项目时,会存在表格展示的数据存在分页的情况,基本每个页面都要配置,很影响开发效率,也不利于后期维护,所以统一封装一下,便于开发使用。
How to Use:
在src/components
目录中创建base-table
,引用到自己的页面中,可以根据自己的需求自由更改。
base-table组件封装
<template>
<div class="base-table bg-white">
<!-- 表格上方操作栏 ,插槽actionBar,配置操作按钮-->
<div class="table-title flex justify-between align-center">
<div class="font-sm">{{ tableTitle }}</div>
<slot name="actionBar"></slot>
</div>
<el-table
:span-method="arraySpanMethod"
v-loading="loading"
:element-loading-text="$t('tips.loading')"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(255, 255, 255, 0.8)"
:header-row-class-name="tableHeader"
:header-cell-style="{ background: '#E3E3E3', color: '#333333' }"
:row-class-name="tabRowClassName"
@selection-change="handleCustomSelect"
ref="table"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
:data="tableData"
:rowArr="rowSpanArr"
style="width: 100%"
:border="border"
>
<el-table-column v-if="selection" type="selection" width="55"> </el-table-column>
<el-table-column v-for="item of labelData" :min-width="item.minWidth" :width="item.width" :label="item.label" :fixed="item.fixed" :align="item.align || 'center'" :key="item.id">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :disabled="!scope.row.showTooltip" v-model="scope.row.showTooltip" :content="scope.row[item.prop]" placement="bottom-start">
<div @mouseenter="showTips($event, scope.row, scope.index, item.prop)" class="cell-word">{{ scope.row[item.prop] }}</div>
</el-tooltip>
</template>
</el-table-column>
<slot></slot>
</el-table>
<div class="table-bottom">
<el-pagination
v-if="pagi"
@size-change="handleSelectionChange"
@current-change="getCurrentPage"
layout="total, sizes, prev, pager, next"
:page-sizes="pageSizeArr"
:page-size="pageSize"
:current-page.sync="tableCurrentPage"
:total="counts"
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
name: 'baseTable',
props: {
loading: Boolean,
tableData: Array,
labelData: Array,
rowSpanArr: Array,
pagi: Boolean,
counts: Number,
currentPage: Number,
selection: Boolean,
isIndex: Boolean,
tableTitle: String,
border: {
type: Boolean,
default: true
},
merge: {
type: Boolean,
default: false
},
mergeCells: {
type: Boolean,
default: false
},
index: {
type: Number,
default: 6
}
},
data() {
return {
pageSizeArr: [5, 10, 15, 20, 25],
pageSize: 10,
tableHeader: 'table-header',
tableCurrentPage: this.currentPage
}
},
created() {},
methods: {
/**
* @description: 合并行或列的计算方法
* @param {*} row 当前行
* @param {*} column 当前列
* @param {*} rowIndex 当前行号
* @param {*} columnIndex 当前列号
*/
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
if (this.merge) {
// 只合并区域位置
if (columnIndex === 0) {
const _row = this.rowSpanArr[rowIndex]
return {
rowspan: _row, // 行
colspan: 1 // 列
}
}
}
if (this.mergeCells) {
// 只合并区域位置
if (columnIndex === 0) {
if (rowIndex % this.index === 0) {
return {
rowspan: 6,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
}
// this.$emit('arraySpanMethod',{ row, column, rowIndex, columnIndex })
},
/**
* @description: 用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否
* @param {*} row 当前行
*/
handleCustomSelect(row) {
this.$emit('selection-change', row)
},
/**
* @description: 通过方法计算返回对应class样式
* @param {*} row 当前行
* @param {*} rowIndex 当前行号
* @return {Boolen}
*/
tabRowClassName({ row, rowIndex }) {
let index = rowIndex + 1
if (index % 2 === 0) {
return 'warning-row'
}
},
/**
* @description: currentPage 改变时会触发
* @param {*} index 跳转页码
* @return {*}
*/
getCurrentPage(index) {
this.$emit('page-change', index)
},
/**
* @description: pageSize 改变时会触发
* @param {*} val 每页条数
* @return {*}
*/
handleSelectionChange(val) {
this.$emit('size-change', val)
},
showTips(obj, row, index, prop) {
/* obj为鼠标移入时的事件对象 */
/* currentWidth 为文本在页面中所占的宽度,创建标签,加入到页面,获取currentWidth ,最后在移除 */
let TemporaryTag = document.createElement('span')
TemporaryTag.innerText = row[prop]
TemporaryTag.className = 'getTextWidth'
document.querySelector('body').appendChild(TemporaryTag)
let currentWidth = document.querySelector('.getTextWidth').offsetWidth
document.querySelector('.getTextWidth').remove()
/* cellWidth为表格容器的宽度 */
const cellWidth = obj.target.offsetWidth
/* 当文本宽度小于||等于容器宽度两倍时,代表文本显示未超过两行 */
currentWidth <= 2 * cellWidth ? (row.showTooltip = false) : (row.showTooltip = true)
this.$set(this.tableData, index, row)
console.log(currentWidth <= 2 * cellWidth ? (row.showTooltip = false) : (row.showTooltip = true))
}
},
mounted() {},
watch: {
currentPage() {
this.tableCurrentPage = this.currentPage
}
}
}
</script>
<style lang="scss" scoped>
.base-table {
border-radius: 4px;
padding: 16px;
margin-top: 8px;
.table-title {
margin-bottom: 16px;
color: #4c4c4c;
}
.table-bottom {
margin-top: 20px;
display: flex;
justify-content: center;
}
/deep/ tr .cell {
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
word-break: break-all;
}
.cell-word {
cursor: pointer;
}
/deep/ .warning-row {
background-color: #f3f3f3;
}
/deep/.el-table {
.cell {
.el-button {
margin-bottom: 4px;
margin-left: 4px;
}
}
}
.spans {
margin: 0 6px;
display: inline-block;
cursor: pointer;
}
}
</style>
传参说明
Table Attributes
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
tableTitle | 表格上方标题 | String | - |
tableData | 显示的数据 | Array | - |
labelData | table-column相关配置信息,详见Table-column Attributes | Array | - |
loading | 区域加载效果,在表格等容器中加载数据时显示。 | Boolean | - |
selection | 是否在表格第一列显示多选框 | Boolean | - |
border | 是否显示表格边框 | Boolean | true |
rowSpanArr | 合并行或列的数组 [rowIndex/columnIndex] | Array | - |
merge | 合并行,配合rowSpanArr使用 | Boolean | false |
mergeCells | 合并列,配合rowSpanArr使用 | Boolean | false |
pagi | 是否显示表格下面的分页 | Boolean | - |
counts | 总条目数 | Number | - |
currentPage | 当前页数,支持 .sync 修饰符 | Number | - |
Table Events
事件名 | 说明 | 参数 |
---|---|---|
selection-change | table第一列,多选项发生变化时会触发该事件 | selection |
page-change | currentPage 改变时会触发 | 当前页 |
size-chang | pageSize 改变时会触发 | 每页条数 |
Table-column Attributes
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
label | 显示的标题 | String | - |
prop | 对应列内容的字段名 | String | - |
width | 对应列的宽度 | String | - |
fixed | 列是否固定在左侧或者右侧,true 表示固定在左侧 | string, boolean | - |
align | 对齐方式 | String | center |
使用模板
需要使用的页面
// template
<base-table
tableTitle="角色列表"
:label-data="tableData.cloumn"
:table-data="tableData.data"
:counts="count"
pagi
selection
:loading="loading"
@size-change="getSelectionChange"
:current-page="searchParams.page"
@page-change="getCurrentPage"
@selection-change="handleselectione"
>
<!-- 表格头部右侧操作栏 -->
<template slot="actionBar">
<el-button type="primary">新增角色</el-button>
</template>
<!-- 自定义操作列 -->
<el-table-column align="center" :label="$t('account.actions')">
<template slot-scope="scope">
<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</base-table>
import BaseTable from '@/components/common/baseTable.vue'
// data
export default {
data() {
return {
loading: true,
tableData: {
// 表格数据
data: [],
cloumn: [
{ label: '角色名称'), prop: 'Name', fixed: true, align: 'left', minWidth: '100px' },
{ label: '角色明细', prop: 'Description', width: '130px' }
]
},
searchParams: { // 请求参数
page: 1,
limit: 10
},
count: 234 // 列表总数
}
},
components: { BaseTable },
}
//methods
// 请求数据
fetch(){},
// 下拉框选择每页显示条数
getSelectionChange(val) {
this.searchParams.limit = val
this.searchParams.page = 1
this.fetch()
},
// 切换分页
getCurrentPage(val) {
this.searchParams.page = val
this.fetch()
},
// 点击选中当前行
handleselectione(value) {
console.log(value)
},
更多文章__> >> 码砖猿的技术博客