在背景管理和中台項目中, table是使用率是特别的高的, 雖然element已經有table元件, 但是分頁和其他各項操作還是要寫一堆的代碼, 是以就在原有的基礎上做了進一步的封裝
所涵蓋的功能有:
内容展示
,
操作欄
,
選擇框
,
分頁
,
圖檔渲染
,
開關
,
過濾器(時間格式化)
直接上代碼
元件:
<template>
<div class="hello">
<el-table
:data="tableData"
style="width: 98%"
@selection-change="handleSelectionChange"
border>
<el-table-column v-if="type=='checkbox'" label="選擇">
<template slot-scope="{ row }">
<el-checkbox v-model="row.isChecked" @change="handleChecked(row)"></el-checkbox>
</template>
</el-table-column>
<el-table-column v-if="type=='selection'" :reserve-selection="true" type="selection" width="55" />
<el-table-column v-if="type=='index'" type="index" label="序号" width="55" />
<template v-for="(item, index) of tableTitle">
<el-table-column
:prop="item.prop"
:label="item.label"
:key="index"
:min-width="item.width"
>
<template slot-scope="{ row, $index }" style="height: 100%;">
<span v-if="item.filter == 'date'">
{{ row[item.prop] | dateFilter }}
</span>
<span v-else-if="item.filter == 'time'">
{{ row[item.prop] | timeFilter }}
</span>
<span v-else-if="item.filter == 'image' && row[item.prop]">
<img :src="row[item.prop]" alt="" style="height: 45px;">
</span>
<span v-else-if="item.filter == 'switch'">
<el-switch
v-model="row[item.prop]"
@change="change(row, $index)"
/>
</span>
<span v-else>
{{ row[item.prop] }}
</span>
</template>
</el-table-column>
</template>
<!-- 插槽: 操作-->
<el-table-column label="操作" v-if="ishandle" :width="handleWidth">
<template slot-scope="scope">
<slot name="handle" :row="scope.row" :index="scope.$index"></slot>
</template>
</el-table-column>
</el-table>
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
:page-size="pageSize"
:current-page.sync="current"
:page-sizes="[10, 20, 30, 40, 50, 100]"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
handleWidth: { // 操作寬度
default: 200
},
ishandle: { // 是否有操作按鈕
type: Boolean,
default: true
},
type: String, // 單選/多選/或值展示
tableTitle: Array, // 表頭
tableData: Array, // 資料
},
data () {
return {
total: 1000,
pageSize: 10,
current: 1
}
},
methods: {
handleSizeChange (size) { // 改變每頁數量
this.pageSize = size
this.$emit('handleChange', this.pageSize, this.current)
},
handleChecked (row) { // 單選
if (row.isChecked) {
this.tableData.map(item => {
if (item.id != row.id) {
this.$set(item, 'isChecked', false)
}
})
this.$emit('handleChecked', row)
} else {
this.$emit('handleChecked', '', row)
}
},
handleSelectionChange (row) { // 多選
this.$emit('handleChecked', row)
},
handleCurrentChange (current) { //換頁
this.current = current
this.$emit('handleChange', this.pageSize, this.current)
},
change (row, index) { // 切換開關
this.$emit('handleSwitch', row, index)
},
}
}
</script>
<style scoped lang="scss">
</style>
在父元件中調用:
<template>
<div class="home">
<ComTable
:handleWidth="200"
:tableTitle="tableTitle"
:tableData="tableData"
@handleChange="handleChange"
@handleSwitch="handleSwitch"
@handleChecked="handleChecked"
>
<template slot="handle" slot-scope="scope">
<el-button type="text" size="small">編輯{{scope.index}}</el-button>
</template>
</ComTable>
</div>
</template>
<script>
import ComTable from '@/components/Com_Table.vue'
export default {
name: 'Home',
components: {
ComTable
},
data () {
return {
tableTitle: [{
prop: 'name',
label: '姓名',
width: '200',
},{
prop: 'sex',
label: '性别',
width: '200',
filter: 'switch',
},{
prop: 'url',
label: '頭像',
width: '200',
filter: 'image',
},{
prop: 'date',
label: '出生日期',
width: '200',
filter: 'date'
},],
tableData: [{
id: 1,
name: '張三',
sex: true,
url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
date: new Date()
},{
id: 2,
name: '張三',
sex: true,
url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
date: new Date()
},{
id: 3,
name: '張三',
sex: true,
url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
date: new Date()
},{
id: 4,
name: '張三',
sex: true,
url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3202059567,1723387850&fm=26&gp=0.jpg',
date: new Date()
},],
}
},
mounted() {
},
methods: {
handleChange (size, current) {
// 分頁改變時的回調---- size: 每頁的數量 current: 第幾頁
console.log(size, current, 'tableData')
},
handleSwitch (row, index) {
// 切換開關時的回調-======== this.tableData: 滑塊值改變後的資料.row: 目前行資料 index: 目前行的索引
console.log(this.tableData, '--tableData---', row, index)
},
handleChecked (val) {
// 勾選時的回調---- val: 選中的資料 多選是val是數組, 單選時是對象
console.log(val, 'val===')
}
}
}
</script>
元件中有使用過濾器, 可以定義一下全家的過濾器,然後引入, 這裡要根據自己的檔案來進行調整. 送上我這裡用的兩個過濾器
// 注冊全局的過濾器 {{ msg | dateFilter }}
import Vue from 'vue'
import moment from 'moment'
// 展示日期格式: YYYY-MM-DD
Vue.filter('dateFilter', function (dataStr, pattern = 'YYYY-MM-DD') {
if (dataStr) {
return moment(dataStr).format(pattern)
} else {
return dataStr
}
})
// 展示日期格式: YYYY-MM-DD HH:mm:ss
Vue.filter('timeFilter', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
if (dataStr) {
return moment(dataStr).format(pattern)
} else {
return dataStr
}
})
下面是相關參數的說明:
type: 表格類型. 非必傳. 值: selection(多選) / checkbox(單選) 類型: string /index:序号1.2.3...
handleWidth: 操作欄寬度 非必傳 預設200
tableTitle: 表頭. 必傳. 類型: 數組 例:
tableTitle: [{
prop: 'name', 綁定的字段
label: '姓名', 表頭名稱
width: '200', 列寬度
filter: 'date' 過濾器. 需要展示的類型. 非必傳. 值:
date: 日期格式(YYYY-MM-DD)
time: 時間格式(YYYY-MM-DD : HH:mm:ss)
image: 圖檔
}]
> tableData: 要展示的資料. 必傳 類型: array 例:
插槽:
slot="handle": handle: 插槽名稱
slot-scope="scope": scope: 元件傳遞給插槽的值 scope.row: 目前行的内容 scope.index: 目前行的索引
事件:
handleChange (size, current) {}, //分頁改變時的回調---- size: 每頁的數量 current: 第幾頁
handleSwitch (row, index) {}, // 切換開關時的回調-======== this.tableData: 滑塊值改變後的資料.row: 目前行資料 index: 目前行的索引
handleChecked (val) {}, // 勾選時的回調---- val: 選中的資料 多選是val是數組, 單選時是對象
封裝并不是很全面很精緻, 但是至少可以省點事~~~
以上代碼還未經過項目的檢驗, 屬于雛形, 還需要不斷的優化和改進, 如遇坑, 請留言. 謝謝!!!