数据权限的设计与实现系列6——前端筛选器组件Everright-filter使用探索

linear 功能探索

最终我们是需要使用 API 的方式,调用后端服务拉取数据填充筛选器组件,不过在探索阶段,直接用 API 方式,就需要构造 mock 数据,比较麻烦,因此先使用 Function 方式来进行功能验证。

组件初始化

新建一个页面,复制官方示例,如下:

<script setup>
import { ref } from 'vue'
import { EverrightFilter } from 'everright-filter'
import 'everright-filter/dist/style.css'
const ERfilterRef = ref(null)
const lang = ref('zh-cn')
const handleListener = ({ type, data }) => {
  console.log(type, data)
}
const getOptions = async () => {
  return new Promise((resolve, reject) => {
    resolve({
      data: {
        options: [],
        operators: {}
      }
    })
  })
}
const getConditions = async (params) => {
  return new Promise((resolve, reject) => {
    resolve({
      data: {
        options: [],
        operators: {}
      }
    })
  })
}
const getProps = async () => {
  return new Promise((resolve, reject) => {
    resolve({
      data: {}
    })
  })
}
const getPropValues = async (params) => {
  return new Promise((resolve, reject) => {
    resolve({
      data: {}
    })
  })
}
</script>

<template>
  <div>
    <EverrightFilter
      :lang="lang"
      @listener="handleListener"
      :getOptions="getOptions"
      :getConditions="getConditions"
      :getProps="getProps"
      :getPropValues="getPropValues"
      ref="ERfilterRef"
    />
  </div>

</template>

页面初始化效果如下:

下拉列表是空的,添加条件点击后,组件显示发生了变化,如下:

大概的界面展示效果出来了,接下来我们摸索下如何添加一个最常用的文本类筛选条件。

文本类筛选条件

经过摸索,筛选条件对应着组件的 option,因此调整 getOptions 方法,模拟一个姓名的筛选条件,如下:

const getOptions = async () => {
  return new Promise((resolve, reject) => {
    resolve({
      data: {
        options: [
          {
            label: '姓名',
            en_label: 'name',
            renderType: 'TEXT',
            operatorKey: 'Text',
            value: 'name'        
          }
        ],
        operators: {
          Text: [
            {
              label: '等于',
              en_label: 'Equal',
              style: 'noop'
            },
            {
              label: '等于其中之一',
              en_label: 'Equal to one of',
              value: 'one_of',
              style: 'tags'
            },
            {
              label: '不等于',
              en_label: 'Not equal',
              value: 'not_equal',
              style: 'noop'
            },
            {
              label: '包含',
              en_label: 'Contains',
              value: 'contains',
              style: 'noop'
            },
            {
              label: '不包含',
              en_label: 'Not contain',
              value: 'not_contain',
              style: 'noop'
            },
            {
              label: '为空',
              en_label: 'Empty',
              value: 'empty',
              style: 'none'
            },
            {
              label: '不为空',
              en_label: 'Not empty',
              value: 'not_empty',
              style: 'none'
            }
          ]
        }
      }
    })
  })
}

效果如下:

每个筛选条件是一个对象,用{}包裹,对象属性含义如下:

label: 中文语种下的标签名称

en_label:英文语种下的标签名称

value: 筛选条件的英文编码

renderType: 筛选条件值的输入或选择控件,可选值:CASCADER,SELECT,REGION,TEXT,NUMBER,TIME,DATE,NONE

operatorKey: 操作符的键,需要在下面的 operators 中定义,一个键对应一个操作符集合。

还有includeOperator 和 excludeOperator两个属性,可以对操作符集合进行正向或反向选取。

例如,上面姓名例子中,若不希望操作符出现“等于其中之一”,需按如下写法配置:

options: [
  {
    label: '姓名',
    en_label: 'name',
    renderType: 'TEXT',
    operatorKey: 'Text',
    value: 'name',
    excludeOperator: {
      operator: ['one_of']
    }
  }
]

注意 excludeOperator 后不是直接指定数组,而是加了一层 operator 节点,其中的值 one_of 对应着操作符对象属性中的 value。

调整后就从操作符列表中去除了“等于其中之一”这一项,如下:

数值类筛选条件

参照上述文本类的配置模式,我们添加一个数值类筛选条件:年龄,如下:

