需求:可以动态增减组合条件来进行数据查询。

  界面运行效果如下图所示:

  界面第一次加载时,默认会显示一个空的查询条件,如下图所示:

  

  点击“加”图标,可以无限增加查询条件,也可以点击“减”图标删除新增的查询条件,如下图所示:

  

  说明:第一个下拉框的数据变化时,第三个下拉框的数据要进行联动,第三个组件可以是下拉框也可以是文本框,它是根据第一个下拉框的数据来决定的。第二个下拉框是固定的四个选项>、<、=、!=。如下图所示:

  

  定义数据结构:

{
"data": {
"array": [{
"opts": [{
"val": "0",
"name": "停止"
}, {
"val": "1",
"name": "运行"
}],
"paramCode": "runStatus",
"name": "运行状态"
}, {
"opts": [{
"val": "0",
"name": "否"
}, {
"val": "1",
"name": "是"
}],
"paramCode": "alarmStatus",
"name": "报警与否"
}, {
"opts": [{
"val": "0",
"name": "就地"
}, {
"val": "1",
"name": "远程"
}],
"paramCode": "remoteLocal",
"name": "远程就地"
}, {
"opts": [{
"val": 0,
"name": "禁用"
}, {
"val": 1,
"name": "启用"
}],
"paramCode": "startUse",
"name": "是否启用"
}, {
"opts": [{
"val": "0",
"name": "变频"
}, {
"val": "1",
"name": "工频"
}],
"paramCode": "runMode",
"name": "工频启停"
}, {
"opts": [{
"val": 0,
"name": "手动"
}, {
"val": 1,
"name": "自动"
}],
"paramCode": "controlMode",
"name": "控制模式"
}, {
"opts": [{
"val": "0",
"name": "手动"
}, {
"val": "1",
"name": "自动"
}],
"paramCode": "frequencyMode",
"name": "频率手自动"
}, {
"opts": [],
"paramCode": "frequencySetValue",
"name": "频率设定"
}, {
"opts": [],
"paramCode": "frequencyReturnValue",
"name": "频率反馈"
}, {
"opts": [],
"paramCode": "tempSetValue",
"name": "温度设定"
}, {
"opts": [],
"paramCode": "tempReturnValue",
"name": "温度反馈"
}, {
"opts": [{
"val": 0,
"name": "关"
}, {
"val": 1,
"name": "开"
}],
"paramCode": "newWindValveOnOff",
"name": "新风阀启停"
}, {
"opts": [],
"paramCode": "newWindValveOpen",
"name": "新风阀开度"
}, {
"opts": [],
"paramCode": "newWindTemp",
"name": "新风阀温度"
}, {
"opts": [],
"paramCode": "newWindHumidity",
"name": "新风阀湿度"
}, {
"opts": [{
"val": 0,
"name": "关"
}, {
"val": 1,
"name": "开"
}],
"paramCode": "returnWindValveOnOff",
"name": "回风阀启停"
}, {
"opts": [],
"paramCode": "returnWindValveOpen",
"name": "回风阀开度"
}, {
"opts": [],
"paramCode": "returnWindHumidity",
"name": "回风阀湿度"
}, {
"opts": [],
"paramCode": "co2",
"name": "回风阀co2"
}, {
"opts": [{
"val": "0",
"name": "手动"
}, {
"val": "1",
"name": "自动"
}],
"paramCode": "waterValveHandAuto",
"name": "水阀手自动"
}, {
"opts": [{
"val": 0,
"name": "关"
}, {
"val": 1,
"name": "开"
}],
"paramCode": "waterValveOnOff",
"name": "水阀启停"
}, {
"opts": [],
"paramCode": "waterValveOpenSet",
"name": "水阀开度设定"
}, {
"opts": [],
"paramCode": "waterValveOpenReturn",
"name": "水阀开度反馈"
}, {
"opts": [],
"paramCode": "supplyAirTemp",
"name": "送风温度"
}, {
"opts": [],
"paramCode": "supplyAirHumidity",
"name": "送风湿度"
}, {
"opts": [],
"paramCode": "supplyAirPressure",
"name": "送风静压"
}, {
"opts": [{
"val": 0,
"name": "关"
}, {
"val": 1,
"name": "开"
}],
"paramCode": "humidityValveOnOff",
"name": "加湿阀启停"
}, {
"opts": [],
"paramCode": "humidityValveOpen",
"name": "加湿阀开度"
}, {
"opts": [],
"paramCode": "filterDiffPressure",
"name": "过滤网压差"
}, {
"opts": [{
"val": 0,
"name": "关"
}, {
"val": 1,
"name": "开"
}],
"paramCode": "elecHeatOnOff",
"name": "电加热"
}, {
"opts": [],
"paramCode": "power",
"name": "功率"
}, {
"opts": [],
"paramCode": "runTime",
"name": "运行时间"
}, {
"opts": [],
"paramCode": "loadPower",
"name": "供冷负荷"
}, {
"opts": [],
"paramCode": "cold",
"name": "累计供冷量"
}, {
"opts": [{
"val": 0,
"name": "正常"
}, {
"val": 1,
"name": "中断"
}],
"paramCode": "commuInterrupt",
"name": "通讯是否正常"
}]
},
"code": 200,
"msg": "",
"errors": null
}

  因为数据量不大,为了提升性能,数据是接口一次性返回的,数据的联动是在内存当中进行数据筛选,从而避免频繁的接口调用。

  在数据结构当中,当opts属性值为空数组时,第三个组件显示为文本框,否则显示为下拉框,并把opts中的数据作为第三个组件的下拉框内容展示出来。当第三个组件是下拉框时,第二个下拉框只能显示=和!=这两项,如果是文本框时,都可以显示。

  后端接口需要的查询参数是:

