Vue implements dynamic query rule generation component

Vue implements dynamic query rule generation component

1. Dynamic query rules

The dynamic query rules are roughly as shown in the figure below. It is a complex component that can organize query statements according to user customization, and can roughly implement the where condition of SQL query. The following is an excerpt from a certain software of mongodb.

insert image description here

2. Component construction ideas

According to the organizational form of rule components, it can be regarded as a tree with a trunk and leaves, which does not seem difficult.

2.1 Component attribute data: is the content of the tree structure, which we define as:

{
condition: 'AND',
rules: [],
}

fieldList: field list array, a collection of fields available for selection;

operatorList: An array of operation lists, a set of optional operations, defined as follows:

{
     label: 'include',
          value: '⊂',
},

2.2 Component HTML

ElementUI is used here to build it, so you can easily combine various UI controls to build the required interface.
Of course, since this component is considered a tree, it is also a recursive component, so it also 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 rule</el-button>
                <el-button size="mini" @click="addGroup(data)">Add 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">                        
                        <!-- Fields -->
                        <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>

2.3 Define different conditions for fields of different data types

const rules = {
    string: [
        {
            value: '==',
            label: 'equal to',
        },
        {
            value: '<>',
            label: 'not equal',
        },
        {
            value: '⊂',
            label: 'include',
        },
        {
            value: '⊄',
            label: 'does not contain',
        },
        {
            value: 'in',
            label: 'One of them',
        },
        {
            value: 'ni',
            label: 'Not one of them',
        },
        {
            value: 'mc',
            label: 'Multiple inclusions',
        },
    ],
    number: [
        {
            value: '==',
            label: 'equal to',
        },
        {
            value: '<>',
            label: 'not equal',
        },
        {
            value: '≥',
            label: 'greater than or equal to',
        },
        {
            value: '≤',
            label: 'less than or equal to',
        },
    ],
    dict: [
        {
            value: 'in',
            label: 'One of them',
        },
        {
            value: 'ni',
            label: 'Not one of them',
        },
    ],
    date: [
        {
            value: 'sdiff',
            label: 'A few days ago',
        },
        {
            value: 'ediff',
            label: 'A few days later',
        },
    ],
}

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 rules addRule(data) {
            let rule = {
                type: 'Text',
                FilterTable: this.firstTable,
                FilterField: this.firstField,
                Operator: '==',
                FilterValue: '',
            }
            data.rules.push(rule)
        },
        // Delete rule delRule(index) {
            this.data.rules.splice(index, 1)
        },
        // Add group addGroup(data) {
            let group = {
                condition: 'OR',
                rules:
                    {
                        type: 'Text',
                        FilterTable: this.firstTable,
                        FilterField: '',
                        Operator: '',
                        FilterValue: '',
                    },
                ],
            }
            data.rules.push(group)
        },
        // Delete group delGroup(data, parent) {
            let index = parent.rules.findIndex((item) => item === data)
            parent.rules.splice(index, 1)
        },

2.5 Define component name

The component is named CreateRule and the definition code is very simple.

export default {
    name: 'CreateRule',
    props: {
        parent: {
            type: Object,
        },
        data: {
            type: Object,
        },
        fieldList: {
            type: Array,
            default() {
                return []
            },
        },
        operatorList: {
            type: Array,
            default() {
                return []
            },
        },
    },
  }

3. Use components

To use components in Vue, just reference them and add them to the component list.

import CreateRule from './CreateRule'
export default {
    name: 'NewRuleForm',
    components:
        CreateRule,
    },
}

Add references to templates

<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. Effect display

This is the actual effect of interception.

insert image description here

In the interface, it works well as a search criterion or a filter criterion 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 enlightenment.

This is the end of this article about Vue's implementation of dynamic query rule generation components. For more relevant Vue dynamic query rule generation component content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of using Vue component to query data by time period
  • Sample code for fuzzy query of Vue input box
  • Vue implements the fuzzy query method of Input input box
  • Vue.js implements paging query function
  • Vue implements the function of clicking on time to obtain time period query
  • Detailed example of query operation in Vue.js
  • Using Vue.js framework to implement train ticket query system (with source code)
  • Implementing paging query function based on vue.js
  • Example code for implementing paging query using Bootstrap4 + Vue2
  • vue+element custom query component

<<:  Detailed explanation of how to use Docker-Compose commands

>>:  Summary of how to modify the root password in MySQL 5.7 and MySQL 8.0

Recommend

Example code for implementing background blur effect with CSS

Is it the effect below? If so, please continue re...

How to install babel using npm in vscode

Preface The previous article introduced the insta...

Understanding and application of JavaScript ES6 destructuring operator

Table of contents Preface The role of deconstruct...

vue-cli introduction and installation

Table of contents 1. Introduction 2. Introduction...

Upgrade Docker version of MySQL 5.7 to MySQL 8.0.13, data migration

Table of contents 1. Back up the old MySQL5.7 dat...

Nginx configuration 80 port access 8080 and project name address method analysis

Tomcat accesses the project, usually ip + port + ...

The difference between JS pre-parsing and variable promotion in web interview

Table of contents What is pre-analysis? The diffe...

How to monitor Linux server status

We deal with Linux servers every day, especially ...

Implementation example of Docker rocketmq deployment

Table of contents Preparation Deployment process ...

mysql installer web community 5.7.21.0.msi installation graphic tutorial

This article example shares the specific code for...

A must-read career plan for web design practitioners

Original article, please indicate the author and ...

Detailed example of MySQL (5.6 and below) parsing JSON

MySQL (5.6 and below) parses json #json parsing f...