const getOptions = async () => {
  return new Promise((resolve, reject) => {
    resolve({
      data: {
        options: [
          {
            label: '姓名',
            en_label: 'name',
            renderType: 'TEXT',
            operatorKey: 'Text',
            value: 'name',
            excludeOperator: {
              operator: ['one_of']
            }
          },
          {
            label: '年龄',
            en_label: 'age',
            renderType: 'NUMBER',
            operatorKey: 'Number',
            value: 'age'
          }
        ],
        operators: {
          Text: [
            {
              label: '等于',
              en_label: 'Equal',
              style: 'noop'
            },
            {
              label: '等于其中之一',
              en_label: 'Equal to one of',
              value: 'one_of',
              style: 'tags'
            },
            {
              label: '不等于',
              en_label: 'Not equal',
              value: 'not_equal',
              style: 'noop'
            },
            {
              label: '包含',
              en_label: 'Contains',
              value: 'contains',
              style: 'noop'
            },
            {
              label: '不包含',
              en_label: 'Not contain',
              value: 'not_contain',
              style: 'noop'
            },
            {
              label: '为空',
              en_label: 'Empty',
              value: 'empty',
              style: 'none'
            },
            {
              label: '不为空',
              en_label: 'Not empty',
              value: 'not_empty',
              style: 'none'
            }
          ],
          Number: [
            {
              label: '等于',
              en_label: 'Equal',
              value: 'equal',
              style: 'noop'
            },
            {
              label: '不等于',
              en_label: 'Not equal',
              value: 'not_equal',
              style: 'noop'
            },
            {
              label: '大于',
              en_label: 'Greater than',
              value: 'greater_than',
              style: 'noop'
            },
            {
              label: '大于等于',
              en_label: 'Greater than or equal to',
              value: 'greater_than_equal',
              style: 'noop'
            },
            {
              label: '小于',
              en_label: 'Less than',
              value: 'less_than',
              style: 'noop'
            },
            {
              label: '小于等于',
              en_label: 'Less than or equal to',
              value: 'less_than_equal',
              style: 'noop'
            },
            {
              label: '区间',
              en_label: 'Between',
              value: 'between',
              style: 'range'
            },
            {
              label: '为空',
              en_label: 'Empty',
              value: 'empty',
              style: 'none'
            },
            {
              label: '不为空',
              en_label: 'Not empty',
              value: 'not_empty',
              style: 'none'
            }
          ]
        }
      }
    })
  })
}

效果如下:

‍其他数据类型,如日期、时间等也大同小异,先不管细节,优先看看整体,继续说一下操作符。

操作符

在上面的探索过程中,实际已经涉及到了操作符,再具体说明下。

示例

[
    {
      label: '等于',
      en_label: 'Equal',
      value: 'equal',
      style: 'noop' // 无意义
    },
    {
      label: '等于其中之一',
      en_label: 'Equal to one of',
      value: 'one_of',
      style: 'tags' // 由操作符控制value为多选类型,适用于renderType CASCADER、SELECT、REGION、TEXT
    },
    {
      label: '为空',
      en_label: 'Empty',
      value: 'empty',
      style: 'none' // 不显示 value
    },
    {
      label: '区间',
      en_label: 'Between',
      value: 'between',
      style: 'range' // 由操作符控制value为区间类型,适用于renderType NUMBER、TIME、DATE
    }
  ]

属性说明

label: ‘为空’,
en_label: ‘Empty’,
value: 操作符的编码,自定义
style: 样式,内置了四种

  • none:不显示值控件,用于不需要值的地方,如为空、不为空等
  • noop:单个值,如等于、不等于
  • tags:由操作符控制 value 为多选类型,适用于 renderType 为CASCADER、SELECT、REGION、TEXT类型之一时
  • range:由操作符控制 value 为区间类型,适用于 renderType 为 NUMBER、TIME、DATE 类型之一时

组件方法

我们使用数据筛选器进行灵活的自定义条件组合,最终还是需要将筛选器的结果拿到后,作为参数传给后端服务的。

这时候就需要使用组件提供的 getData 方法了。

在页面中新加一个按钮,调用组件的获取数据方法,将数据 json 格式化后输出到控制台,如下:

我们输入两个查询条件,界面如下:

点击按钮,输出数据如下:

{
  "filters": [
    {
      "conditions": [
        {
          "property": "name",
          "value": "张三"
        },
        {
          "operator": "greater_than",
          "property": "age",
          "value": 24
        }
      ],
      "logicalOperator": "and"
    }
  ],
  "logicalOperator": "and"
}

