实现一个筛选框,点击筛选按钮出现弹窗,弹窗内有选择框/输入框/单选框等等,底部有重置/确定两个按钮。

需求:

  1. 点击筛选外部其他位置可以关闭弹窗,关闭弹窗后已编辑的数据不保存,
  2. 点击确定按钮关闭弹窗;
  3. 点击重置按钮不关闭弹窗;
  4. 弹窗打开时,点击筛选按钮弹窗关闭,弹窗关闭时,点击筛选按钮弹窗打开;

如下图所示:

图一

实现方法:

完整代码在最下方,展示的是方法二的完整代码,可以根据自己需求来修改对应的逻辑。

注意:两种方法都需要把有下拉框的组件中加上:teleported="false",否则,点击下拉框选择数据后也会关闭弹窗,就不符合需求了。

一、通过ref+hide方法实现

实现步骤:

1、在el-popover设置popoverRef,在点击弹窗内部的确定按钮时,通过popoverRef.value.hide()关闭弹窗;

2、要实现点击弹窗外其他地方,已编辑的数据不保存,用sessionStorage来实现,在点击确定按钮通过sessionStorage把参数保存起来,点击重置,就删除sessionStorage的参数;

3、使用el-popover自带的hide方法,点击弹窗外其他地方后,通过hide方法把已编辑的数据恢复;

const popoverRef = ref<any>(null)// 关闭弹窗
const clickShowFilter = async () => {if (sessionStorage.getItem('filterFormQuery')) {Object.assign(filterForm.value,JSON.parse(sessionStorage.getItem(`filterFormQuery`) || ''))} else {handleCancel('清除')}
}// 重置
const handleCancel = async (type = '') => {filterForm.value = {selectVal: '',inputVal: '',radioVal: '1',dateVal: '',}if (type === '清除') {return false}// 清除筛选参数sessionStorage.removeItem(`filterFormQuery`)// 调用接口
}// 确定
const handleConfirm = async () => {// 关闭弹窗popoverRef.value.hide()// 保存筛选参数sessionStorage.setItem('filterFormQuery', JSON.stringify(filterForm.value))// 调用接口
}

二、通过:visible+v-click-outside实现

使用visible手动控制弹窗的显示/隐藏,点击筛选按钮和确定按钮时,可以通过定义的变量来控制弹窗,但是点击空白区域不会自动关闭弹窗,这时候就需要用到Element Plus 提供的 v-click-outside 指令。

1、引入指令:

import { ClickOutside as vClickOutside } from 'element-plus'

2、给el-popover中的reference绑定指令元素

3、定义关闭函数

const handleClickOutside = (event: { target: any }) => {const popoverContent = popoverRef.value?.popperRef?.contentRefif (fillterShow.value && !popoverContent?.contains(event.target)) {fillterShow.value = false}
}

完整代码:

