一、标题 + 查询条件+按钮(Header)
<!-- Header 标题搜索栏 -->
<template><div><div class="header"><div class="h-left"><div class="title"><div class="desc-test"><i class="el-icon-s-grid"></i><span>{{ title }}</span></div></div></div><div class="h-right"><el-inputv-if="inputType === 'input'":placeholder="inputPlaceholder"v-model="searchValue"size="small"class="search"clearable></el-input><el-selectv-else-if="inputType === 'select'":placeholder="selectPlaceholder"v-model="searchValue"size="small"class="search"clearable><!-- 添加select选项 --><el-optionv-for="(option, index) in options":key="index":label="option.label":value="option.value"></el-option></el-select><!-- 按钮组 --><slot name="button-list"> </slot></div></div></div>
</template><script>
export default {props: {title: {type: String,default: '测试管理',},inputType: {type: String,default: 'select', },inputPlaceholder: {type: String,default: '请输入内容', },selectPlaceholder: {type: String,default: '请选择内容', },options: {type: Array,default: () => [],},},data() {return {searchValue: '',}},methods: {},
}
</script>
<style lang="less" scoped>
.header {display: flex;height: 35px;line-height: 35px;justify-content: space-between;width: 100%;.h-left {width: 25%;.title {line-height: 26px;.desc-test {margin-top: 5px;font-weight: bold;margin-bottom: 3px;font-size: 14px;color: #313131;white-space: nowrap;width: fit-content;border-bottom: 2px solid #646565;i {font-size: 16px;position: relative;top: 1px;margin-right: 2px;}}}}.h-right {display: flex;flex-direction: row;justify-content: flex-end;/deep/ .el-input__inner {height: 35px;line-height: 35px;}.search {margin-right: 20px;}}
}
</style>
二、高级查询 (SearchCondition)
<!--*名称:弹窗的搜索条件组件*功能:methods1.点击搜索的方法:@search2.搜索条件 props : formItemList
--><template><div class="searchBox" v-show="isShowSearch"><div class="dialog-search"><!-- inline 行内表单域 --><el-form:inline="true"ref="ruleForm":model="formInline"class="demo-form-inline"><el-form-itemv-for="(item, index) in formItemList":key="index":label="item.label.length > 7 ? item.label.slice(0, 7) + '...' : item.label"label-width="115px"><div class="icon-input"><!-- effect= light / dark --><div class="slotIcon" slot="label"><el-tooltip effect="dark" :content="item.label" placement="top"><i class="el-icon-question" /></el-tooltip></div><div class="inputBox"><!-- 普通 input 框 --><el-inputv-if="item.type == 'input'"v-model.trim="formInline[item.param]":size="getSize(item.param, item.type) || 'small'"placeholder="请输入"></el-input><div style="width: 256px;" v-if="item.type === 'interval'"><!-- 区间输入框 - 起始值 --><el-inputstyle="width:47%;"v-model.trim="formInline[item.param].start":size="getSize(item.param, item.type) || 'small'"placeholder="起始值"></el-input><span> - </span><!-- 区间输入框 - 结束值 --><el-inputstyle="width:48%;"v-model.trim="formInline[item.param].end":size="getSize(item.param, item.type) || 'small'"placeholder="结束值"></el-input></div><!-- 时间区间选择器 --><el-date-pickerstyle="width: 257px;"v-if="item.type == 'daterange'"v-model="formInline[item.param]"type="daterange"range-separator="-"start-placeholder="开始日期"end-placeholder="结束日期"format="YYYY-MM-DD"value-format="YYYY-MM-DD":size="getSize(item.param, item.type) || 'small'"></el-date-picker><!-- 单个日期 --><el-date-pickerv-if="item.type == 'date'"v-model="formInline[item.param]"type="date"placeholder="选择日期"format="YYYY-MM-DD"value-format="YYYY-MM-DD":size="getSize(item.param, item.type) || 'small'"></el-date-picker><!-- 数字输入框 --><el-inputv-if="item.type == 'inputNumber'"v-model="formInline[item.param]"type="number"placeholder="请输入数字":min="getLimit(item.param, item.type, 'min') || ''":max="getLimit(item.param, item.type, 'max') || ''":maxlength="getMaxLength(item.param, item.type) || ''":size="getSize(item.param, item.type) || 'small'"@change="handleChange(item)"@blur="handleBlur(item)"></el-input><!-- 文本输入框 --><el-inputv-if="item.type == 'inputText'"v-model="formInline[item.param]"type="text"placeholder="请输入文本":maxlength="getMaxLength(item.param, item.type) || ''":size="getSize(item.param, item.type) || 'small'"show-word-limit></el-input><!-- select 框 单选--><el-selectv-if="item.type == 'select'"v-model="formInline[item.param]"placeholder="请选择内容":size="getSize(item.param, item.type) || 'small'"><el-optionv-for="(item2, index2) in item.selectOptions":key="index2":label="item2.key":value="item2.value"></el-option></el-select><!-- 省 的 select --><el-selectv-if="item.type == 'proSelect'"v-model="formInline[item.param]"placeholder="请选择内容"@change="provChange":size="getSize(item.param, item.type) || 'small'"><el-optionv-for="(item2, index2) in item.selectOptions":key="index2":label="item2.key":value="item2.id"></el-option></el-select><!-- 市 的 select --><el-selectv-if="item.type == 'citySelect'"v-model="formInline[item.param]"placeholder="请选择内容"@change="cityChange":size="getSize(item.param, item.type) || 'small'"><el-optionv-for="(item2, index2) in cityList":key="index2":label="item2.key":value="item2.id"></el-option></el-select><!-- 区县 的 select --><el-selectv-if="item.type == 'xzqSelect'"v-model="formInline[item.param]"placeholder="请选择内容"@change="xzqChange":size="getSize(item.param, item.type) || 'small'"><el-optionv-for="(item2, index2) in quList":key="index2":label="item2.value":value="item2.id"></el-option></el-select></div></div></el-form-item><!-- 可用于显示其他按钮 --><slot></slot></el-form><div class="btn"><el-form-item><el-button type="primary" plain size="mini" @click="onSubmit">查询</el-button><el-buttontype="success"plainsize="mini"@click="resetForm('ruleForm')">重置</el-button><el-button type="warning" plain size="mini" @click="onClose">关闭</el-button></el-form-item></div></div></div>
</template><script>
import { regionData, CodeToText } from 'element-china-area-data'
export default {name: 'BaseSearch',props: {formItemList: {type: Array,default() {return [{label: '下拉框',type: 'select',selectOptions: [{ name: 111, value: 111 }],param: 'company',defaultSelect: '222', },{label: '输入框',type: 'input',param: 'name',},]},},isShowSearch: {type: Boolean,default: false,},},data() {let formInline = {}for (const obj of this.formItemList) {if (obj.type === 'interval') {formInline[obj.param] = obj.defaultSelect || { start: '', end: '' }} else {formInline[obj.param] = obj.defaultSelect || ''}}return {formInline,options: regionData, selectedOptions: [],cityList: [],quList: [],intervalParam: { start: '', end: '' }, }},watch: {formItemList: {handler(newVal, oldVal) {for (const obj of this.formItemList) {if (obj.defaultSelect) {formInline[obj.param] = obj.defaultSelect}}},deep: true,},},mounted() {},methods: {onSubmit() {for (const item of this.formItemList) {if (item.type === 'interval') {this.formInline[item.param] = {start: this.formInline[item.param].start,end: this.formInline[item.param].end,}}}this.$emit('search', this.formInline)this.$emit('isShowHSearchFn')},resetForm(formName) {this.$refs[formName].resetFields()let formInline = {}for (const obj of this.formItemList) {if (obj.type === 'interval') {formInline[obj.param] = { start: '', end: '' }} else {formInline[obj.param] = '' }}this.formInline = formInlinethis.cityList = [] this.quList = [] },onClose() {this.resetForm('ruleForm')this.$emit('isShowHSearchFn')},getMaxLength(param, type) {let maxlength = this.formItemList.find((item) => item.param === param && item.type === type).maxlengthreturn maxlength},getLimit(param, type, limitType) {let limit = ''if (limitType === 'min') {limit = this.formItemList.find((item) => item.param === param && item.type === type).min} else if (limitType === 'max') {limit = this.formItemList.find((item) => item.param === param && item.type === type).max}return limit},getSize(param, type) {let size = this.formItemList.find((item) => item.param === param && item.type === type).sizereturn size},handleChange(item) {let value = this.formInline[item.param]if (item.min && value < Number(item.min)) {this.formInline[item.param] = item.min} else if (item.max && value > Number(item.max)) {this.formInline[item.param] = item.max} else {this.formInline[item.param] = value}},handleBlur(item) {let value = this.formInline[item.param]if (item.min && value < Number(item.min)) {this.formInline[item.param] = item.min} else if (item.max && value > Number(item.max)) {this.formInline[item.param] = item.max} else {this.formInline[item.param] = value}},provChange(val) {this.cityList = []this.quList = []this.formInline.City = ''this.formInline.AreaCounty = ''this.cityList = this.formItemList[3].selectOptions.filter((item) => {if (val === item.parentId) {return item}})},cityChange(val) {this.quList = []this.formInline.AreaCounty = ''this.quList = this.formItemList[4].selectOptions.filter((item) => {if (val === item.parentId) {return item}})},xzqChange(val) {},},
}
</script><style lang="less" scoped>
.searchBox {width: 100%;box-sizing: border-box;background: #fefefe;border: 1px solid #ececec;position: absolute;z-index: 999;padding: 25px 20px;box-shadow: 0 7px 18px -12px #bdc0bb;
}
.dialog-search {margin: 0 1rem;text-align: left;.icon-input {display: flex;}/deep/ .el-form-item__label {padding: 0;}/deep/ .el-form-item__content {.slotIcon {margin-right: 0.3125rem ;}.el-input {width: 16rem;}.el-select {.el-input__inner {}}}.btn {display: flex;justify-content: flex-end;width: 100%;height: 1.875rem ;}
}
</style>
三、表格组件 (Tables2)
<!-- Tables2 表格组件 -->
<template><div><!-- tableData.slice((currentPage - 1) * pageSize,currentPage * pageSize) --><div class="tables"><el-tableref="multipleTable":data="displayedData":max-height="tableHeight"borderrow-key="id"style="width: 100%"tooltip-effect="dark"@selection-change="handleSelectionChange"><el-table-columntype="selection"width="55"align="center":reserve-selection="true"></el-table-column><el-table-column:align="item.align"v-for="(item, index) in columns":key="item.prop":prop="item.prop":label="item.label":fixed="item.fixed":width="item.width":formatter="item.formatter":sortable="item.prop !== 'index' ? false : true":filters="item.prop !== 'index' ? dateFilters(item.prop) : ''":filter-method="item.prop !== 'index' ? filterHandler : ''"></el-table-column><el-table-column fixed="right" label="操作" width="210" align="center"><template #default="{ scope }"><!-- 使用插槽来展示自定义的操作按钮 --><slot name="action-buttons" :scope="scope" /></template></el-table-column></el-table></div><!-- 分页器 --><div class="footer"><span class="demonstration">当前选中<el-tag>{{ multipleSelection.length }}</el-tag> 条</span><!-- computed --><el-paginationalign="center"@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="[5, 10, 20, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></div></div>
</template><script>
export default {props: {tableData: {type: Array,default: () => [],required: true,},columns: {type: Array,default: () => [],},currentPage: {type: Number,default: 1,}, total: {type: Number,default: 20,}, pageSize: {type: Number,default: 10,}, tableHeight: {type: Number,default: 600,},},data() {return {multipleSelection: [], }},components: {},computed: {displayedData() {return this.tableData},displayedColumns() {return this.columns},displayedCurrentPage: {get() {return this.currentPage},set(newValue) {this.$emit('update:currentPage', newValue)},},displayedPageSize: {get() {return this.pageSize},set(newValue) {this.$emit('update:pageSize', newValue)},},dateFilters() {return (columnName) => {const values = new Set(this.tableData.map((item) => item[columnName]))return Array.from(values).map((value) => ({text: value,value: value,}))}},},mounted() {},watch: {},methods: {handleSelectionChange(val) {console.log('@选中的值', val)this.multipleSelection = val},handleSizeChange(val) {console.log(`每页 ${val} 条`)this.$emit('update:currentPage', 1) this.$emit('update:pageSize', val) this.$emit('getDataList')},handleCurrentChange(val) {console.log(`当前页: ${val}`)this.$emit('update:currentPage', val) this.$emit('getDataList')},filterHandler(value, row, column) {const property = column['property']return row[property] === value},},
}
</script>
<style lang="less" scoped>
.footer {position: absolute;right: 0;padding-top: 15px;font-size: 14px;width: 100%;line-height: 2.25rem ;display: flex;justify-content: flex-end;.demonstration {margin-right: 0.625rem ;}/deep/ .el-pagination {padding-top: 5px;line-height: 30px;}
}
</style>
四、配置项
const columns = [{prop: 'index',label: '序号',width: '80',fixed: 'left',align: 'center',},{prop: 'name',label: '姓名',align: 'center',},{prop: 'issue',label: '期次',align: 'center',formatter: function(row, column, cellValue, index) {if (row.issue === '6') {return <el-tag style="backgroundColor: #bf933f;">{row.issue}</el-tag>} else {return <el-tag type="success">{row.issue}</el-tag>}},},{prop: 'creator',label: '上传人',align: 'center',},{prop: 'createDate',label: '上传时间',align: 'center',},{prop: 'size',label: '文件大小',align: 'center',},
]
export { columns }
const formItemList = [{label: '单位名称:',type: 'input',param: 'unit_name',},{label: '省:',type: 'proSelect',selectOptions: [],param: 'prov',},{label: '市:',type: 'citySelect',selectOptions: [],param: 'city',},{label: '区县:',type: 'xzqSelect',selectOptions: [],param: 'xzqdm',},{label: '联系人:',type: 'input',param: 'linkman',},
]
export { formItemList }
五、父页面
<!-- 测试页面 -->
<template><div><div class="wrap"><Headerref="Header":title="title":input-type="inputType":input-placeholder="inputPlaceholder":select-placeholder="selectPlaceholder":options="options"><template v-slot:button-list><!-- 按钮列表 --><el-buttontype="primary"size="small"icon="el-icon-search"@click="search">查询</el-button><el-buttontype="primary"size="small"icon="el-icon-search"plain@click="showHsearch">高级查询</el-button><el-button type="primary" size="small" icon="el-icon-search" plain>添加</el-button></template></Header><div class="content"><!-- 高级查询 --><SearchCondition:formItemList="formItemList":emitSearch="emitSearch"@search="hSearch"@isShowHSearchFn="isShowHSearchFn":isShowSearch="isShowHSearch"/><!-- 表格 v-model 对应 computed --><Tablesv-model:tableData="tableData"v-model:currentPage="currentPage"v-model:pageSize="pageSize":total="total":columns="columns":tableHeight="tableHeight"@getDataList="getWeekList"><!-- 使用插槽来配置自定义的操作按钮 --><template #action-buttons="scope"><el-buttonlinktype="primary"size="mini"@click.prevent="viewRow(scope)">查看</el-button><el-buttonlinktype="primary"size="mini"@click.prevent="editRow(scope)">编辑</el-button><el-buttonlinktype="primary"size="mini"@click.prevent="deleteRow(scope)">删除</el-button></template></Tables></div></div></div>
</template><script>
import SearchCondition from '@/Tcomponents/SearchCondition.vue'
import Header from '@/Tcomponents/Header.vue'
import Tables from '@/Tcomponents/Tables2.vue'
import { WeeklyReportReq } from '@/api/methods'
import { columns } from './options/column'
import { formItemList } from './options/formItemList'
export default {data() {return {title: '测试页面',inputType: 'input',inputPlaceholder: '请输入内容',selectPlaceholder: '请选择内容',options: [{ label: '选项11', value: 'value11' },{ label: '选项22', value: 'value22' },{ label: '选项33', value: 'value33' },],isShowHSearch: false,emitSearch: false,formItemList: formItemList,tableData: [{createDate: '2023-08-08 15:22:25',createID: 1,creator: '超级管理员',id: '868191e5-df45-446a-b759-2e38e1cac95c',issue: '2',name: '20230726153935新建 DOCX 文档',size: '9KB',},{createDate: '2023-08-08 15:22:25',createID: 1,creator: '超级管理员',id: '868191e5-df45-446a-b759-2e38e1cac95c',issue: '2',name: '20230726153935新建 DOCX 文档',size: '9KB',},{createDate: '2023-08-08 15:22:25',createID: 1,creator: '超级管理员',id: '868191e5-df45-446a-b759-2e38e1cac95c',issue: '2',name: '20230726153935新建 DOCX 文档',size: '9KB',},{createDate: '2023-08-08 15:22:25',createID: 1,creator: '超级管理员',id: '868191e5-df45-446a-b759-2e38e1cac95c',issue: '2',name: '20230726153935新建 DOCX 文档',size: '9KB',},],columns: columns,currentPage: 1, total: 20, pageSize: 10, tableHeight: null,}},components: { SearchCondition, Header, Tables },computed: {},mounted() {this.getDomHeight()this.getWeekList()},methods: {search() {console.log('@点击查询=获取参数', this.$refs.Header.searchValue)this.getWeekList()},showHsearch() {this.$refs.Header.searchValue = ''this.isShowHSearch = !this.isShowHSearch},hSearch(params) {console.log('高级查询的参数', params)},isShowHSearchFn() {this.isShowHSearch = !this.isShowHSearch},getDomHeight() {setTimeout(() => {const content = document.querySelector('.content').offsetHeightconst footer = document.querySelector('.footer').offsetHeightthis.tableHeight = content - footer}, 200)},viewRow(row) {console.log('@viewRow', row)},editRow(row) {console.log('@editRow', row)},deleteRow(row) {console.log('@deleteRow', row)},async getWeekList() {let params = {pageindex: this.currentPage,pagesize: this.pageSize,name: this.$refs.Header.searchValue,}let res = await WeeklyReportReq(params)res.data.data.forEach((item, index) => {item.index = ++index})this.total = res.data.total},},
}
</script>
<style lang="less" scoped>.wrap {height: calc(100vh - 95px);width: 100%;padding: 15px;.content {margin-top: 15px;height: calc(100% - 50px);position: relative;.footer {position: absolute;right: 0;padding-top: 15px;font-size: 14px;width: 100%;line-height: 2.25rem;display: flex;justify-content: flex-end;.demonstration {margin-right: 0.625rem;}/deep/ .el-pagination {padding-top: 5px;line-height: 30px;}}}}
</style>