dataListParams: [{paramName: "runStatus", operator: 2, value: "0"}, {paramName: "startUse", operator: 2, value: 0}]

  接下来,我们定义vue组件中的内容,Dom部分:

        <div class='search-item'>
<label>组合条件:</label>
</div>
<div class="search-item"
v-for="(paramObj,index) in dataListParams"
:key="index">
<!-- 参数名 -->
<el-select v-model="paramObj.paramName"
filterable
clearable
@change="(e)=>changeParam(e,index)"
placeholder="请选择"
style="width:100px">
<el-option v-for="item in paramList"
:key="item.paramCode"
:label="item.name"
:value="item.paramCode"></el-option>
</el-select>
<!-- 操作符列表 -->
<el-select v-model="paramObj.operator"
clearable
placeholder=""
style="width:60px">
<el-option v-for="(item,sindex) in operatorOptions"
:disabled="getDisabled(sindex,index)"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
<!-- 参数值 -->
<el-select v-if="listOpts[index].length>0"
v-model="paramObj.value"
filterable
clearable
placeholder="请选择"
style="width:100px">
<el-option v-for="item in listOpts[index]"
:key="item.val"
:label="item.name"
:value="item.val"></el-option>
</el-select>
<el-input v-else
v-model="paramObj.value"
:clearable="true"
placeholder="请输入"
style="width:100px"></el-input> <span v-if="index==0"
class="add-where"><i class="iconfont icon-add"
@click="addWhere"></i></span>
<span v-else
class="remove-where"><i class="iconfont icon-shanchu1"
@click="removeWhere(index)"></i></span>
</div>

  js部分:

export default {
mixins: [indexOptions],
data () {
return {
//操作符列表
operatorOptions: [
{ id: 0, name: '>' },
{ id: 1, name: '<' },
{ id: 2, name: '=' },
{ id: 3, name: '!=' }
],
//组合条件
dataListParams: [{ paramName: "", operator: '', value: "" }],
checkedAll: false, //全选所有
deviceIds: [],
listOpts: [[]]//操作列表
}
},
computed: {//筛选参数列表,如果参数列表dataListParams当中有任何一个属性值为空,则不传递
filterDataListParams () {
return this.dataListParams.filter(f => { return f.paramName !== "" && f.operator !== "" && f.value !== "" });
}
},
methods: {//获取操作选项启用、禁用
getDisabled (sindex, index) {
if (this.listOpts.length > 0 && this.listOpts[index].length > 0) {
return [0, 1].includes(sindex);
} else {
return false;
}
},
//添加组合条件
addWhere () {
this.dataListParams.push({ paramName: '', operator: '', value: '' });
this.listOpts.push([]);
},
//移除组合条件
removeWhere (index) {
this.dataListParams.splice(index, 1);
this.listOpts.splice(index, 1);
},
//根据参数编码获取操作列表
getOptsByParamCode (code,) {
let res = this.paramList.find(f => f.paramCode == code);
return res ? res.opts : [];
},
//参数选项变化
changeParam (code, index) {
//变化之前的类型
let preType = this.listOpts[index].length > 0; //是否下拉框
let arr = this.getOptsByParamCode(code);
this.listOpts[index] = arr;
this.dataListParams[index].value = '';
//变化之后的类型
let nextType = arr.length > 0;//是否是下拉框
//前后类型不一致时,清空操作符
if (preType != nextType) {
this.dataListParams[index].operator = '';
}
}
}
};

  当第一个下拉框选项变化时,如果第三个组件是相同类型(下拉框或文本框),则第二个下拉框的选项不清空,否则清空。

  只有一组查询条件当中三个选项的值都不为空时,才会把参数传递给后端,所以前端通过计算熟悉filterDataListParams进行了数据过滤。

  由于数据结构是动态变化的,所以为了保存查询条件的保存状态,下拉框的数据列表项也应当是动态的(数组存储)。

  最后把filterDataListParams作为参数传递给后端接口就可以了,这是一个很典型的vue动态数据驱动应用。

