1. 动态查询规则
动态查询规则,大致如下图所示。是可以按照用户的自定义进行组织查询语句的一种复杂组件,大致可以实现SQL查询的where条件,下面是摘自mongodb的某一软件。
2.组件构建思路
按照规则组件的组织形式,可以把其视为一棵树,有树干和树叶,这样看起来就不难了。
2.1 组件属性 data: 是树结构的内容,我们定义为:
{ condition: \'AND\', rules: [], }
fieldList: 字段列表数组,可供选择的字段集合;
operatorList: 操作列表数组,可供选择的操作集合,定义如下:
{ label: \'包含\', value: \'⊂\', },
2.2 组件html
这里采用ElementUI构建,因此可以方便的组合各类ui控件来进行构建需要的界面。
当然该组件既然被看作树,因此其也是个递归组件,因此还涉及到自己调用自己。
<template> <div class=\"rules-group-container\"> <div class=\"rules-group-header\"> <el-radio-group v-model=\"data.condition\" size=\"mini\"> <el-radio-button label=\"AND\"></el-radio-button> <el-radio-button label=\"OR\"></el-radio-button> </el-radio-group> <div> <el-button size=\"mini\" @click=\"addRule(data)\">添加规则</el-button> <el-button size=\"mini\" @click=\"addGroup(data)\">添加分组</el-button> <el-button v-if=\"parent\" size=\"mini\" @click=\"delGroup(data, parent)\">删除</el-button> </div> </div> <div class=\"rules-group-body\"> <div class=\"rules-list\"> <template v-for=\"(rule, index) in data.rules\"> <div :key=\"index\" v-if=\"!rule.condition\" class=\"rule-container\"> <!-- 字段 --> <wt-dropdown class=\"rule-item\" v-model=\"rule.FilterField\" :data=\"getFieldList(rule.FilterTable)\" @change=\"handleFieldChange(rule)\" ></wt-dropdown> <!-- 操作符 --> <wt-dropdown class=\"rule-item\" v-model=\"rule.Operator\" :disabled=\"inputStatus && rule.FilterField === \'CommunityId\'\" :data=\"getRule(rule.FilterTable, rule.FilterField)\" ></wt-dropdown> <!-- 值 --> <wt-multi-dropdown class=\"rule-item-long\" v-if=\"rule.type === \'Dropdown\'\" :disabled=\"inputStatus && rule.FilterField === \'CommunityId\'\" v-model=\"rule.FilterValue\" :data=\"getData(rule.FilterTable, rule.FilterField)\" ></wt-multi-dropdown> <wt-number class=\"rule-item-long\" :disabled=\"inputStatus && rule.FilterField === \'CommunityId\'\" v-else-if=\"[\'DateTime\', \'Number\', \'Decimal\'].includes(rule.type)\" v-model=\"rule.FilterValue\" ></wt-number> <wt-text class=\"rule-item-long\" v-else v-model=\"rule.FilterValue\" :disabled=\"inputStatus && rule.FilterField === \'CommunityId\'\"></wt-text> <el-button size=\"mini\" @click=\"delRule(index)\">删除</el-button> </div> <CreateRule :key=\"index\" v-else :data=\"rule\" :parent=\"data\" :fieldList=\"fieldList\" :operatorList=\"operatorList\" ></CreateRule> </template> </div> </div> </div> </template>
2.3 对不同数据类型的字段定义不同的条件
const rules = { string: [ { value: \'==\', label: \'等于\', }, { value: \'<>\', label: \'不等于\', }, { value: \'⊂\', label: \'包含\', }, { value: \'⊄\', label: \'不包含\', }, { value: \'in\', label: \'其中之一\', }, { value: \'ni\', label: \'非其中之一\', }, { value: \'mc\', label: \'多包含\', }, ], number: [ { value: \'==\', label: \'等于\', }, { value: \'<>\', label: \'不等于\', }, { value: \'≥\', label: \'大于等于\', }, { value: \'≤\', label: \'小于等于\', }, ], dict: [ { value: \'in\', label: \'其中之一\', }, { value: \'ni\', label: \'非其中之一\', }, ], date: [ { value: \'sdiff\', label: \'几天前\', }, { value: \'ediff\', label: \'几天后\', }, ], }
2.4 定义方法操作组\\规则
主要的操作涉及到添加\\删除 组和规则。
getRule(table, field) { let data = (rules && rules.string) || [] let theField = this.getCurrentField(table, field) if (theField && theField.ControlType) { if ([\'Dropdown\'].includes(theField.ControlType)) { return rules.dict } else if ([\'DateTime\'].includes(theField.ControlType)) { return rules.date } else if ([\'Number\', \'Decimal\'].includes(theField.ControlType)) { return rules.number } else { return rules.string } } return data }, // 添加规则 addRule(data) { let rule = { type: \'Text\', FilterTable: this.firstTable, FilterField: this.firstField, Operator: \'==\', FilterValue: \'\', } data.rules.push(rule) }, // 删除规则 delRule(index) { this.data.rules.splice(index, 1) }, // 添加分组 addGroup(data) { let group = { condition: \'OR\', rules: [ { type: \'Text\', FilterTable: this.firstTable, FilterField: \'\', Operator: \'\', FilterValue: \'\', }, ], } data.rules.push(group) }, // 删除分组 delGroup(data, parent) { let index = parent.rules.findIndex((item) => item === data) parent.rules.splice(index, 1) },
2.5 定义组件名
该组件命名为 CreateRule
,定义代码很简单了。
export default { name: \'CreateRule\', props: { parent: { type: Object, }, data: { type: Object, }, fieldList: { type: Array, default() { return [] }, }, operatorList: { type: Array, default() { return [] }, }, }, }
3.使用组件
vue中使用组件只需引用并增加到组件列表中即可。
import CreateRule from \'./CreateRule\' export default { name: \'NewRuleForm\', components: { CreateRule, }, }
模板内增加引用
<template> <div class=\"new-rule-form\"> <CreateRule v-if=\"!loading\" :data=\"data\" :fieldList=\"FilterTable\" :operatorList=\"operatorList\" ></CreateRule> <div v-if=\"!loading\" class=\"discription-wrap\" v-html=\"discription\"></div> </div> </template>
4.效果展示
这是截取的实际效果.
在界面中,作为搜索条件或过滤条件效果均不错,可以做到非常灵活。
5.小结
在vue开发应用中,可以多参考下windows软件的某些界面,偶尔能给我们很大的灵感和启发的。
© 版权声明
THE END
暂无评论内容