表格组件封装

This commit is contained in:
BianLzhaoMin 2024-08-07 09:53:21 +08:00
parent 14f0bc1732
commit ef97374758
6 changed files with 396 additions and 118 deletions

View File

@ -1,129 +1,172 @@
<template>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
<el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
</el-tooltip>
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
</el-tooltip>
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
<el-button size="mini" circle icon="el-icon-menu" />
<el-dropdown-menu slot="dropdown">
<template v-for="item in columns">
<el-dropdown-item :key="item.key">
<el-checkbox :checked="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" />
</el-dropdown-item>
</template>
</el-dropdown-menu>
</el-dropdown>
</el-tooltip>
</el-row>
<el-dialog :title="title" :visible.sync="open" append-to-body>
<el-transfer
:titles="['显示', '隐藏']"
v-model="value"
:data="columns"
@change="dataChange"
></el-transfer>
</el-dialog>
</div>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip
class="item"
effect="dark"
:content="showSearch ? '隐藏搜索' : '显示搜索'"
placement="top"
v-if="search"
>
<el-button
size="mini"
circle
icon="el-icon-search"
@click="toggleSearch()"
/>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="刷新"
placement="top"
>
<el-button
size="mini"
circle
icon="el-icon-refresh"
@click="refresh()"
/>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="显隐列"
placement="top"
v-if="columns"
>
<el-button
size="mini"
circle
icon="el-icon-menu"
@click="showColumn()"
v-if="showColumnsType == 'transfer'"
/>
<el-dropdown
trigger="click"
:hide-on-click="false"
style="padding-left: 12px"
v-if="showColumnsType == 'checkbox'"
>
<el-button size="mini" circle icon="el-icon-menu" />
<el-dropdown-menu slot="dropdown">
<template v-for="item in columns">
<el-dropdown-item :key="item.key">
<el-checkbox
:checked="item.visible"
@change="checkboxChange($event, item.label)"
:label="item.label"
/>
</el-dropdown-item>
</template>
</el-dropdown-menu>
</el-dropdown>
</el-tooltip>
</el-row>
<el-dialog :title="title" :visible.sync="open" append-to-body>
<el-transfer
:titles="['显示', '隐藏']"
v-model="value"
:data="columns"
@change="dataChange"
></el-transfer>
</el-dialog>
</div>
</template>
<script>
export default {
name: "RightToolbar",
data() {
return {
//
value: [],
//
title: "显示/隐藏",
//
open: false,
};
},
props: {
/* 是否显示检索条件 */
showSearch: {
type: Boolean,
default: true,
},
/* 显隐列信息 */
columns: {
type: Array,
},
/* 是否显示检索图标 */
search: {
type: Boolean,
default: true,
},
/* 显隐列类型transfer穿梭框、checkbox复选框 */
showColumnsType: {
type: String,
default: "checkbox",
},
/* 右外边距 */
gutter: {
type: Number,
default: 10,
},
},
computed: {
style() {
const ret = {};
if (this.gutter) {
ret.marginRight = `${this.gutter / 2}px`;
}
return ret;
}
},
created() {
if (this.showColumnsType == 'transfer') {
//
for (let item in this.columns) {
if (this.columns[item].visible === false) {
this.value.push(parseInt(item));
name: 'RightToolbar',
data() {
return {
//
value: [],
//
title: '显示/隐藏',
//
open: false,
}
}
}
},
methods: {
//
toggleSearch() {
this.$emit("update:showSearch", !this.showSearch);
},
//
refresh() {
this.$emit("queryTable");
props: {
/* 是否显示检索条件 */
showSearch: {
type: Boolean,
default: true,
},
/* 显隐列信息 */
columns: {
type: Array,
},
/* 是否显示检索图标 */
search: {
type: Boolean,
default: true,
},
/* 显隐列类型transfer穿梭框、checkbox复选框 */
showColumnsType: {
type: String,
default: 'checkbox',
},
/* 右外边距 */
gutter: {
type: Number,
default: 10,
},
},
//
dataChange(data) {
for (let item in this.columns) {
const key = this.columns[item].key;
this.columns[item].visible = !data.includes(key);
}
computed: {
style() {
const ret = {}
if (this.gutter) {
ret.marginRight = `${this.gutter / 2}px`
}
return ret
},
},
// dialog
showColumn() {
this.open = true;
created() {
if (this.showColumnsType == 'transfer') {
//
for (let item in this.columns) {
if (this.columns[item].visible === false) {
this.value.push(parseInt(item))
}
}
}
},
//
checkboxChange(event, label) {
this.columns.filter(item => item.label == label)[0].visible = event;
}
},
};
methods: {
//
toggleSearch() {
this.$emit('update:showSearch', !this.showSearch)
},
//
refresh() {
this.$emit('queryTable')
},
//
dataChange(data) {
for (let item in this.columns) {
const key = this.columns[item].key
this.columns[item].visible = !data.includes(key)
}
},
// dialog
showColumn() {
this.open = true
},
//
checkboxChange(event, label) {
this.columns.filter((item) => item.label == label)[0].visible =
event
},
},
}
</script>
<style lang="scss" scoped>
::v-deep .el-transfer__button {
border-radius: 50%;
padding: 12px;
display: block;
margin-left: 0px;
border-radius: 50%;
padding: 12px;
display: block;
margin-left: 0px;
}
::v-deep .el-transfer__button:first-child {
margin-bottom: 10px;
margin-bottom: 10px;
}
</style>

View File

@ -0,0 +1,210 @@
<template>
<!-- 表格公共组件 -->
<div>
<!-- 表单搜索 -->
<el-form
:model="queryParams"
ref="queryFormRef"
size="small"
:inline="true"
label-width="100px"
v-show="showSearch"
>
<el-form-item
v-for="(item, v) in formLabel"
:key="v"
:label="item.f_label"
:prop="item.f_model"
>
<el-input
v-if="item.f_type === 'ipt'"
v-model="queryParams[item.f_model]"
:placeholder="`请输入${item.f_label}`"
clearable
style="width: 240px"
/>
<el-select
v-if="item.f_type === 'sel'"
v-model="queryParams[item.f_model]"
clearable
filterable
style="width: 240px"
:placeholder="`请选择${item.f_label}`"
>
<el-option
v-for="(sel, v) in item.f_selList"
:key="v"
:label="sel.label"
:value="sel.value"
/>
</el-select>
<el-cascader
v-if="item.f_type === 'selCas'"
v-model="queryParams[item.f_model]"
:options="item.f_selList"
:props="item.optionProps"
:show-all-levels="false"
clearable
style="width: 240px"
/>
<el-date-picker
v-if="item.f_type === 'date'"
v-model="queryParams[item.f_model]"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>查询</el-button
>
<el-button
type="warning"
icon="el-icon-refresh"
size="mini"
@click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<!-- 按钮集群 -->
<el-row>
<slot name="btn" :pageParams="pageParams"></slot>
<RightToolbar
:showSearch.sync="showSearch"
@queryTable="getTableList"
:columns="tableColumCheckProps"
/>
</el-row>
<!-- 表格 -->
<el-table-column
v-for="(item, v) in tableColumCheckProps"
:key="v"
:label="item.t_label"
:prop="item.t_props"
:width="item.t_width"
align="center"
show-overflow-tooltip
>
<template slot-scope="scope">
<!-- 判断当前列数据是否需要使用插槽的数据 -->
<template v-if="item.t_slot">
<slot :data="scope.row" :name="item.t_slot"></slot>
</template>
<template v-else>
{{ scope.row[item.t_props] || '-' }}
</template>
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
v-if="config.handleColShow"
:width="config.handleWidth"
>
<template slot-scope="{ row }">
<slot :data="row" name="handle"></slot>
</template>
<!-- 增加筛选列显示隐藏操作 -->
<template slot="header">
<el-popover
placement="bottom"
title="筛选列"
width="200"
trigger="click"
>
<span slot="reference" class="handel-text">操作</span>
<div>
<el-checkbox
v-for="(check, index) in columCheckList"
v-show="check.t_label != '序号'"
:key="index"
v-model="check.checked"
>{{ check.t_label }}</el-checkbox
>
</div>
</el-popover>
</template>
</el-table-column>
</div>
</template>
<script>
export default {
props: {
/** 表单查询条件 */
formLabel: {
type: Array,
default: () => [],
},
/** 列表请求接口 */
requestApi: {
type: Function,
default: () => function () {},
},
/* 列表配置项 */
columnsList: {
type: Object,
default: () => [],
},
},
computed: {
/* 根据操作栏控制表头是否显示 */
tableColumCheckProps() {
return this.columCheckList.filter((e) => {
return e.checked != false
})
},
},
data() {
return {
//
queryParams: {},
//
showSearch: true,
}
},
created() {
this.columCheckList = this.columnsList
this.columCheckList = this.columCheckList.map((e) => {
this.$set(e, 'checked', true)
return e
})
/* 生成查询参数 */
this.formLabel.map((e) => {
this.$set(this.queryParams, e.f_model, '')
})
this.getTableList()
},
methods: {
/** 获取列表数据 */
async getTableList() {
const res = await this.requestApi({ ...this.queryParams })
console.log(res, '列表数据')
},
/** 查询按钮 */
handleQuery() {
this.getTableList()
},
/** 重置按钮 */
resetQuery() {
this.$refs.queryFormRef.resetFields()
this.getTableList()
},
},
}
</script>
<style></style>

View File

@ -38,6 +38,9 @@ import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
// 表格组件
import TableModel from '@/components/TableModel'
// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
@ -57,6 +60,7 @@ Vue.component('Editor', Editor)
Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload)
Vue.component('ImagePreview', ImagePreview)
Vue.component('TableModel', TableModel)
Vue.use(directive)
Vue.use(plugins)

View File

@ -0,0 +1,13 @@
export const formLabel = [
{ f_label: '分公司名称', f_model: 'keywords', f_type: 'ipt' },
]
export const columnsList = [
// { t_width: '55px', t_props: '', t_label: '序号' },
{ t_width: '', t_props: 'scrapNum', t_label: '单位名称', },
{ t_width: '', t_props: '', t_label: '单位类型' },
{ t_width: '', t_props: 'repairNum', t_label: '所属分公司' },
{ t_width: '', t_props: 'unitName', t_label: '联系人', },
{ t_width: '', t_props: 'projectName', t_label: '联系电话', },
{ t_width: '', t_props: 'itemType', t_label: '状态', },
]

View File

@ -1,10 +1,18 @@
<template>
<!-- 工程管理 -->
<div> 工程管理 </div>
<div>
<TableModel :formLabel="formLabel" :columnsList="columnsList" />
</div>
</template>
<script>
export default {}
import { formLabel, columnsList } from './config'
export default {
data() {
return {
formLabel,
columnsList,
}
},
}
</script>
<style></style>

View File

@ -35,7 +35,7 @@ module.exports = {
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:18080`,
target: `http://192.168.2.130:18080`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''