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

Detailed explanation of redundant and duplicate indexes in MySQL

MySQL allows you to create multiple indexes on th...

The benefits of div+css and web standard pages

The div element is used to provide structure and b...

Database query optimization: subquery optimization

1. Case Take all employees who are not the head o...

An article to understand operators in ECMAScript

Table of contents Unary Operators Boolean Operato...

HTML table tag tutorial (8): background image attribute BACKGROUND

Set a background image for the table. You can use...

A simple LED digital clock implementation method in CSS3

This should be something that many people have do...

Perfect solution to MySQL common insufficient memory startup failure

1. If MySQL is not started successfully, check th...

JavaScript implementation of magnifying glass details

Table of contents 1. Rendering 2. Implementation ...

User needs lead to marketing-oriented design

<br />For each of our topics, the team will ...

Vue makes div height draggable

This article shares the specific code of Vue to r...

How to start tomcat using jsvc (run as a normal user)

Introduction to jsvc In production, Tomcat should...

Detailed explanation of using top command to analyze Linux system performance

Introduction to Linux top command The top command...

Vue Basics Listener Detailed Explanation

Table of contents What is a listener in vue Usage...

On Visual Design and Interaction Design

<br />In the entire product design process, ...