1. Dynamically query rules
The following figure shows the dynamic query rules. It is a complex component that can organize query statements according to user’s customization, and can roughly realize the WHERE condition of SQL query. The following is a software excerpt from mongodb.
2. Component construction ideas
The way the regular components are organized, you can think of it as a tree, with a trunk and leaves, so it doesn’t look hard.
2.1 Component Properties
- Data: is the content of the tree structure, which we define as:
{
condition: 'AND'.rules: [],}Copy the code
- FieldList: Array of field lists, a collection of fields to choose from;
- OperatorList: Array of operation lists, a collection of optional operations, defined as follows:
{
label: 'contains'.value: '⊂',},Copy the code
2.2 components HTML
This is built with ElementUI, so you can easily combine various UI controls to build the desired interface. Of course, since this component is considered a tree, it is also a recursive component and therefore involves calling itself.
<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)">Add rules</el-button>
<el-button size="mini" @click="addGroup(data)">Add a group</el-button>
<el-button v-if="parent" size="mini" @click="delGroup(data, parent)">delete</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">
<! - field -- - >
<wt-dropdown
class="rule-item"
v-model="rule.FilterField"
:data="getFieldList(rule.FilterTable)"
@change="handleFieldChange(rule)"
></wt-dropdown>
<! -- operator -->
<wt-dropdown
class="rule-item"
v-model="rule.Operator"
:disabled="inputStatus && rule.FilterField === 'CommunityId'"
:data="getRule(rule.FilterTable, rule.FilterField)"
></wt-dropdown>
<! - value - >
<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)">delete</el-button>
</div>
<CreateRule
:key="index"
v-else
:data="rule"
:parent="data"
:fieldList="fieldList"
:operatorList="operatorList"
></CreateRule>
</template>
</div>
</div>
</div>
</template>
Copy the code
2.3 Define different conditions for fields of different data types
const rules = {
string: [{value: '= ='.label: 'equal to'}, {value: '< >'.label: The prime is not equal to the prime.}, {value: '⊂'.label: 'contains'}, {value: '⊄'.label: 'Not included'}, {value: 'in'.label: 'One of'}, {value: 'ni'.label: 'Not one of them'}, {value: 'mc'.label: 'More contains'],},number: [{value: '= ='.label: 'equal to'}, {value: '< >'.label: The prime is not equal to the prime.}, {value: 'or'.label: The prime is greater than or equal to the prime.}, {value: 'or less'.label: 'Less than or equal to'.],},dict: [{value: 'in'.label: 'One of'}, {value: 'ni'.label: 'Not one of them'],},date: [{value: 'sdiff'.label: 'A few days ago'}, {value: 'ediff'.label: 'In a few days',},],}Copy the code
2.4 Define method operation groups \ rules
The main operations involve adding \ deleting groups and rules.
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
},
// Add the rule
addRule(data) {
let rule = {
type: 'Text'.FilterTable: this.firstTable,
FilterField: this.firstField,
Operator: '= ='.FilterValue: ' ',
}
data.rules.push(rule)
},
// Delete the rule
delRule(index) {
this.data.rules.splice(index, 1)},// Add a group
addGroup(data) {
let group = {
condition: 'OR'.rules: [{type: 'Text'.FilterTable: this.firstTable,
FilterField: ' '.Operator: ' '.FilterValue: ' ',
},
],
}
data.rules.push(group)
},
// Delete the group
delGroup(data, parent) {
let index = parent.rules.findIndex((item) = > item === data)
parent.rules.splice(index, 1)},Copy the code
2.5 Defining component Names
This component is named CreateRule, and defining the code is simple.
export default {
name: 'CreateRule'.props: {
parent: {
type: Object,},data: {
type: Object,},fieldList: {
type: Array.default() {
return[]}},operatorList: {
type: Array.default() {
return[]},},},}Copy the code
3. Use components
Components used in VUE are simply referenced and added to the list of components.
import CreateRule from './CreateRule'
export default {
name: 'NewRuleForm'.components: {
CreateRule,
},
}
Copy the code
Adding a reference to a template
<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>
Copy the code
4. Effect display
This is the actual effect of the intercept.It works well as a search condition or filter condition in the interface and can be very flexible.
5. Summary
In the development of VUE applications, we can refer to some interfaces of Windows software, which can occasionally give us great inspiration and inspiration. Of course, also hope this article can help small friends.