Vue + Element-UI管理系统中 Table表格 二次封装
前言:
项目中,使用vue + element 的后台管理系统中 用的table表格很多,而且大部分很相似,一遍遍的写,代码会变得很冗余,
于是利用Vue + Element Table 重新封装出了一套表格组件。
下面是常见的table效果图:
包含页面跳转、属性过滤、图片、文字颜色显示、switch切换、操作栏等,
数据使用了 mockjs 创建

1. 在 component中 创建文件夹 talbeData 添加文件 index.vue
<template>
<div class="app-container">
<el-table
:data="dataList"
v-loading="loading"
border
fit
highlight-current-row
style="width: 100%;"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange">
<!-- 是否有多选 -->
<el-table-column type="selection" width="55" v-if="table_config.isCheckBox"></el-table-column>
<!-- 是否需要序号 -->
<el-table-column type="index" label="序号" width="55" align="center" v-if="table_config.isIndex"/>
<el-table-column
v-for="item in table_config.thead"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:min-width="item.minWidth"
:sortable="item.sortable ? true : false"
align="center">
<template slot-scope="scope">
<!-- 有状态过滤 -->
<span v-if="item.filter" :class="item.specialClass && item.specialClass(scope.row)">
{{item.callback && item.callback(scope.row)}}
</span>
<!-- 图片展示 -->
<img v-else-if="item.image" :src="scope.row[item.prop]" style="width:40px; height: 40px">
<!-- switch开关 -->
<el-switch
v-else-if="item.switch"
v-model="scope.row[item.prop]"
active-text="启用"
active-value = 1
inactive-value = 0
inactive-text="停用"
@change="item.callback && item.callback(scope.row)"
>
</el-switch>
<!-- 有跳转 -->
<router-link
v-else-if="item.router"
:to="{path: item.routerPath, query: {name: scope.row[item.prop]}}"
>
{{ scope.row[item.prop]}}
</router-link>
<!-- 默认展示 -->
<span v-else>{{ scope.row[item.prop]}}</span>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column
fixed="right"
:label="table_config.operation.label"
:width="table_config.operation.width"
align="center"
v-if="isShow">
<template slot-scope="scope">
<template v-if="table_config.operation.cols">
<div class="btn"
v-for="item in table_config.operation.cols.slice(0,2)"
:key="item.label">
<el-button @click="item.handleRow(scope.row,item.label)" :type="item.type" size="small">
{{item.label}}
</el-button>
</div>
</template>
<!-- 操作列超过3个,用更多下拉显示 -->
<el-dropdown v-if="isShowOperationCols">
<span class="el-dropdown-link">
更多<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="item in table_config.operation.cols.slice(2)"
:key="item.label"
@click.native="item.handleRow(scope.row,item.label)">
{{item.label}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
props: {
config: {
type: Object,
default: () => {}
},
dataList: {
type: Array,
default: () => {
return []
}
},
loading: {
type: Boolean,
default: false
}
},
data() {
return {
table_config: {
thead: [], // 表格头
isCheckBox: false, // 是否多选
isIndex: false, // 是否有序号
isOperation: true, // 是否有操作列表
operation: { // 操作
cols: []
},
}
}
},
computed: {
isShow() {
return this.table_config.isOperation && this.table_config.operation.cols.length
},
isShowOperationCols() {
let list = this.table_config.operation.cols
return list.length && list.length > 2
}
},
watch: {
// 监听传过来的config,进行初始化
config: {
handler(newVal) {
if(newVal) {
this.initConfig()
}
},
immediate: true
}
},
mounted() {
},
methods: {
// 初始化配置
initConfig() {
for(let key in this.config) {
if(Object.keys(this.table_config).includes(key)) {
this.table_config[key] = this.config[key]
}
}
},
// 多选事件
handleSelectionChange(val) {
this.$emit('selection-change', val)
},
// 排序事件
handleSortChange(val) {
this.$emit('sort-change', val)
}
}
}
</script>
<style scoped>
.btn{
display: flex;
justify-content: center;
display: inline-block;
margin: 5px 0 0 10px;
}
.btn:first-child{
margin-left: 0;
}
.color1{
color: red;
}
.color2{
color: green;
}
.color3{
color: blue;
}
.el-dropdown{
margin-left: 10px;
cursor: pointer;
}
</style>
2.在组件中引用
<template>
<div>
<tableData
:config="table_config"
:dataList="dataList"
:loading="loading"
@selection-change="selectionChange"
@sort-change="sortChange"
/>
<pagination
:total="total"
:pageNum.sync="pages.pageNum"
:limit.sync="pages.pageSize"
@pagination="fetchData()"
/>
</div>
</template>
<script>
import { getList } from '@/api/table'
import TableData from '@/components/tableData';
import Pagination from '@/components/pagination';
import { sexType,roleType } from '../utils/config';
export default {
components: {
TableData,
Pagination
},
data() {
return {
// 配置项
table_config: {
thead: [
{
label: '姓名',
prop: 'name',
minWidth: '150px',
router: true,
routerPath: 'xxx'
},
{
label: '性别',
prop: 'sex',
minWidth: '100px',
filter: true,
callback: (rowData) => {
let data = sexType[rowData.sex]
if(data) {
return data.label
}
}
},
{label: '头像',prop: 'img', minWidth: '100px',image: true},
{label: '电话',prop: 'phone',minWidth: '150px',},
{label: '时间',prop: 'time', minWidth: '200px',sortable: true},
{
label: '角色',
prop: 'role',
minWidth: '150px',
filter: true,
colorName: '',
callback: (rowData) => {
let data = roleType[rowData.role]
if(data) {
return data.label
}
},
specialClass: (rowData) => {
let data = roleType[rowData.role]
if(data) {
return data.className
}
}
},
{
label: '状态',
prop: 'status',
minWidth: '150px',
switch: true,
callback: this.changeStatus
},
],
isCheckBox: true,
isIndex: true,
isOperation: true,
// 表格操作列
operation: {
label: '操作',
width: '200',
cols: [
{
label: '编辑',
type: 'primary',
handleRow: this.handleRow
},
{
label: '删除',
type: 'danger',
handleRow: this.handleRow
}
]
},
},
dataList: [],
loading: false,
pages: {
pageNum: 1,
pageSize: 10
},
total: 0
}
},
mounted() {
this.fetchData()
},
methods: {
fetchData() {
this.loading = true
getList(this.pages).then(res => {
if(res.data.code === 20000) {
this.dataList = res.data.data.items
this.total = res.data.data.total
this.loading = false
}
})
setTimeout(() => {
this.loading = false
},3000)
},
// 操作方法
handleRow(rowData,label) {
console.log(rowData,label);
},
// 多选方法
selectionChange(val) {
console.log(val);
},
// 排序方法
sortChange(val) {
console.log(val);
},
changeStatus(val) {
console.log(val);
}
}
}
</script>
3.配置参数
table_config
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| thead | 表格的列 | Array | [] |
| isCheckBox | 是否多选 | Boolean | false |
| isIndex | 是否有序号 | Boolean | false |
| isOperation | 是否有操作列 | Boolean | true |
| operation | 操作列 | Object | - |
配置列 thead
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| label | 标题 | string | - |
| prop | 字段名 | string | - |
| minWidth | 最小宽度 | string | - |
| image | 是否图片 | Boolean | false |
| sortable | 是否排序 | Boolean | false |
| router | 是否有跳转 | Boolean | false |
| filter | 是否有信息过滤 | Boolean | false |
| switch | 是否有开关 | Boolean | false |
| routerPath | 跳转地址 | string | - |
Table Events
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| selection-change | 多选事件 | Function | - |
| sort-change | 排序事件 | Function | - |
table-column Events
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| callback | 回调函数 | Function(row) | - |
| specialClass | 特殊字体颜色函数 | Function(row) | - |
| handleRow | 操作列回调函数 | Function(row, label) | - |
源码
如果你感兴趣的话,请前往 GitHub 查看源码和完整文档。
https://github.com/wangibook/my-table-component

浙公网安备 33010602011771号