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