<template><div class="box"><el-popoverref="popoverRef"placement="bottom-start":width="300"trigger="click":teleported="false":visible="fillterShow"><template #reference><div@click="clickShowFilter"v-click-outside="handleClickOutside":disabled="loading"class="filter-button"><span>筛选</span><el-icon :size="14" color="#$008dff"><Filter /></el-icon></div></template><el-formlabel-position="top"label-width="auto":model="filterForm"class="query-box":inline="true"><el-form-item label="选择框:"><el-select:teleported="false"v-model="filterForm.selectVal"placeholder="请选择"><el-option :key="0" label="全部" value="" /><el-option :key="1" label="选择1" :value="1" /><el-option :key="2" label="选择2" :value="2" /></el-select></el-form-item><el-form-item label="输入框:"><el-inputv-model="filterForm.inputVal"placeholder="请输入"suffix-icon="Search"/></el-form-item><el-form-item label="单选框:"><el-radio-group v-model="filterForm.radioVal"><el-radio value="1">单选1</el-radio><el-radio value="2">单选2</el-radio></el-radio-group></el-form-item><el-form-item label="日期选择框:"><el-date-picker:teleported="false"v-model="filterForm.dateVal"type="date"placeholder="日期选择"/></el-form-item><div class="form-button"><el-button :loading="loading" @click="handleCancel()">重置</el-button><el-button :loading="loading" type="primary" @click="handleConfirm">确定</el-button></div></el-form></el-popover></div>
</template>
<script setup lang="ts">
import { ClickOutside as vClickOutside } from 'element-plus'let loading = ref<boolean>(false)interface filterParams {selectVal: stringinputVal: stringradioVal: stringdateVal: string
}
const filterForm = ref<filterParams>({selectVal: '',inputVal: '',radioVal: '1',dateVal: '',
})const popoverRef = ref<any>(null)
// 筛选弹出框开关
const fillterShow = ref<boolean>(false)// 关闭弹窗
const clickShowFilter = async () => {fillterShow.value = !fillterShow.valueif (fillterShow.value) {// 判断之前是否有筛选过的参数,有就把该参数赋值给filterForm.value,没有就初始化(相当于重置)if (sessionStorage.getItem('filterFormQuery')) {Object.assign(filterForm.value,JSON.parse(sessionStorage.getItem(`filterFormQuery`) || ''))} else {handleCancel('清除')}}
}// 重置
const handleCancel = async (type = '') => {filterForm.value = {selectVal: '',inputVal: '',radioVal: '1',dateVal: '',}if (type === '清除') {return false}// 清除筛选参数sessionStorage.removeItem(`filterFormQuery`)// 调用接口
}// 确定
const handleConfirm = async () => {// 关闭弹窗fillterShow.value = false// 保存筛选参数sessionStorage.setItem('filterFormQuery', JSON.stringify(filterForm.value))// 调用接口
}const handleClickOutside = (event: { target: any }) => {const popoverContent = popoverRef.value?.popperRef?.contentRefif (fillterShow.value && !popoverContent?.contains(event.target)) {fillterShow.value = false}
}
</script>
<style lang="scss" scoped>
.box {margin: 16px;background-color: #fff;overflow: auto;height: 100%;padding: 16px;box-sizing: border-box;.filter-button {display: flex;align-items: center;justify-content: center;width: 64px;height: 32px;line-height: 32px;font-size: 14px;font-weight: 400;color: #008dff;cursor: pointer;border: 1px solid #008dff;border-radius: 4px;i {margin-left: 5px;font-size: 14px;}}.query-box {:deep(.el-input) {width: 220px;}:deep(.el-select) {width: 220px;}}.form-button {display: flex;align-items: center;justify-content: flex-end;width: 100%;}
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/92441.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/92441.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/92441.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python每日一题 贪心算法练习

在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。给定两个整数数组 gas 和 cost &…

Python + Pika RabbitMQ集群压测完整方案

一、最近搭建了个rabbitmq集群 三个磁盘节点&#xff0c;上生产环境之前想做个压测&#xff0c;测试下稳定性&#xff0c;参考Deepseek做了如下测试方案二、核心代码实现&#xff1a; 配置文件 (config.py) import os RABBITMQ_NODES [amqp://admin:123456192.168.0.175:8101,…

【第7话:相机模型3】自动驾驶IPM图像投影拼接技术详解及代码示例

IPM图像投影拼接技术详解 IPM&#xff08;逆透视映射&#xff09;图像投影拼接技术是一种在计算机视觉中广泛应用的图像处理方法&#xff0c;主要用于将多个透视视图的图像转换为鸟瞰视图并拼接成一个无缝的大场景图像。该技术特别适用于自动驾驶、机器人导航和监控系统等领域&…

【测试工程思考】测试自动化基础能力建设

1 回顾 传统软件研发体系下定义的软件测试是从用户视角设计的。测试是试图穷尽用户行为的工程&#xff0c;从测试用例&#xff08;use case&#xff09;的英文定义就可见一般。测试的逻辑资产就是用自然语言去描述用户的操作行为或路径。 但随着软件工程向分布式架构和敏捷交付…

进阶向:AI聊天机器人(NLP+DeepSeek API)

什么是AI聊天机器人? AI聊天机器人是一种通过自然语言处理(NLP)技术模拟人类对话的智能程序系统。其核心是建立在机器学习算法和大型语言模型基础上的对话引擎,能够理解用户的自然语言输入,分析语境和意图,并生成符合上下文的相关回复。 这类机器人系统通常包含以下几个…

一个C#的段子

猜猜按钮的结果是啥。 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } public static bool flag true; privat…

使用 gptqmodel 量化 Qwen3-Coder-30B-A3B-Instruct

代码部分 : quantize_qwen3_coder_30b_a3b_instruct_gptq.py import os########## 环境变量设置 ########## # 当前可用的 CUDA 编号 os.environ["CUDA_VISIBLE_DEVICES"] "1" # GPU 显存资源片段优化 os.environ["PYTORCH_CUDA_ALLOC_CONF"] …

基于python、django的疫苗接种管理系统

基于python、django的疫苗接种管理系统

Go语言实战案例:使用sync.Map构建线程安全map

在并发编程中&#xff0c;共享资源的访问是一个绕不开的问题。Go 中的 map 在并发读写时是不安全的&#xff0c;直接使用可能导致程序 panic。因此&#xff0c;在多协程同时访问 Map 的场景下&#xff0c;必须采取有效的同步措施。本篇将通过一个实战案例&#xff0c;介绍 Go 的…

关于vue2中对接海康摄像头以及直播流rtsp或rtmp,后台ffmpeg转码后通过ws实现

最近项目中需要对接摄像头监控&#xff0c;海康摄像头为rtsp流格式有一个软件VLC media player&#xff0c;可以在线进行rtsp或者rtmp流播放&#xff0c;可用来测试流地址是否可用功能实现思路为后台通过fmpeg把rtsp流进行转码&#xff0c;然后通过ws方式进行一帧一帧推送。&am…

Docker容器强制删除及文件系统修复完整指南

Docker容器强制删除及文件系统修复完整指南 故障现象与原因分析 ​故障表现​&#xff1a; ERROR: for c9ca40be974d_OpIsosMD_OB unable to remove filesystem unlinkat /data/docker/storage/containers/c9ca40be974d...: structure needs cleaning​根本原因​&#xff1a;…

Matplotlib 知识点总结

1. 基础绘图&#xff08;plot函数&#xff09;基本语法&#xff1a;plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)功能特点&#xff1a;可绘制点、线和组合图形自动生成x轴&#xff08;0-N-1&#xff09;当x未指定时示例&#xff1a;绘制两点连线、多点不规则线等代码…

高可用微服务架构实战:Nacos集群+Nginx负载均衡,Spring Cloud无缝对接

"当你的注册中心挂了&#xff0c;整个微服务就变成了无头苍蝇。" 这是我在生产环境踩坑后最痛的领悟。今天&#xff0c;我将分享如何用Nacos集群Nginx搭建坚如磐石的注册中心&#xff0c;让你的微服务永不迷路&#xff01; 在 Windows 环境下配置 Nacos 集群&#x…

Spark大数据处理实战指南

Spark 简介 Apache Spark 是一个开源的分布式计算框架,专为大规模数据处理而设计。它通过内存计算和优化的执行引擎显著提升了数据处理速度,适用于批处理、实时流处理、机器学习和图计算等场景。 核心特性 高性能:利用内存计算(In-Memory Processing)减少磁盘 I/O,比传…

浏览器缓存机制全解析:强缓存与协商缓存

浏览器缓存是浏览器为提升页面加载速度、减少服务器压力和节省网络带宽&#xff0c;在本地存储资源&#xff08;如 HTML、CSS、JS、图片等&#xff09;的机制。其核心分为强缓存和协商缓存&#xff0c;并涉及多种 HTTP 头字段和存储位置。以下是详细解析&#xff1a;⚙️ 一、缓…

知识随记-----Qt 实用技巧:自定义倒计时按钮防止用户频繁点击

Qt 技巧&#xff1a;实现自定义倒计时按钮防止用户频繁点击注册 项目场景 在一个基于 Qt 开发的聊天应用中&#xff0c;用户注册时需要获取验证码。为防止用户频繁点击获取验证码按钮&#xff0c;需要实现一个倒计时功能&#xff0c;用户点击后按钮进入倒计时状态&#xff0c;倒…

Linux与Windows应急响应

本人首先进行了linux的应急响应&#xff0c;windows之后再进行 Linux与Windows应急响应初体验1 linux应急响应1.1 账户&#xff1a;1.1.1 使用cat /etc/passwd命令查看passwd文件2.1.2 使用cat /etc/shadow命令查找shadow文件&#xff0c;该文件为密码文件的存储项1.2 入侵排查…

计算机网络1-4:计算机网络的定义和分类

目录 计算机网络的定义 计算机网络的分类 计算机网络的定义 计算机网络的分类 按交换技术分类&#xff1a;电路交换网络、报文交换网络、分组交换网络 按使用者分类&#xff1a;公用网、专用网 按传输介质分类&#xff1a;有线网络、无线网络 按覆盖范围分类&#xff1a;…

在QT中动态添加/删除控件,伸缩因子该怎么处理

开发中遇到的问题[TOC](开发中遇到的问题)处理方式在我们的界面开发过程中&#xff0c;通常需要开发一些可以动态添加or删除控件的容器&#xff0c;类似Tab页一样&#xff0c;为了美观的话&#xff0c;我们通常使用伸缩因子将容器中的控件往一个方向挤&#xff0c;类似下面的控…

【设计模式精解】什么是代理模式?彻底理解静态代理和动态代理

目录 静态代理 动态代理 JDK动态代理 CGLIB代理 JDK动态代理和CGLIB代理的区别 总结 代理模式简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问&#xff0c;这样就可以在不修改原目标对象的前提下&#xff0c;扩展目标对象的功能。 代理模式有静态代理…