封裝搜尋元件,優化代碼量,減少備援
<template>
<div v-if="!$_.isEmpty(searchData)" class="search-box">
<slot name="before" />
<div v-for="(item, idx) in searchDataIsVisible" :key="idx" class="form">
<div v-if="item.type === 'select'" class="select">
<span class="text">{{ item.title }}</span>
<el-select
v-model="query[item.model]"
:style="{ width: item.width }"
filterable
:clearable="!item.clearable"
:loading="item.loading"
:remote="!!item.callback"
:remote-method="item.callback ? q => remoteMethod(q, item) : null"
@change="value => onSelectClear(value, item)"
>
<!-- <el-option
v-for="i in item.enumType
? $enums[item.enumType].allList()
: item.option"
:key="i.value"
:label="i.label"
:value="i.value"
/> -->
<el-option
v-for="i in item.option"
:key="i.value"
:label="i.label"
:value="i.value"
/>
</el-select>
</div>
<div v-if="item.type === 'cascader'" class="cascader">
<span class="text">{{ item.title }}</span>
<el-cascader
v-model="item.model"
:style="{ width: item.width }"
:options="item.option"
:props="item.props"
collapse-tags
clearable
change-on-select
@change="value => cascaderChange(value, item)"
/>
</div>
<div v-if="item.type === 'dateSection'" class="date-section">
<span class="text">{{ item.title }}</span>
<el-date-picker
v-model="date"
class="date input"
:type="item.dateType"
align="right"
unlink-panels
start-placeholder="開始日期"
end-placeholder="結束日期"
:picker-options="pickerOptions"
@change="value => dateChange(value, item)"
/>
</div>
<div v-if="item.type === 'date'" class="date">
<span class="text">{{ item.title }}</span>
<el-date-picker
v-model="item.initialDate"
:type="item.dateType"
:format="
item.dateType === 'month'
? 'yyyy-MM'
: item.dateType === 'year'
? 'yyyy'
: 'yyyy-MM-dd'
"
class="date"
:picker-options="item.noShortcut ? pickerOptions1 : pickerOptions"
placeholder="選擇時間"
@change="value => dateSingeChange(value, item)"
/>
</div>
<div v-if="item.type === 'input'" class="input">
<span class="text">{{ item.title }}</span>
<el-input
v-model="query[item.modelName]"
:placeholder="item.placeholder"
@keyup.enter.native="emitSearchChange"
>
<el-button
slot="append"
icon="el-icon-search"
@click="emitSearchChange"
/>
<!--<i @click="$search(table)" slot="suffix" class="el-input__icon el-icon-search"></i>-->
</el-input>
</div>
</div>
<span class="ctrl-btn">
<slot name="after" />
</span>
</div>
</template>
<script>
export default {
props: {
searchData: {
type: Array,
default() {
return []
}
},
query: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
pickerOptions1: {
disabledDate(date) {
// disabledDate 文檔上:設定禁用狀态,參數為目前日期,要求傳回 Boolean
return date.getTime() >= Date.now()
}
},
pickerOptions: {
disabledDate(date) {
// disabledDate 文檔上:設定禁用狀态,參數為目前日期,要求傳回 Boolean
return date.getTime() >= Date.now()
},
shortcuts: [
{
text: '最近一個月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(
new Date(new Date().setMonth(new Date().getMonth() - 1))
)
picker.$emit('pick', [start, end])
}
},
{
text: '最近三個月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(
new Date(new Date().setMonth(new Date().getMonth() - 3))
)
picker.$emit('pick', [start, end])
}
},
{
text: '最近六個月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setTime(
new Date(new Date().setMonth(new Date().getMonth() - 6))
)
picker.$emit('pick', [start, end])
}
}
]
}
}
},
computed: {
searchDataIsVisible() {
return this.searchData.filter(t => !t.hide)
},
// date() {
// const arr = []
// this.searchData.forEach(e => {
// e.modelName &&
// Array.isArray(e.modelName) &&
// e.modelName.forEach(i => {
// arr.push(this.query[i])
// })
// })
// return arr || []
// },
date: {
get: function() {
const arr = []
this.searchData.forEach(e => {
e.modelName &&
Array.isArray(e.modelName) &&
e.modelName.forEach(i => {
arr.push(this.query[i])
})
})
return arr || []
},
set: function(val) {
this.searchData.forEach(e => {
e.modelName &&
Array.isArray(e.modelName) &&
e.modelName.forEach((i, idx) => {
if (val) {
if (idx === 0) {
this.query[i] = this.$dayjs(val[0]).format(
'YYYY-MM-DD 00:00:00'
)
} else {
this.query[i] = this.$dayjs(val[1]).format(
'YYYY-MM-DD 23:59:59'
)
}
}
})
})
}
}
},
created() {
this.initOptions()
},
methods: {
// select 遠端搜尋回調
async remoteMethod(q, item) {
const setOption = newOpt => this.$set(item, 'option', newOpt)
const setLoading = v => this.$set(item, 'loading', v)
item.callback(q, { setOption, setLoading })
},
initOptions() {
this.searchData.forEach(async item => {
if (item.api) {
// eslint-disable-next-line no-useless-catch
try {
this.$set(item, 'loading', true)
const query = this.$_.cloneDeep(item.query) || {}
const res = await item.api(query)
this.$set(item, 'loading', false)
let data = null
if (res instanceof Array) {
data = res
}
// let data = res.data.data
// if (data instanceof Array) {
if (item.type === 'tree') {
this.$set(item, 'option', data)
} else if (item.type === 'select') {
this.$set(
item,
'option',
data.map(obj => {
return {
value: obj[item.keyValueName ? item.keyValueName[0] : 'id'],
label:
obj[item.keyValueName ? item.keyValueName[1] : 'name']
}
})
)
}
// }
} catch (e) {
throw e
}
}
})
},
emitSearchChange() {
this.$emit('on-search-change', this.query)
},
onSelectClear(val, item) {
if (!val) {
this.query[item.model] = ''
}
if (this.query.clone) {
this.query[this.query.clone1] = this.$_.cloneDeep(this.query.startTime)
this.query[this.query.clone2] = this.$_.cloneDeep(this.query.endTime)
}
this.emitSearchChange()
},
// cascader 值改變的時候
cascaderChange(val, item) {
if (item.props.multiple) {
const arr = []
for (let i = 0; i < val.length; i++) {
arr.push(val[i][val[i].length - 1])
}
this.query[item.modelName] = arr
} else {
this.query[item.modelName] = val
}
this.emitSearchChange()
},
// 日期選擇控件切換的回調
dateChange(val, item) {
//
if (val === null) {
this.query[item.modelName[0]] = this.$dayjs().format(
'YYYY-MM-DD 00:00:00'
)
this.query[item.modelName[1]] = this.$dayjs().format(
'YYYY-MM-DD 23:59:59'
)
} else {
this.query[item.modelName[0]] = this.$dayjs(val[0]).format(
'YYYY-MM-DD 00:00:00'
)
this.query[item.modelName[1]] = this.$dayjs(val[1]).format(
'YYYY-MM-DD 23:59:59'
)
}
if (this.query.userChange) {
this.query.sortApi = 'listStaticSort'
}
if (this.query.clone) {
this.query[this.query.clone1] = this.$_.cloneDeep(
this.query[item.modelName[0]]
)
this.query[this.query.clone2] = this.$_.cloneDeep(
this.query[item.modelName[1]]
)
}
this.emitSearchChange()
},
// 日期單選控件切換的回調
dateSingeChange(val, item) {
// this.query[item.model] = val
if (item.onlyYear) {
if (!val) {
this.query[item.model] = null
this.emitSearchChange()
return
}
this.query[item.model] = this.$dayjs(val).format('YYYY')
this.emitSearchChange()
return
}
if (val === null) {
// let date = new Date()
// this.query[item.model] = this.$dayjs(date).format('YYYY-MM-DD HH:mm:ss')
this.query[item.model] = null
} else {
this.query[item.model] = this.$dayjs(val).format('YYYY-MM-DD HH:mm:ss')
}
this.emitSearchChange()
}
}
}
</script>
<style lang="scss" scoped>
.search-box {
padding: 0 0 20px 0;
min-width: 806px;
.ctrl-btn {
display: inline-block;
margin-top: 38px;
}
.item {
margin-top: 10px;
}
.text {
display: block;
margin-left: 5px;
margin-bottom: 5px;
font-size: 12px;
font-weight: bold;
color: #666;
}
.form {
display: inline-block;
margin-right: 10px;
margin-top: 10px;
margin-bottom: 10px;
vertical-align: top;
// float: left;
}
.date {
width: 260px !important;
}
.el-select {
width: 160px;
display: block;
display: block;
.el-input__inner {
padding-right: 30px !important;
}
}
.el-cascader {
width: 160px;
}
.el-date-editor .el-range-separator {
line-height: 28px !important;
}
.input {
width: 210px;
}
}
</style>