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实现表格合并功能
Dec 01 Vue.js
对vue生命周期的深入理解
Dec 03 Vue.js
vue如何使用rem适配
Feb 06 Vue.js
vue 数据双向绑定的实现方法
Mar 04 Vue.js
解读Vue组件注册方式
May 15 Vue.js
vue 实现上传组件
May 31 Vue.js
Vue Element-ui表单校验规则实现
Jul 09 Vue.js
Vue自定义铃声提示音组件的实现
Jan 22 Vue.js
vue elementUI批量上传文件
Apr 26 Vue.js
vue/cli 配置动态代理无需重启服务的方法
May 20 Vue.js
Vue Element plus使用方法梳理
Dec 24 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
《破坏领主》销量已超100万 未来将继续开发新内容
2020/03/08 其他游戏
ajax+php打造进度条 readyState各状态
2010/03/20 PHP
php对mongodb的扩展(初出茅庐)
2012/11/11 PHP
php导出csv数据在浏览器中输出提供下载或保存到文件的示例
2014/04/24 PHP
PHP AjaxForm提交图片上传并显示图片源码
2016/11/29 PHP
PHP实现双链表删除与插入节点的方法示例
2017/11/11 PHP
Laravel项目中timeAgo字段语言转换的改善方法示例
2019/09/16 PHP
js实现GridView单选效果自动设置交替行、选中行、鼠标移动行背景色
2010/05/27 Javascript
JavaScript实现统计文本框Textarea字数增强用户体验
2012/12/21 Javascript
JavaScript生成的动态下雨背景效果实现方法
2015/02/25 Javascript
JS获取月份最后天数、最大天数与某日周数的方法
2015/12/08 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
详解JavaScript中基于原型prototype的继承特性
2016/05/05 Javascript
基于Vue如何封装分页组件
2016/12/16 Javascript
微信小程序实现页面跳转传值的方法
2017/10/12 Javascript
nodeJS与MySQL实现分页数据以及倒序数据
2020/06/05 NodeJs
VUE异步更新DOM - 用$nextTick解决DOM视图的问题
2020/11/06 Javascript
[03:47]2015国际邀请赛第三日现场精彩回顾
2015/08/08 DOTA
[00:12]2018DOTA2亚洲邀请赛 sylar表现SOLO技艺
2018/04/06 DOTA
[01:11:21]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第一场 3月6日
2021/03/11 DOTA
python实现k均值算法示例(k均值聚类算法)
2014/03/16 Python
python判断给定的字符串是否是有效日期的方法
2015/05/13 Python
简单谈谈Python流程控制语句
2016/12/04 Python
Python中查看文件名和文件路径
2017/03/31 Python
[原创]Python入门教程2. 字符串基本操作【运算、格式化输出、常用函数】
2018/10/29 Python
画pytorch模型图,以及参数计算的方法
2019/08/17 Python
python实现通过队列完成进程间的多任务功能示例
2019/10/28 Python
python pptx复制指定页的ppt教程
2020/02/14 Python
基于Python的OCR实现示例
2020/04/03 Python
pandas dataframe 中的explode函数用法详解
2020/05/18 Python
Python代码覆盖率统计工具coverage.py用法详解
2020/11/25 Python
加拿大百叶窗和窗帘定制网站:Blinds
2017/01/30 全球购物
八项规定整改措施
2014/02/12 职场文书
党员教师四风问题对照检查材料
2014/09/26 职场文书
2015年企业团支部工作总结
2015/05/21 职场文书
单机多实例部署 MySQL8.0.20
2022/05/15 MySQL