注意该 json 的数据结构以及最终数据和 option 和 operater 的对应关系,筛选条件 option 的 value 对应着 conditions 中的 property,操作符 operation 的 value 对应着 conditions 中的 operator,筛选条件输入的值,最终对应着 conditions 中的 vaule,然后就是组内和组件的关系设定,是 and 还是 or。

后端拿到该 json 语句后,进行解析和处理,转换成最终的 sql 语句来执行。‍

matrix 功能探索

有了上面 linear 的基础,matrix 就简单多了。

逻辑组的数量,类型为 linear 时默认只有 1 个,类型matrix则调整为了可以动态添加多个。

在原 demo 代码基础上,为筛选器组件新增一个属性 type="matrix"(默认是 linear)即可,刷新页面,效果如下:

获取到 data 结构如下:

{
  "filters": [
    {
      "conditions": [
        {
          "property": "name",
          "value": "张三"
        },
        {
          "operator": "greater_than",
          "property": "age",
          "value": 24
        }
      ],
      "logicalOperator": "and"
    },
    {
      "conditions": [
        {
          "operator": "equal",
          "property": "age",
          "value": 30
        }
      ],
      "logicalOperator": "and"
    }
  ],
  "logicalOperator": "and"
}

可以看到,数据结构并没有变化,只是多个逻辑分组的情况下,数据看上去更复杂了一些而已。

开源平台资料

平台名称:一二三开发平台

简介: 企业级通用开发平台

设计资料:[csdn专栏]

开源地址:[Gitee]

开源协议:MIT

如果您在阅读本文时获得了帮助或受到了启发,希望您能够喜欢并收藏这篇文章,为它点赞~
请在评论区与我分享您的想法和心得,一起交流学习,不断进步,遇见更加优秀的自己!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/873074.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Visual Studio Code:让你的工作效率飞升的秘密武器

在现代软件开发环境中&#xff0c;效率已成为每个开发者追求的目标。而在众多编程工具中&#xff0c;Visual Studio Code&#xff08;简称VS Code&#xff09;凭借其强大的功能、轻量的界面和高度的可定制性&#xff0c;成为了全球开发者的首选。无论你是编写前端代码、后端服务…

软考(计算机技术与软件专业技术资格(水平)考试)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

SpringBoot教程(十五) | SpringBoot集成RabbitMq(消息丢失、消息重复、消息顺序、消息顺序)

SpringBoot教程&#xff08;十五&#xff09; | SpringBoot集成RabbitMq&#xff08;消息丢失、消息重复、消息顺序、消息顺序&#xff09; RabbitMQ常见问题解决方案问题一&#xff1a;消息丢失的解决方案&#xff08;1&#xff09;生成者丢失消息丢失的情景解决方案1&#xf…

C++三位状态比较排序

