前言:
項目中,使用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
