說明:css
在管理系統中,涉及到不少根據查詢條件,查出數據,而後使用表格展現的頁面。vue
對於這種複用性極強的page,提供一個公共的組件是很必要的(樣式統1、高效開發)。bash
主要切分爲3個組件。async
一、Filter 功能:搜索條件,搜索按鈕flex
二、Table 功能:展現數據,列表內實現一些操做如:查看、編輯等ui
三、Pagination 功能:分頁,控制頁面大小,頁面數this
調用方式:spa
<template lang="pug">
FilterTable(
:list="list"
:filters="filters"
:tableList="tableList"
:pageNum="pageNum"
:pageSize="pageSize"
:total="total"
@listenHandleClickFilterButton="handleClickFilterButton"
@listenHandleClickTableColumnHref="handleClickTableColumnHref"
@listenHandleChangePaginationSize="handleChangePaginationSize"
@listenHandleChangePaginationNum="handleChangePaginationNum"
)
</template>
import FilterTable from '@/components/common/c-filter-table'
import list from './list'
export default {
components: {
FilterTable
},
created() {},
data() {
return {
pageNum: 1,
pageSize: 20,
total: 0,
tableList: [],
list,
filters: list.filterList.reduce((obj, item) => {
if (item.type !== 'button') {
obj[item.key] = ''
}
return obj
}, {}),
}
},
methods: {
handleClickFilterButton(buttonKey) {
if (buttonKey === 'search') {
this.handleClickSearch()
}
if (buttonKey === 'reset') {
this.handleClickReset()
}
if (buttonKey === 'export') {
this.handleClickExport()
}
if (buttonKey === 'add') {
this.handleClickAdd()
}
},
handleClickTableColumnHref(columnKey, row) {
if (columnKey === 'edit') {
console.log('click column edit')
}
},
handleChangePaginationSize(size) {
this.pageNum = 1
this.pageSize = size
this.handleClickSearch()
},
handleChangePaginationNum(num) {
this.pageNum = num
this.handleClickSearch()
},
async handleClickSearch() {
...
},
handleClickAdd() {
...
},
async handleClickReset() {
this.filters = list.filterList.reduce((obj, item) => {
if (item.type !== 'button') {
obj[item.key] = ''
}
return obj
}, {})
...
}
}
}
複製代碼
一個list配置以下:code
const list = {
filterList: [
{
label: '座位號',
key: 'id',
type: 'input',
span: 6
},
{
label: '班級',
key: 'class',
type: 'select',
options: [
{
key: '1',
label: '一班',
val: '1'
},
{
key: '2',
label: '二班',
val: '2'
}
],
span: 6
},
{
label: '入學日期',
key: 'statPeriod',
type: 'datePicker',
span: 6,
config: {
type: 'date',
placeholder: '選擇日期'
}
},
{
label: '入校時長',
key: 'backDate',
type: 'datePicker',
config: {
type: 'daterange',
rangeSeparator: '至',
startPlaceholder: '開始日期',
endPlaceholder: '結束日期'
},
span: 12
},
{
label: '查詢',
key: 'search',
type: 'button',
config: {
type: 'primary'
},
span: 2
},
{
label: '重置',
key: 'reset',
type: 'button',
config: {
type: ''
},
span: 2
},
{
label: '導出',
key: 'export',
type: 'button',
config: {
type: 'success'
},
span: 2
}
],
tableColumns: [
{
label: '狀態',
key: 'stateName'
},
{
label: '編號',
key: 'code'
},
{
label: '姓名',
key: 'name'
},
{
label: '年齡',
key: 'remark'
},
{
label: '操做',
key: 'edit',
type: 'href',
filter: () => '編輯'
}
],
複製代碼
filterList
用於配置搜索框 對應的事件處理爲:listenHandleClickFilterButton
component
tableColumns
用於配置表格字段 對應的事件處理爲:listenHandleClickTableColumnHref
tableList: 搜索結果,傳入table
的數據
pageNum、pageSize、total: 分頁須要的數據
對應的控制分頁事件爲:listenHandleChangePaginationSize、listenHandleChangePaginationNum
c-filter-table
完整代碼:
<template lang="pug">
.c-table-container
el-form.search-box
el-row(:gutter="20")
template(v-for="item in list.filterList")
el-col(
v-if="item.type==='button'"
:span="item.span"
:key="item.key")
el-button(:type="item.config.type" @click="handleClickFilterButton(item.key)") {{ item.label }}
el-col(
v-else
:span="item.span"
:key="item.key")
el-form-item(
:label="item.label"
:prop="item.key"
label-width="110px")
el-input(
v-if="item.type==='input'"
v-model="filters[item.key]")
el-select(
v-if="item.type==='select'"
v-model="filters[item.key]")
el-option(
v-for="option in item.options"
:key="option.key"
:value="option.val"
:label="option.label")
el-select(
v-if="item.type==='select-filterable'"
v-model="filters[item.key]"
filterable placeholder="請選擇")
el-option(
v-for="option in item.options"
:key="option.key"
:value="option.val"
:label="option.label")
el-date-picker(
v-if="item.type==='datePicker'"
v-model="filters[item.key]"
:type="item.config.type"
:range-separator="item.config.rangeSeparator"
:start-placeholder="item.config.startPlaceholder"
:end-placeholder="item.config.endPlaceholder")
el-table(:data="tableList" border)
el-table-column(
type="index"
label="序號"
align="center")
el-table-column(
v-for="item in list.tableColumns"
:key="item.key"
:label="item.label"
:prop="item.key"
align="center")
template(slot-scope="scope")
a(
v-if="item.type === 'href'"
class="blue"
@click="handleClickTableColumnHref(item.key, scope.row)"
) {{ item.filter(scope.row) }}
span(v-else) {{ item.filter ? item.filter(scope.row) : scope.row[item.key] }}
el-pagination(
@size-change="handleChangePaginationSize"
@current-change="handleChangePaginationNum"
:page-sizes="[10, 20, 50, 100]"
:current-page.sync="selfPageNum"
:page-size="selfPageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total")
</template>
<script>
export default {
props: [
'list',
'tableList',
'total',
'pageNum',
'pageSize',
'filters',
'listenHandleClickFilterButton',
'listenHandleClickTableColumnHref',
'listenHandleChangePaginationSize',
'listenHandleChangePaginationNum'
],
data() {
return {
selfPageNum: this.pageNum,
selfPageSize: this.pageSize
}
},
methods: {
handleClickFilterButton(filterKey) {
this.$emit('listenHandleClickFilterButton', filterKey)
},
handleClickTableColumnHref(columnKey, row) {
this.$emit('listenHandleClickTableColumnHref', columnKey, row)
},
handleChangePaginationSize(val) {
this.selfPageNum = 1
this.selfPageSize = val
this.$emit('listenHandleChangePaginationSize', val)
},
handleChangePaginationNum(val) {
this.selfPageNum = val
this.$emit('listenHandleChangePaginationNum', val)
}
}
}
</script>
<style scoped lang="scss">
.el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.blue {
color: #409eff;
}
.c-table-container {
padding: 15px;
min-height: 500px;
.search-box.el-form {
display: flex;
flex-wrap: wrap;
.el-form-item {
.el-input {
width: 160px;
}
}
}
.extand {
.el-form-item {
width: 25%;
}
}
.el-pagination {
text-align: right;
padding: 10px;
}
}
</style>
複製代碼