数组相同元素个数及按序 void 交换3个数升(int& A, int& B, int& C, bool& k) {int J 0;if (B > A&&A > C)J C, C B, B A, A J, k true;//231else if (C > A&&A > B)J A, A B, B J, k true;//213else if (A > B&a…

使用python+opencv解析图像和文本数据

1. 创建虚拟环境 新建文件夹, 并在文件夹中创建虚拟环境,可以使用Vscode打开文件夹, 然后在终端中输入以下命令: python -m venv venv2. 激活虚拟环境 在终端中输入以下命令: venv\Scripts\activate3. 安装依赖 在终端中输入以下命令: pip install opencv-pythonpip inst…

ArmSoM CM5 RK3576核心板推出,强势替代树莓派CM4

ArmSoM团队隆重推出全新的CM5 RK3576核心板&#xff0c;这款模块专为嵌入式开发者设计&#xff0c;凭借其强大的性能与丰富的扩展性&#xff0c;完美替代树莓派CM4&#xff0c;成为开发者们的理想选择。 CM5核心板采用了先进的RK3576 SoC&#xff0c;凭借卓越的计算能力和出色…

MapSet之二叉搜索树

系列文章&#xff1a; 1. 先导片--Map&Set之二叉搜索树 2. Map&Set之相关概念 目录 前言 1.二叉搜索树 1.1 定义 1.2 操作-查找 1.3 操作-新增 1.4 操作-删除(难点) 1.5 总体实现代码 1.6 性能分析 前言 TreeMap 和 TreeSet 是 Java 中基于搜索树实现的 M…

第一个搭建SpringBoot项目(连接mysql)

首先新建项目找到Spring Initializr 我使用的URL是https://start.spring.io这里最低的JDK版本是17&#xff0c;而且当网速不好的时候可能会显示超时&#xff0c;这里可以选用阿里云的镜像https://start.aliyun.com可以更快一些但是里面还是有一些区别的 我们这里选择Java语言&a…

2024 数学建模高教社杯 国赛(A题)| “板凳龙”舞龙队 | 建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍团队独辟蹊径&#xff0c;运用等距螺线&#xff0c;多目标规划等强大工具&#xff0c;构建了这一题的详细解答哦&#xff01; 为大家量身打造创新解决方案。小秘籍团队&#xff0c;始终引领着建模问题求解的风潮。 抓紧小秘籍&am…

《深度学习》OpenCV轮廓检测 轮廓近似 解析及实现

目录 一、轮廓近似 1、什么是轮廓近似 2、参数解析 1&#xff09;用法 2&#xff09;参数 3&#xff09;返回值 4&#xff09;代码解析及实现 运行结果为&#xff1a; 二、总结 1、概念 2、轮廓近似的步骤&#xff1a; 一、轮廓近似 1、什么是轮廓近似 指对轮廓进行…

Linux_kernel移植uboot07

一、移植 根据硬件平台的差异&#xff0c;将代码进行少量的修改&#xff0c;修改过后的代码在目标平台上运行起来 移植还需要考虑硬件环境&#xff0c;驱动只需要考虑内核的环境 二、移植内容 1、移植Uboot uboot属于bootloader的一种&#xff0c;还有其他的bootloader&#x…

Qt-常用控件(3)-多元素控件、容器类控件和布局管理器

1. 多元素控件 Qt 中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView xxWidget 和 xxView 之间的区别&#xff0c;以 QTableWidget 和 QTableView 为例. QTableView 是基于 MVC 设计的控件.QTableView 自身不持有数据,使用 QTableView 的…

欧拉系统安装 NVIDIA 显卡驱动

1、安装显卡驱动编译工具 yum install gcc make kernel-devel 2、安装显卡驱动依赖包 yum install vulkan-loader 可选安装项&#xff0c;不安装该系统包时会出现以下警告提示&#xff0c;但不影响安装和使用。 3、安装 NVIDIA GPU 驱动 生产环境建议选择 .run 格式的驱动…

Autoware 定位之初始姿态输入(九)

0. 简介 这一讲按照《Autoware 技术代码解读&#xff08;三&#xff09;》梳理的顺序&#xff0c;我们来说一说Autoware中的初始化操作&#xff0c;这个软件包当中完成了ekf_localizer发送初始姿态的包。它接收来自GNSS/用户的粗略估计的初始姿态。将姿态传递给ndt_scan_match…

[数据集][目标检测]石油泄漏检测数据集VOC+YOLO格式6633张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6633 标注数量(xml文件个数)&#xff1a;6633 标注数量(txt文件个数)&#xff1a;6633 标注…

解决Django会话中的竞态条件

Django 会话中的竞态条件&#xff08;race condition&#xff09;问题通常发生在多个请求几乎同时修改同一个会话数据时&#xff0c;导致数据丢失或数据不一致。这种情况在需要频繁更新会话数据的场景&#xff08;如实时聊天应用、并发请求处理等&#xff09;中尤为常见。 1、问…

CentOS 7 docker 部署遇到内网通,外网不通 问题

CentOS 7 docker 部署遇到内网通&#xff0c;外网不通 问题 [rootlocalhost ~]# systemctl status network ● network.service - LSB: Bring up/down networkingLoaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled)Active: failed (Result: exit-code) …

9-6springboot该如何学习

这阶段如何学习 javase&#xff1a;面向对象OOP mysql:持久化 htmlcssjsjquery框架&#xff1a;视图&#xff08;框架不熟练&#xff09;&#xff0c;css不好 javaweb&#xff1a;独立开发MVC三层架构的网站&#xff1a;原始 ssm&#xff1a;框架&#xff1a;简化了我们的…

2-1 opencv实战进阶系列 阈值编辑器

目录 一、不说废话&#xff0c;先上现象 二、前言 三、方法详解 四、贴出完整代码 一、不说废话&#xff0c;先上现象 二、前言 对图像的处理中&#xff0c;设置合适的掩膜、寻找多边形、颜色追踪等方法都需要预先设置好颜色的上阈值和下阈值&#xff0c;来从原图中分割出…

C++11线程池、多线程编程(附源码)

Test1 示例源码展示&#xff1a; #include<iostream> #include<thread> #include<string> using namespace std;void printHelloWord(string s) {cout << s << endl;//return; } int main() {string s;s "wegfer";thread thread1(p…