[element plus] 对话框组件再封装使用 - vue
学习关键语句:
饿了么组件dialog组件使用
dialog组件二次封装
vue3中封住的组件使用update触发更新
vue3中封装组件使用v-model:属性值来传值
写在前面
这是我遇到的一个页面需求 , 其中一个对话框的内容是很常用的 , 所以我将它封装出来才写的一篇文章
现在给出如下需求:
封装一个组件 , 要求每次选择用户的时候 , 能从组件返回选择的用户id数组
并且能在选择用户是看到选择了哪些用户
- 如果你只是想看如何封装组件 , 请根据目录点击 ‘封装对话框组件’ 这个内容
文章末尾附带本文项目文件链接
开始
提示 : 本项目使用 vite 创建的 vue3 项目 , 使用 express 创建的后端
创建项目文件夹
随意新建一个文件夹 , 起名为 test , 在该文件夹下 , 再新建一个文件夹为 server

开启终端 , 输入创建项目命令
npm create vite
依次输入项目名称 dialog , 框架选择 Vue , 语言选择 typescript

创建完成后 , 根据提示 输入提示的命令
cd dialog
npm install
npm run dev

点击打开最后这个网址就完成了项目最初的创建
现在我们来创建后端服务器
打开终端 , 进入 server 文件夹 , 输入以下命令
npm init

测试使用 , 全部按回车默认过去就OK了
命令行中安装依赖
npm install
同时我们再创建一个文件 起名为 app.js
全部创建完后的目录如下

安装库和配置
现在需要在前端和后端中各安装需要的库
其中 , 前端需要安装 elementUI 和 axios
后端需要安装 express , cors , body-parser 和 connect-multiparty
注意 安装依赖前请确定在对的终端下 , 不可下错了位置
后端
优先进行后端的配置
- 安装 express 制作服务器
npm install express --save
- 安装 cors 解决跨域
npm install cors --save
- 引入中间件解决读取参数问题
npm install body-parser --save
npm install connect-multiparty --save
配置完成之后我们来写服务器文件 app.js
app.js
// 导入 express
const express = require('express')
// 创建 app
const app = express()
// 设置跨域访问
const cors = require('cors')
app.use(cors())
// 处理POST参数
const bodyParser = require('body-parser')
const multiparty = require('connect-multiparty')
// 处理 x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended:true
}));
// 处理 application/json
app.use(bodyParser.json())
// 处理 mutipart/form-data
app.use(multiparty())// 测试接口能否正常调用
app.get('/hello', (req, res) => {res.send("Hello shaoyahu !")
})// 我们写一个获取用户信息的接口
// 模拟数据库中的用户数据
let db = [{ id: 1, name: '张一' },{ id: 2, name: '张二' },{ id: 3, name: '张三' },{ id: 4, name: '熊大' },{ id: 5, name: '熊二' },{ id: 6, name: '熊三' },{ id: 7, name: '李三' },{ id: 8, name: '李四' },
]
app.post('/getUserData', (req, res) => {let txt = req.body.namelet data = db.filter(item => {return item.name.includes(txt)})res.send({status: 200,data,msg: '获取成功'})
})// 启动
app.listen(3000, () => {console.log('express server running at http://127.0.0.1:' + 3000);
})
写好服务器文件后在终端输入如下命令启动服务器
node app.js
当控制台打印出我们设置的语句时表示服务器已经启动成功

现在简单测试一下调用接口
在浏览器中输入
http://localhost:3000/hello
如果出现 Hello shaoyahu ! 就说明接口调用成功了

那么后端先写到这里 , 我们现在来看前端
前端
- 安装element plus
npm install element-plus --save
安装完毕后打开 main.ts 文件进行引入和挂载
import { createApp } from 'vue'
import ElementPlus from 'element-plus' // 加入
import 'element-plus/dist/index.css' // 加入
import App from './App.vue'const app = createApp(App) // 修改
app.use(ElementPlus) // 修改
app.mount('#app') // 修改
这样就能使用饿了么的组件了
- 安装 axios
npm install axios --save
在 src 目录下新建文件 axios.ts
axios.ts
进行简单的封装 , 不添加拦截器
import axios from 'axios'const service = axios.create({// 根据刚才的后端地址和端口配置写出请求基础路径baseURL: 'http://localhost:3000'
})export default service
在 src 目录下新建文件夹起名 api
在 api 文件夹中新建文件起名为 user.ts
user.ts
专门存放和用户有关的接口请求
我们写一个获取用户信息的请求
import axios from '../axios'// 获取用户信息
export function getUserData(data: { name: string }){return axios.post('/getUserData', data)
}
axios 相关的操作完成后目录结构如下图