通过一个很常用的场景来展示vue数据驱动的应用的更多相关文章

  1. 转载:给bash的提示符设置不同的颜色 一个很常用的功能,效果如下:

    原文来自:http://www.cnblogs.com/cyttina/archive/2013/01/08/2850406.html 一个很常用的功能,效果如下: 这样就可以很轻易的将输入的指令和其 ...

  2. Makefile经典教程(一个很棒很清晰的讲解)【转】

    转自:https://blog.csdn.net/seven_amber/article/details/70216216 该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神 ...

  3. [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office

    打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...

  4. Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》

    首先,简单介绍:Redis是一个基于内存的键值对存储系统,常用作数据库.缓存和消息代理. 支持:字符串,字典,列表,集合,有序集合,位图(bitmaps),地理位置,HyperLogLog等多种数据结 ...

  5. HTML之:fieldset——一个不常用的HTML标签

    2016年4月14日17:10:02记录 一个不常用的HTML标签fieldset,不过我觉得比较有意思,其语法如下: <fieldset><legend>fieldset名称 ...

  6. 一个很不错的bash脚本编写教程

    转自 http://blog.chinaunix.net/uid-20328094-id-95121.html 一个很不错的bash脚本编写教程,至少没接触过BASH的也能看懂! 建立一个脚本 Lin ...

  7. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇] 在进行基于会话信道的WCF服务调用中,由于受到并发信道数量的限制,我们需要及时的关闭信道:当遇到某些异常,我们需要强行中止(Abor ...

  8. 有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果(转)

    引用 前几天在网上看到一个淘宝的面试题:有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果.一:分析题目 从题中可以看到“很大的List”以及“ ...

  9. 关于引入多个jquery冲突的问题(附一个很好用的validate前端验证框架及使用方法)

    废话不多说,进入正题: 如果一个jsp中想要使用两个不同版本的jquery怎么办呢?客官往下看: <script src="${ctxStatic}/jquery/jquery-1.8 ...

随机推荐

  1. Java基础——HashMap

    1.HashMap底层的实现 JDK 1.7 中 HashMap 是以数组+链表的形式组成的 JDK 1.8 之后数组+链表/红黑树的组成的,当链表大于 8 并且容量大于 64 时,链表结构会转换成红 ...

  2. eclipse validating 卡着一直不动

    处理方式: 1.对项目的.project文件去掉下面两个配置 org.eclipse.wst.jsdt.core.javascriptValidator 和 org.eclipse.wst.jsdt. ...

  3. Python-装饰器(语法糖)上下五千年和前世今生

    装饰器上下五千年和前世今生,这里我们始终要问,装饰器为何产生?装饰器产生解决了什么问题?什么样的需求推动了装饰器的产生?思考问题的时候,始终要问,为什么要这样,而不是那样或者其他样.这里我不先说,也不 ...

  4. 协同过滤 Collaborative Filtering

    协同过滤 collaborative filtering 人以类聚,物以群分 相似度 1. Jaccard 相似度 定义为两个集合的交并比: Jaccard 距离,定义为 1 - J(A, B),衡量 ...

  5. 再解决不了前端加密我就吃shi

    参考文章 快速定位前端加密方法 渗透测试-前端加密测试 前言 最近学习挖洞以来,碰到数据做了加密基本上也就放弃了.但是发现越来越多的网站都开始做前端加密了,不论是金融行业还是其他.所以趁此机会来捣鼓一 ...

  6. 为啥你用@JsonFormat注解时,LocalDateTime会反序列化失败?

    写在前面 最近,有个小伙伴问我:我在SpringBoot项目中,使用@JsonFormat注解标注LocalDateTime类型的字段时,LocalDateTime反序列化失败,这个我该怎么处理呢?别 ...

  7. Spring系列之事务的控制 注解实现+xml实现+事务的隔离等级

    Spring系列之事务的控制 注解实现+xml实现 在前面我写过一篇关于事务的文章,大家可以先去看看那一篇再看这一篇,学习起来会更加得心应手 链接:https://blog.csdn.net/pjh8 ...

  8. HTML中css水平居中的几种方式

    1. 子元素为行内元素时,父元素使用 text-align: center; 实现子元素的水平居中: 2. 子元素为块级元素时, 2.1. 将子元素设置 margin: 0 auto; 实现居中: 2 ...

  9. 057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和

    057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和 本文知识点:求整型数组的数组元素的元素值累加和 案例:求整型数 ...

  10. VS中OpenCV用imread读取不到图片

    转自:https://blog.csdn.net/u012423865/article/details/78116059 在VS中OpenCV用imread读取不到图片 今天在Visual Studi ...