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中使用CSS3实现内容无缝滚动的示例代码
Nov 27 Vue.js
vue实现表格合并功能
Dec 01 Vue.js
如何在VUE中使用vue-awesome-swiper
Jan 04 Vue.js
如何在vue-cli中使用css-loader实现css module
Jan 07 Vue.js
vue自定义组件实现双向绑定
Jan 13 Vue.js
Vue中的nextTick作用和几个简单的使用场景
Jan 25 Vue.js
深入理解Vue的数据响应式
May 15 Vue.js
vue-cropper插件实现图片截取上传组件封装
May 27 Vue.js
vue+elementui 实现新增和修改共用一个弹框的完整代码
Jun 08 Vue.js
VUE使用draggable实现组件拖拽
Apr 06 Vue.js
vue如何清除浏览器历史栈
May 25 Vue.js
Vue深入理解插槽slot的使用
Aug 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
日本收入最高的漫画家:海贼王作者版税年收入高达8.45亿元
2020/03/04 日漫
PHP提取字符串中的图片地址[正则表达式]
2011/11/12 PHP
php的大小写敏感问题整理
2011/12/29 PHP
php实现水仙花数的4个示例分享
2014/04/08 PHP
PHP两种去掉数组重复值的方法比较
2014/06/19 PHP
PHP编程中尝试程序并发的几种方式总结
2016/03/21 PHP
tp5框架基于Ajax实现列表无刷新排序功能示例
2020/02/10 PHP
js 判断计算字符串长度/判断空的简单方法
2013/08/05 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
2013/11/19 Javascript
js实现的折叠导航示例
2013/11/29 Javascript
JQuery中extend使用介绍
2014/03/13 Javascript
JS版的date函数(和PHP的date函数一样)
2014/05/12 Javascript
jQuery弹出框代码封装DialogHelper
2015/01/30 Javascript
网页中右键功能的实现方法之contextMenu的使用
2017/02/20 Javascript
在 Angular 中实现搜索关键字高亮示例
2017/03/21 Javascript
mac下的nodejs环境安装的步骤
2017/05/24 NodeJs
微信小程序实现文字跑马灯效果
2020/05/26 Javascript
浅谈vue项目如何打包扔向服务器
2018/05/08 Javascript
微信小程序画布圆形进度条显示效果
2020/11/17 Javascript
在vue中把含有html标签转为html渲染页面的实例
2019/10/28 Javascript
如何基于JavaScript判断图片是否加载完成
2019/12/28 Javascript
Python实现的一个找零钱的小程序代码分享
2014/08/25 Python
python自动化测试之setUp与tearDown实例
2014/09/28 Python
python实现定时同步本机与北京时间的方法
2015/03/24 Python
详解Python中的各种函数的使用
2015/05/24 Python
Python 类与元类的深度挖掘 II【经验】
2016/05/06 Python
利用python实现xml与数据库读取转换的方法
2017/06/17 Python
python正则实现计算器功能
2017/12/14 Python
css3制作彩色边线3d立体按钮的示例(css3按钮)
2014/05/06 HTML / CSS
世界上最大的家庭自动化公司:Smarthome
2017/12/20 全球购物
Bose法国官网:购买耳机、扬声器、家庭影院、专业音响
2017/12/21 全球购物
道路运输企业安全生产责任书
2014/07/28 职场文书
对照四风自我剖析材料
2014/10/07 职场文书
优秀家长事迹材料(2016推荐版)
2016/02/29 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书
Python入门学习之类的相关知识总结
2021/05/25 Python