编写页面内容
我们将 App.vue 页面的内容清空 , 写入一个简单的提示词 , 输入框和按钮
App.vue
<template><div class="index"><span>选中的用户</span><el-input v-model="searchTxt" type="textarea"style="width: 220px;" disabled :placeholder="'请选择用户'" /><el-button @click="toSelectPerson">选择用户</el-button></div>
</template><script setup lang='ts'>
import { ref } from "vue";
let searchTxt = ref('')
const toSelectPerson = () => {}
</script>

我们的逻辑是 , 点击选择用户按钮 , 打开一个对话框 , 在对话框中我们选择好需要的用户后关闭对话框 , 将在对话框中选中的用户在输入框中展现
那么 , 由于这个选择人物的对话框会在多处使用到 , 所以我们现在就来封装一个对话框组件吧
封装对话框组件
我们在 src 下的 components 文件夹中新建文件 起名为 myDialog.vue
myDialog.vue
需要注意的点如下
- 开启关闭对话框的方法必须使用 v-model: 来给属性值
- 饿了么组件的对话框原始的 v-model 需要修改成 :model-value 才不会报错
- 这个文件里的样式我没写在下方 , 但是末尾文件中会有样式
- 通过点击遮罩层关闭掉对话框的方式虽然可以关闭对话框 , 但实际上传入的值仍然为 true , 解决方法有两个 , 第一个是通用的 , 将打开对话框和关闭对话框的方法写在组件上 , 通过操控组件来打开和关闭对话框 , 第二个办法则是参考了饿了么组件提供的一个属性 before-close , 在这个属性中 , 我们手动 emit 传入的值修改为 false 就可以了
<template><el-dialog :model-value="props.selectUserShow":title="props.title" :width="props.width":draggable="drag" :before-close="beforeClose"><slot><div><span>搜索 : </span><el-input v-model="searchTxt" :placeholder="'输入关键词'"><template #append><el-button @click="searchPerson">查询</el-button></template></el-input><div><div><span>选择用户</span></div><div><div v-for="item, index in data" :key="index" style="margin: 20px;"><el-checkbox v-model="item.checked" :label="item.name" size="large" @change="select(item)" /></div></div><div><span>已选择用户</span><div>{{ selectedTxt }}</div></div></div></div></slot><template #footer><span><el-button type="primary" @click="emit('confirm', selectedData)">确定</el-button><el-button @click="emit('update:selectUserShow', false)">取消</el-button></span></template></el-dialog>
</template><script setup lang='ts'>
import { computed, ref } from 'vue'
import { getUserData } from '../api/user.js'
export interface IData {id: number,name: string,checked?: boolean
}
const props = defineProps({// 控制组件的显示与隐藏selectUserShow: {type: Boolean,default: false,required: true},// 传进来的已经选择了的用户数组selectUserList: {type: Array<IData>,default: [],required: true},title: {type: String,default: ''},width: {type: String,default: '80%'},drag: {type: Boolean,default: true}
})
const emit = defineEmits(['confirm', 'update:selectUserShow'])
// 查询用户的关键词
let searchTxt = ref('')
// 查询结果数据
let data = ref<IData[]>([])
// 已经选择的数据数组
let selectedData = ref<IData[]>(props.selectUserList)
let selectedTxt = computed(() => {let t = ''selectedData.value.map((item: IData) => {t += `${item.name} , `})t = t.substring(0, t.length - 2)return t
})
// 查询用户
const searchPerson = () => {getUserData({ name: searchTxt.value }).then((res: any) => {data.value = res.data.dataaddSelectedStatus(data.value)})
}
// 选择用户
const select = (obj: IData) => {if (obj.checked) {selectedData.value.push(obj)} else {selectedData.value = selectedData.value.filter((item: IData) => {return item.id !== obj.id})}
}
// 给所有人添加选中状态
// 需要判断查询出来的用户中是否已经有被选中的用户
function addSelectedStatus(data: IData[]) {data.forEach((item: any) => {let flag = selectedData.value.some((item2: IData) => {return item2.id === item.id})if (flag) {item.checked = true} else {item.checked = false}})
}
// 关闭对话框之前
const beforeClose = (done: Function) => {emit('update:selectUserShow', false)done()
}
searchPerson()
// 导出搜索用户的方法 , 是为了防止一个页面多个查询用户共用一个组件导致已选中的打开无法显示已选中的情况出现 , 使用方法为在打开组件时调用这个方法
defineExpose({searchPerson
})
</script>
这样一个对话框组件就被封装完成了 , 但是由于添加了很多属性和内容 , 所以定制度是比较高的 , 我将所有默认的内容都放在了默认插槽中 , 如果需要另一个对话框的话可以使用插槽覆盖掉原有的内容 , 不过还是建议重新封装一个
补完页面
对话框组件已经封装好了 , 现在我们回头去使用这个组件
App.vue
<template><div class="index"><span>选中的用户</span><el-input v-model="userTxt" type="textarea" style="width:220px" disabled :placeholder="'请选择用户'" /><el-button @click="toSelectPerson">选择用户</el-button></div>{{ selectUserList }}<myDialog v-model:selectUserShow="selectUserShow" :selectUserList="selectUserList" @confirm="confirmUser"></myDialog>
</template><script setup lang='ts'>
import { ref } from "vue";
import myDialog, { IData } from './components/myDialog.vue'let userTxt = ref('')
let selectUserShow = ref(false)const toSelectPerson = () => {selectUserShow.value = true
}
let selectUserList = ref<IData[]>([])
const confirmUser = (selectedData: IData[]) => {userTxt.value = ''selectUserShow.value = falseselectUserList.value = selectedDataselectUserList.value.map((item: IData) => {userTxt.value += `${item.name} , `})userTxt.value = userTxt.value.substring(0, userTxt.value.length - 2)
}
</script>

