1. 使用形式: 表格组件 x-table 使用时尽量看一下源码再使用
// 并不完善 有待继续开发
x-table(
:loading='loading' // Table加载
:columns='columns' // 表格配置数据
:data='featchData' // 接口返回数据
:immediately='false'// 是否立即执行 默认为true
:pageSizes='[20]' // 动态修改 pageSizes 默认为 [10, 20, 50, 100]
@search='onFeatchData' // 查询数据事件
)
<!-- 此处为iview表格自定义模版行为 -->
template(slot-scope="{ row, index }" slot="actions")
Button(type="primary" size="small" style="margin-right: 5px" @click="show(index)") View
Button(type="error" size="small" @click="remove(index)") Delete
2. 表格组件 - 配置文件 columns.js
<!-- 配置文件 -->
|—— key 对应数据展示字段
|—— title 展示内容
|—— width 表格宽度
|—— isHideColumn 为在表格中隐藏该列展示
|—— query 查询表单配置
|—— form: 'select' 表单类型
|—— defaultValue: 0 默认值
|—— clearable: false 是否显示清空所有 默认为true
|—— options 选项配置
|—— children 子级数据
export default [
{
key: 'card_type',
title: '卡类型',
isHideColumn: true,
query: {
form: 'select',
defaultValue: 0,
clearable: false,
options: [
{
label: '全部',
value: 0
},
{
label: '实体卡',
value: 2
},
{
label: '电子卡',
value: 3
},
]
},
},
{
key: 'query_date',
title: '时间',
isHideColumn: true,
query: {
form: 'date',
defaultValue: new Date(),
clearable: false,
},
},
{
key: 'window_date',
title: '窗口期',
isHideColumn: true,
query: {
form: 'select',
defaultValue: 0,
clearable: false,
options: [
{
label: '0天',
value: 0
},
{
label: '3天',
value: 3
},
{
label: '7天',
value: 7
},
{
label: '15天',
value: 15
},
{
label: '30天',
value: 30
},
]
},
},
{
key: 'ad_id',
title: '计划ID',
width: 200,
query: {
form: 'input',
}
},
{
key: 'dt',
title: '日期',
},
{
key: 'sold_unused_cnt',
title: '包含子元素',
children: [
{
key: 'total_income',
title: '总收入',
},
{
key: 'card_income',
title: '售卡收入',
},
]
},
{
key: 'actions',
title: '操作',
width: 160,
<!-- 需定义slot类型 对应第12行解释 -->
slot: 'actions'
},
]
3. 源码
<template lang="pug">
.x-table
//- 表单组件
.form-box.main(v-if='dynamicQueryList.length > 0')
//- 动态渲染各表单组件
.query-box
.query(v-for='i in dynamicQueryList' :key='i.key')
//- Title
.title {{ i.title }}:
//- 日期时间组件
DatePicker.form-item(
v-if='i.query.form === "date"'
v-model='form[i.key]'
:class="i.query.type || 'date'"
:type="i.query.type || 'date'"
:format='i.query.format || "yyyy-MM-dd"'
:placeholder='`请选择${i.placeholder || i.title}`'
:clearable='i.query.clearable !== undefined ? i.query.clearable : true'
)
//- 下拉选择组件
Select.form-item(
v-else-if='i.query.form === "select"'
v-model='form[i.key]'
:placeholder='`请选择${i.placeholder || i.title}`'
:clearable='i.query.clearable !== undefined ? i.query.clearable : true'
@clear='form[i.key] = null'
:filterable='i.query.filterable'
)
Option(
v-for='item in i.query.options'
:key='item.value'
:label='item.label'
:value='item.value'
)
//- 输入框组件
Input.form-item(
v-else
v-model='form[i.key]'
:placeholder='`请输入${i.placeholder || i.title}`'
:clearable='i.query.clearable !== undefined ? i.query.clearable : true'
)
//- 操作组件
.actions-box
.action_btn
Button(@click='handleSearch' type='primary') 查询
Button(@click='handleReset') 重置
//- 其他操作插槽
slot(name='action' :form='form')
//- 表格分页组件
.table-box.main
//- 头部slot
slot(name='header')
//- 表格组件
Table(border :loading='loading' :columns='columnsComputed' :data='data.list || []')
template(v-for='column in columnsSlotComputed' :slot='column.slot' slot-scope='params')
slot(:name='column.slot' v-bind='params')
//- 分页组件
Page.pagination(
v-if='data.total'
show-total
show-elevator
show-sizer
:total='data.total'
:current='option.page'
:page-size='option.pageSize'
:page-size-opts='option.pageSizes'
@on-change='handlePageChange'
@on-page-size-change='handlePageSizeChange'
)
//- 底部slot
slot(name='footer')
</template>
<script>
export default {
name: 'x-table',
props: {
loading: { // Table加载
type: Boolean,
default: false
},
columns: Array, // 配置表格数据
data: {
type: Object,
default: () => {
return {
list: [], // 数据列表
total: 0 // 数据总量
}
}
}, // 展示数据
immediately: { // 是否立即执行
type: Boolean,
default: true
},
pageSizes: { // pageSizes 动态配置
type: Array,
default: () => []
}
},
data () {
return {
// 检索表单绑定
form: {},
// 检索表单列表数据
dynamicQueryList: [],
option: {
page: 1, // 当前展示页码
pageSize: 20, // 每页展示数量
pageSizes: [10, 20, 50, 100] // 每页显示个数选择器的选项设置
}
}
},
created () {
// 设置检索数据
this.setQuery()
// 修改PageSizes配置
if (this.pageSizes.length) {
this.option.pageSizes = this.pageSizes
this.option.pageSize = this.pageSizes[0]
}
},
computed: {
// 计算隐藏列展示项
columnsComputed () {
return this.columns.filter(i => !i.isHideColumn)
},
// 计算存在slot展示项
columnsSlotComputed () {
return this.columns.filter(i => !!i.slot)
}
},
methods: {
// 设置检索数据
setQuery () {
// 表单映射
this.columns.forEach(column => {
if (column.query) {
this.dynamicQueryList.push(column) // 保存表单查询元素配置
const defaultValue = column.query.defaultValue === undefined ? null : column.query.defaultValue // 获取初始值
this.$set(this.form, column.key, defaultValue) // 动态设置query
}
})
// 立即执行获取数据
this.immediately && this.handleSearch()
},
// 重置数据
handleReset () {
this.dynamicQueryList.forEach(item => {
this.form[item.key] = item.query.defaultValue === undefined ? null : item.query.defaultValue
})
this.handleSearch()
},
// 查询数据
handleSearch () {
const { page, pageSize } = this.option
// 查询参数以及分页参数
const query = {
form: this.form,
option: {
page,
pageSize
}
}
this.$emit('search', query)
},
// 页码改变的回调,返回改变后的页码
handlePageChange (page) {
this.option.page = page
this.handleSearch()
},
// 切换每页条数时的回调,返回切换后的每页条数
handlePageSizeChange (pageSize) {
this.option.pageSize = pageSize
this.handleSearch()
}
}
}
</script>
<style scoped lang="less">
.x-table {
.form-box {
margin-bottom: 20px;
}
.query-box {
display: flex;
align-items: center;
flex-flow: row wrap;
.query {
display: flex;
align-items: center;
margin: 0 20px 14px 0;
.form-item {
width: 180px;
margin-left: 10px;
}
.daterange {
width: 200px;
}
.datetimerange {
width: 320px;
}
}
}
.actions-box {
button {
margin-right: 10px;
}
}
.pagination {
margin-top: 14px;
}
}
</style>