一、标题 + 查询条件+按钮(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- input
v- if = "inputType === 'input'"
: placeholder= "inputPlaceholder"
v- model= "searchValue"
size= "small"
class = "search"
clearable
>
< / el- input>
< el- select
v- else - if = "inputType === 'select'"
: placeholder= "selectPlaceholder"
v- model= "searchValue"
size= "small"
class = "search"
clearable
>
< ! -- 添加select选项 -- >
< el- option
v- 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)
< ! --
* 名称:弹窗的搜索条件组件
* 功能:methods
1. 点击搜索的方法:@search
2. 搜索条件 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- item
v- 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- input
v- 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- input
style= "width:47%;"
v- model. trim= "formInline[item.param].start"
: size= "getSize(item.param, item.type) || 'small'"
placeholder= "起始值"
> < / el- input>
< span> - < / span>
< ! -- 区间输入框 - 结束值 -- >
< el- input
style= "width:48%;"
v- model. trim= "formInline[item.param].end"
: size= "getSize(item.param, item.type) || 'small'"
placeholder= "结束值"
> < / el- input>
< / div>
< ! -- 时间区间选择器 -- >
< el- date- picker
style= "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- picker
v- 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- input
v- 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- input
v- 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- select
v- if = "item.type == 'select'"
v- model= "formInline[item.param]"
placeholder= "请选择内容"
: size= "getSize(item.param, item.type) || 'small'"
>
< el- option
v- for = "(item2, index2) in item.selectOptions"
: key= "index2"
: label= "item2.key"
: value= "item2.value"
> < / el- option>
< / el- select>
< ! -- 省 的 select -- >
< el- select
v- if = "item.type == 'proSelect'"
v- model= "formInline[item.param]"
placeholder= "请选择内容"
@change= "provChange"
: size= "getSize(item.param, item.type) || 'small'"
>
< el- option
v- for = "(item2, index2) in item.selectOptions"
: key= "index2"
: label= "item2.key"
: value= "item2.id"
> < / el- option>
< / el- select>
< ! -- 市 的 select -- >
< el- select
v- if = "item.type == 'citySelect'"
v- model= "formInline[item.param]"
placeholder= "请选择内容"
@change= "cityChange"
: size= "getSize(item.param, item.type) || 'small'"
>
< el- option
v- for = "(item2, index2) in cityList"
: key= "index2"
: label= "item2.key"
: value= "item2.id"
> < / el- option>
< / el- select>
< ! -- 区县 的 select -- >
< el- select
v- if = "item.type == 'xzqSelect'"
v- model= "formInline[item.param]"
placeholder= "请选择内容"
@change= "xzqChange"
: size= "getSize(item.param, item.type) || 'small'"
>
< el- option
v- 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- button
type= "success"
plain
size= "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 = formInline
this . 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
) . maxlength
return 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
) . size
return 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- table
ref= "multipleTable"
: data= "displayedData"
: max- height= "tableHeight"
border
row- key= "id"
style= "width: 100%"
tooltip- effect= "dark"
@selection- change= "handleSelectionChange"
>
< el- table- column
type= "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- pagination
align= "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" >
< Header
ref= "Header"
: title= "title"
: input- type= "inputType"
: input- placeholder= "inputPlaceholder"
: select- placeholder= "selectPlaceholder"
: options= "options"
>
< template v- slot: button- list>
< ! -- 按钮列表 -- >
< el- button
type= "primary"
size= "small"
icon= "el-icon-search"
@click= "search"
>
查询
< / el- button>
< el- button
type= "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 -- >
< Tables
v- model: tableData= "tableData"
v- model: currentPage= "currentPage"
v- model: pageSize= "pageSize"
: total= "total"
: columns= "columns"
: tableHeight= "tableHeight"
@getDataList= "getWeekList"
>
< ! -- 使用插槽来配置自定义的操作按钮 -- >
< template #action- buttons= "scope" >
< el- button
link
type= "primary"
size= "mini"
@click. prevent= "viewRow(scope)"
>
查看
< / el- button>
< el- button
link
type= "primary"
size= "mini"
@click. prevent= "editRow(scope)"
>
编辑
< / el- button>
< el- button
link
type= "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' ) . offsetHeight
const footer = document. querySelector ( '.footer' ) . offsetHeight
this . 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>