结束
就这样这个组件就完成了 , 不过不是很建议大家使用传入值来控制组件的显示和隐藏 , 推荐还是使用组件 expose 出的方法来操作
文件链接
最后附上文件链接
https://download.csdn.net/download/shaoyahu/87477013
相关文章:
[element plus] 对话框组件再封装使用 - vue
学习关键语句: 饿了么组件dialog组件使用 dialog组件二次封装 vue3中封住的组件使用update触发更新 vue3中封装组件使用v-model:属性值来传值 写在前面 这是我遇到的一个页面需求 , 其中一个对话框的内容是很常用的 , 所以我将它封装出来才写的一篇文章 现在给出如下需求: 封…...
Markdown基本语法简介
前言:当你在git平台创建一个仓库时,平台会自动创建一个README.md文件,并将它的内容展现在web端页面,方面其他读者查阅。README.md实则是一个适用Markdown语法的文本文件,从他的后缀md即可看出它是Markdown的缩写。在gi…...
分布式服务的接口幂等性如何设计
1.1 概述 所谓幂等: 多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致。 基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析 举个例子: 假如你有个某多多 有个服务 服务提供一个接口,结果这个服务部署在…...
视频流截取保存到本地路径(打包jar包CMD运行)
需求:现在有一批https的监控视频流URL,需要对视频流进行每三秒截屏一次,并保存到本地路径,png格式,以当前时间命名。代码:import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Fra…...
mysql索引失效的几种情况
失效的几种情况 1、select * from xxx 2、索引列上有计算 3、索引列上有函数 4、like左边包含‘%’ 5、使用or关键字 6、not in和not exists 7、order by 8、不满足最左匹配原则 给code、age和name这3个字段建好联合索引:idx_code_age_name。 该索引字段的顺…...
Windows下载安装Redis的详细步骤
目录 一、概述 1.redis的版本维护介绍 2.msi安装包和压缩包的优点和缺点 二、操作步骤 三、测试是否安装成功(查看版本) 四、获取资源 一、概述 1.redis的版本维护介绍 Redis的官网只提供Linux系统的下载。但是微软的技术团队长期开发和维护着这…...
【蓝桥杯每日一题】差分算法
🍎 博客主页:🌙披星戴月的贾维斯 🍎 欢迎关注:👍点赞🍃收藏🔥留言 🍇系列专栏:🌙 蓝桥杯 🌙我与杀戮之中绽放,亦如黎明的花…...
MyBatis Plus 数据库字段加密处理
目录1.场景介绍2.Maven依赖2.AESUtil.java 加解密工具类3.字段处理类4.修改 MyBatis Plus 查询4.1 修改表对应实体类4.2 修改加密字段对应属性4.3 修改 xml 使用 ResultMap4.4 修改 xml 中 el 表达式5.测试结果6.MyBatis Plus 缺陷补充:测试实例1 查询测试1.1 查询信…...
openpose在win下环境配置
1.下载OpenPose库 以下二选一进行下载源码 (1)git进行下载 打开GitHub Desktop或者Powershell git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose cd openpose/ git submodule update --init --recursive --remote(2)在github上手动下载 由于下载环境问…...
【剑指offer-C++】JZ16:数值的整数次方
【剑指offer】JZ16:数值的整数次方题目描述解题思路题目描述 描述:实现函数 double Power(double base, int exponent),求base的exponent次方。 注意: 1.保证base和exponent不同时为0。 2.不得使用库函数,同时不需要…...
了解Axios及其运用方式
Axios简介 axios框架全称(ajax – I/O – system): 基于promise用于浏览器和node.js的http客户端,因此可以使用Promise API 一、axios是干啥的 说到axios我们就不得不说下Ajax。在旧浏览器页面在向服务器请求数据时,…...
【LeetCode】剑指 Offer(7)
目录 写在前面: 题目剑指 Offer 17. 打印从1到最大的n位数 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 题目:剑指 Offer 18. 删除链表的节…...
Python:try except 异常处理整理
目录 一、try except异常处理的语句格式 二、获取相关异常信息 (1)sys.exec_info() 三、traceback模块的常用方式 (1)traceback.print_tb(tb, limitNone, fileNone) 打印指定堆栈异常信息 (2)tracebac…...
Redis Lua脚本的详细介绍以及使用入门
Redis Lua脚本的详细介绍以及使用入门。 文章目录Redis Lua脚本的引入开源软件的可扩展性Redis的扩展性脚本Redis Lua脚本的基本使用通过EVAL命令执行Lua脚本通过脚本与Redis交互Java中调用Redis Lua脚本Java调用Lua脚本的方式Redis Lua脚本的使用建议脚本缓存脚本缓存稳定性脚…...
synchronized和ReentrantLock有什么区别呢?
第15讲 | synchronized和ReentrantLock有什么区别呢? 从今天开始,我们将进入 Java 并发学习阶段。软件并发已经成为现代软件开发的基础能力,而 Java 精心设计的高效并发机制,正是构建大规模应用的基础之一,所以考察并发…...
SVHN数据集下载及使用方法
街景门牌号数据集(SVHN),这是一个现实世界数据集,用于开发目标检测算法。它需要最少的数据预处理过程。它与 MNIST 数据集有些类似,但是有着更多的标注数据(超过 600,000 张图像)。这些数据是从…...
产业安全公开课:2023年DDoS攻击趋势研判与企业防护新思路
2023年,全球数字化正在加速发展,网络安全是数字化发展的重要保障。与此同时,网络威胁日益加剧。其中,DDoS攻击作为网络安全的主要威胁之一,呈现出连年增长的态势,给企业业务稳定带来巨大挑战。2月21日&…...
Docker 容器命令 和安装各种镜像环境
CentOS安装Docker 1.1.卸载(可选) 如果之前安装过旧版本的Docker,可以使用下面命令卸载: yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotat…...
【数据结构】顺序表的深度剖析
🌇个人主页:平凡的小苏 📚学习格言:别人可以拷贝我的模式,但不能拷贝我不断往前的激情 🛸C语言专栏:https://blog.csdn.net/vhhhbb/category_12174730.html 🚀数据结构专栏ÿ…...
当面试官问“你的SQL能力怎么样”时,怎么回答才不会掉进应聘陷阱?
在某平台看到一个比较实际的问题,在这里分享给职场新人。 SQL已经是职场最常用的一种编程语言,所以应聘技术或非技术岗位,都可能会被问道一个问题:你的SQL能力怎么样? 对于职场新人来说(SQL高手可以无视下…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
