本来要撤退了,实在饿得不行了,不过jenkins编译前端代码又卡主了,那就再来说说搜索组件的设计吧
1.烦人的搜索条件
既然搜索条件繁琐而烦人,真的应该整成一个组件,还是按照我们之前的思路,使用数据配置驱动它。
提取模板文件如下,支持的组件并不是很多,重在思路,已经包含了日期范围、下拉框、输入框,不够可以自己添加。
<template>
<div>
<el-collapse v-model="showSearch" accordion>
<el-collapse-item name="1">
<template slot="title">
<i class="header-icon el-icon-search"> 搜索条件,点击显示/隐藏</i>
</template>
<div class="search">
<template v-for="(item,index) in model">
<el-input v-if="item.control=='text'" class="input" v-model="item.value" size="mini" clearable :key="index" >
<template slot="prepend">{{item.label}}:</template>
</el-input>
<div v-else-if="item.control=='dropdown'" :key="index" class="dropdown">
<span class="span">{{item.label}}:</span>
<el-select v-model="item.value" size="mini" clearable >
<el-option
v-for="dItem in getdict(item.dictType -1,item.custom)"
:key="dItem.value"
:label="dItem.name"
:value="dItem.value">
</el-option>
</el-select>
</div>
<div v-else-if="item.control=='age'" class="age" :key="index" >
<span class="span">{{item.label}}:</span>
<div class="ageSlider">
<el-slider v-model="item.value" range :max="150">
</el-slider>
</div>
</div>
<div v-else-if="item.control=='dateRange'" class="dateRange" :key="index" >
<span class="span">{{item.label}}:</span>
<el-date-picker
clearable
v-model="item.value"
type="daterange"
align="center"
size="small"
unlink-panels
range-separator="—-"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
:picker-options="pickerOptions">
</el-date-picker>
</div>
</template>
<slot>buttons area</slot>
</div>
</el-collapse-item>
</el-collapse>
</div>
</template>
2、组件脚本
组件脚本相当简单,我们只需要提供参数的获取方法,以及其他的初始化工作即可。
<script>
export default {
name:'WSearch',
props: {
model:{
type:Array,
default:()=>{
return [
]
}
},
dict:{type:Array,default:()=>[] },
show:{type:String,default:''}
},
created(){
},
data() {
return {
marks:{
50:'50岁',
100:'100岁'
},
pickerOptions: {
shortcuts: [
{
text: '今天',
onClick(picker) {
const end = new Date();
const start = new Date();
picker.$emit('pick', [start, end]);
}
},{
text: '昨天',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', [start, end]);
}
},
{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
},
listQuery: {
page: 1,
limit: 10,
account: undefined,
name: undefined
},
customDict: [],
showSearch : this.show
}
},
methods: {
handleInput(e,index) {
//this.$emit("input", this.model);
},
getCustomDict(url) {
return this.$http.fetch({
url: url,
method: "get"
});
},
getdict(index,url){
if(url){
return this.customDict[url] || []
}
else if(this.dict && this.dict.length > index){
var d = [{
name:'全选',
value: ''
},...this.dict[index]]
return d
}
else{
//console.log('dict',this.dict)
return []
}
} ,
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.search {
display: flex;
display: -webkit-flex; /* Safari */
flex-direction: row;
flex-wrap: wrap ;
justify-content:left;
align-items: center;
.span{
border-left: 1px solid #DCDFE6;
border-top: 1px solid #DCDFE6;
border-bottom: 1px solid #DCDFE6;
border-right: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
//width:60px;
background-color: #F5F7FA;
color: #909399;
vertical-align: middle;
display: table-cell;
position: relative;
margin-right:0px;
padding: 0 20px;
white-space: nowrap;
height: 28px;
}
.input{
width:240px;
margin: 5px;
}
.dropdown{
width:240px;
margin: 5px;
display: flex;
display: -webkit-flex; /* Safari */
flex-direction: row;
flex-wrap: nowrap ;
justify-content:center;
align-items: center;
::v-deep input{
border-top-left-radius: 0;
border-bottom-left-radius: 0;
width:100%;
min-width: 150px;
}
}
.age{
width:240px;
margin: 5px;
display: flex;
display: -webkit-flex; /* Safari */
flex-direction: row;
flex-wrap: nowrap ;
justify-content:center;
align-items: center;
.ageSlider{
width:100%;
min-width:150px;
border: 1px solid #DCDFE6;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
height:28px;
align-self:flex-start;
padding:0 10px 0 10px;
}
::v-deep .el-slider__bar{
background-color:#aaa
}
}
.dateRange{
min-width:250px;
margin: 5px;
display: flex;
display: -webkit-flex; /* Safari */
flex-direction: row;
flex-wrap: nowrap ;
justify-content:left;
align-items: center;
flex-grow:1;
::v-deep .el-input__inner{
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.span{
height:32px;
}
::v-deep input{
width:100%;
min-width: 80px;
}
}
}
</style>
3.使用组件
记得引用文件和定义组件.然后直接使用标签
<w-search ref="search" :model="searchList" v-bind:dict=dict>
<el-button type="success" size="mini" icon="el-icon-search" @click.native="search">{{ $t('button.search') }}</el-button>
<el-button type="primary" size="mini" icon="el-icon-refresh" @click.native="reset">{{ $t('button.reset') }}</el-button>
</w-search>
这里model定义了搜索组件的元数据,dict给定了搜索框的词典。
元数据信息形如:
searchList:[
{
label:this.$t(myConfig.model+'.cpShowType'),
control:'dropdown', //br换行
name:'CpShowType',
dictType:'1',
value: null,
default: null,
},
{
label:this.$t(myConfig.model+'.cpCode'),
control:'text', //br换行
name:'CpCode',
dictType:'',
value: null,
default: '',
},
],
4.界面如下:
Jenkins终于编译好了,界面可以看到了。
当然,根据元数据的不同可以随便扩展搜索条件了,开开心心码完代码,下班。
5. 小结
我是vue新手,多多关照,大家可以提提问题哦,