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+vant实现购物车全选和反选功能
Nov 17 Vue.js
vue单元格多列合并的实现
Nov 26 Vue.js
Vue router安装及使用方法解析
Dec 02 Vue.js
Vue解决移动端弹窗滚动穿透问题
Dec 15 Vue.js
Vue.extend 登录注册模态框的实现
Dec 29 Vue.js
vue element和nuxt的使用技巧分享
Jan 14 Vue.js
Vue实现摇一摇功能(兼容ios13.3以上)
Jan 26 Vue.js
vue完美实现el-table列宽自适应
May 08 Vue.js
Vue通过懒加载提升页面响应速度
May 10 Vue.js
Vue中插槽slot的使用方法与应用场景详析
Jun 08 Vue.js
vue修饰符.capture和.self的区别
Apr 22 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
Apache下禁止php文件被直接访问的解决方案
2013/04/25 PHP
基于PHP对XML的操作详解
2013/06/07 PHP
PHP面向对象编程之深入理解方法重载与方法覆盖(多态)
2015/12/24 PHP
CodeIgniter针对数据库的连接、配置及使用方法
2016/03/03 PHP
php 判断过去离现在几年的函数(实例代码)
2016/11/15 PHP
PHP连接MySQL数据库并以json格式输出
2018/05/21 PHP
PHP智能识别收货地址信息实例
2019/01/05 PHP
如何设置一定时间内只能发送一次请求
2014/02/28 Javascript
php读取sqlite数据库入门实例代码
2014/06/25 Javascript
jQuery实现按钮点击遮罩加载及处理完后恢复的效果
2016/06/07 Javascript
使用bat打开多个cmd窗口执行gulp、node
2017/02/17 Javascript
详解Angular操作cookies方法
2018/06/01 Javascript
vue插件实现v-model功能
2018/09/10 Javascript
JavaScript实现身份证验证代码实例
2019/08/26 Javascript
微信小程序如何播放腾讯视频的实现
2019/09/20 Javascript
Openlayers实现点闪烁扩散效果
2020/09/24 Javascript
[01:03:33]Alliance vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
浅谈python中的面向对象和类的基本语法
2016/06/13 Python
安装Python和pygame及相应的环境变量配置(图文教程)
2017/06/04 Python
python得到windows自启动列表的方法
2018/10/14 Python
Pyqt5实现英文学习词典
2019/06/24 Python
tensorflow 环境变量设置方式
2020/02/06 Python
Python日志syslog使用原理详解
2020/02/18 Python
Python插件机制实现详解
2020/05/04 Python
Tensorflow加载Vgg预训练模型操作
2020/05/26 Python
python如何实时获取tcpdump输出
2020/09/16 Python
.NET初级开发工程师面试题
2014/04/18 面试题
销售心得体会
2014/01/02 职场文书
留学推荐信怎么写
2014/01/25 职场文书
学校创先争优活动总结
2014/08/28 职场文书
2014年小学数学教师工作总结
2014/12/03 职场文书
护士个人总结范文
2015/02/13 职场文书
党支部审查意见
2015/06/02 职场文书
汽车修理厂管理制度
2015/08/05 职场文书
喜迎建国70周年:有关爱国的名言名句
2019/09/24 职场文书
浅谈怎么给Python添加类型标注
2021/06/08 Python