Vue实现动态查询规则生成组件


Posted in Vue.js onMay 27, 2021

1. 动态查询规则

动态查询规则,大致如下图所示。是可以按照用户的自定义进行组织查询语句的一种复杂组件,大致可以实现SQL查询的where条件,下面是摘自mongodb的某一软件。

Vue实现动态查询规则生成组件

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.效果展示

这是截取的实际效果.

Vue实现动态查询规则生成组件

在界面中,作为搜索条件或过滤条件效果均不错,可以做到非常灵活。

5.小结

在vue开发应用中,可以多参考下windows软件的某些界面,偶尔能给我们很大的灵感和启发的。

到此这篇关于Vue实现动态查询规则生成组件的文章就介绍到这了,更多相关Vue 动态查询规则生成组件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
vue使用echarts图表自适应的几种解决方案
Dec 04 Vue.js
vuex的使用步骤
Jan 06 Vue.js
vue使用过滤器格式化日期
Jan 20 Vue.js
深入了解Vue动态组件和异步组件
Jan 26 Vue.js
vue 根据选择的月份动态展示日期对应的星期几
Feb 06 Vue.js
Vue实现todo应用的示例
Feb 20 Vue.js
vue路由实现登录拦截
Mar 24 Vue.js
vue实现无缝轮播效果(跑马灯)
May 14 Vue.js
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
May 18 Vue.js
VUE中的v-if与v-show区别介绍
Mar 13 Vue.js
vue的项目如何打包上线
Apr 13 Vue.js
vue @ ~ 相对路径 路径别名设置方式
Jun 05 Vue.js
详解vue身份认证管理和租户管理
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
vue-element-admin项目导入和导出的实现
May 21 #Vue.js
vue2实现provide inject传递响应式
May 21 #Vue.js
vue使用节流函数的踩坑实例指南
vue实现同时设置多个倒计时
May 20 #Vue.js
Vue和Flask通信的实现
You might like
DOTA2 6.87版本后新眼位详解攻略
2020/04/20 DOTA
PHP 处理TXT文件(打开/关闭/检查/读取)
2013/05/13 PHP
PHP程序员的技术成长规划
2016/03/25 PHP
PHP中__autoload和Smarty冲突的简单解决方法
2016/04/08 PHP
深入理解PHP原理之执行周期分析
2016/06/01 PHP
Javascript实现DIV滚动自动滚动到底部的代码
2012/03/01 Javascript
关于js new Date() 出现NaN 的分析
2012/10/23 Javascript
javascript中2个感叹号的用法实例详解
2014/09/04 Javascript
jquery+CSS3模拟Path2.0动画菜单效果代码
2015/08/31 Javascript
深入探讨Vue.js组件和组件通信
2016/09/12 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
2017/01/03 Javascript
js实现简易垂直滚动条
2017/02/22 Javascript
Vue组件中slot的用法
2018/01/30 Javascript
jQuery插件实现非常实用的tab栏切换功能【案例】
2019/02/18 jQuery
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
JS如何实现动态添加的元素绑定事件
2019/11/12 Javascript
JavaScript大数相加相乘的实现方法实例
2020/10/18 Javascript
swiperjs实现导航与tab页的联动
2020/12/13 Javascript
使用python搭建Django应用程序步骤及版本冲突问题解决
2013/11/19 Python
用map函数来完成Python并行任务的简单示例
2015/04/02 Python
Python多线程编程(六):可重入锁RLock
2015/04/05 Python
Python基础知识_浅谈用户交互
2017/05/31 Python
Python 列表理解及使用方法
2017/10/27 Python
对numpy中布尔型数组的处理方法详解
2018/04/17 Python
python计算列表内各元素的个数实例
2018/06/29 Python
pyqt5中QThread在使用时出现重复emit的实例
2019/06/21 Python
使用python无账号无限制获取企查查信息的实例代码
2020/04/17 Python
python调用百度API实现人脸识别
2020/11/17 Python
荷兰浴室和卫浴网上商店:Badkamerxxl.nl
2020/10/06 全球购物
就业推荐自我鉴定
2013/10/06 职场文书
火锅店创业计划书范文
2014/02/02 职场文书
平安校园建设方案
2014/05/02 职场文书
2014年有孩子的离婚协议书范本
2014/10/08 职场文书
详解Spring Security中的HttpBasic登录验证模式
2022/03/17 Java/Android
python实现会员信息管理系统(List)
2022/03/18 Python
对讲机知识
2022/04/07 无线电