当前位置: 首页 > news >正文

[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

注意 安装依赖前请确定在对的终端下 , 不可下错了位置

后端

优先进行后端的配置

  1. 安装 express 制作服务器
npm install express --save
  1. 安装 cors 解决跨域
npm install cors --save
  1. 引入中间件解决读取参数问题
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 ! 就说明接口调用成功了

在这里插入图片描述
那么后端先写到这里 , 我们现在来看前端

前端

  1. 安装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')			// 修改

这样就能使用饿了么的组件了

  1. 安装 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 相关的操作完成后目录结构如下图
![在这里插入图片描述](https://img-blog.csdnimg.cn/9b9d31c0af2d4168a5cf42c2fd02f121.png在这里插入图片描述

编写页面内容

我们将 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基本语法简介

前言&#xff1a;当你在git平台创建一个仓库时&#xff0c;平台会自动创建一个README.md文件&#xff0c;并将它的内容展现在web端页面&#xff0c;方面其他读者查阅。README.md实则是一个适用Markdown语法的文本文件&#xff0c;从他的后缀md即可看出它是Markdown的缩写。在gi…...

分布式服务的接口幂等性如何设计

1.1 概述 所谓幂等: 多次调用方法或者接口不会改变业务状态&#xff0c;可以保证重复调用的结果和单次调用的结果一致。 基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析 举个例子: 假如你有个某多多 有个服务 服务提供一个接口&#xff0c;结果这个服务部署在…...

视频流截取保存到本地路径(打包jar包CMD运行)

需求&#xff1a;现在有一批https的监控视频流URL&#xff0c;需要对视频流进行每三秒截屏一次&#xff0c;并保存到本地路径&#xff0c;png格式&#xff0c;以当前时间命名。代码&#xff1a;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个字段建好联合索引&#xff1a;idx_code_age_name。 该索引字段的顺…...

Windows下载安装Redis的详细步骤

目录 一、概述 1.redis的版本维护介绍 2.msi安装包和压缩包的优点和缺点 二、操作步骤 三、测试是否安装成功&#xff08;查看版本&#xff09; 四、获取资源 一、概述 1.redis的版本维护介绍 Redis的官网只提供Linux系统的下载。但是微软的技术团队长期开发和维护着这…...

【蓝桥杯每日一题】差分算法

&#x1f34e; 博客主页&#xff1a;&#x1f319;披星戴月的贾维斯 &#x1f34e; 欢迎关注&#xff1a;&#x1f44d;点赞&#x1f343;收藏&#x1f525;留言 &#x1f347;系列专栏&#xff1a;&#x1f319; 蓝桥杯 &#x1f319;我与杀戮之中绽放&#xff0c;亦如黎明的花…...

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 缺陷补充&#xff1a;测试实例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&#xff1a;数值的整数次方题目描述解题思路题目描述 描述&#xff1a;实现函数 double Power(double base, int exponent)&#xff0c;求base的exponent次方。 注意&#xff1a; 1.保证base和exponent不同时为0。 2.不得使用库函数&#xff0c;同时不需要…...

了解Axios及其运用方式

Axios简介 axios框架全称&#xff08;ajax – I/O – system&#xff09;&#xff1a; 基于promise用于浏览器和node.js的http客户端&#xff0c;因此可以使用Promise API 一、axios是干啥的 说到axios我们就不得不说下Ajax。在旧浏览器页面在向服务器请求数据时&#xff0c;…...

【LeetCode】剑指 Offer(7)

目录 写在前面&#xff1a; 题目剑指 Offer 17. 打印从1到最大的n位数 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 18. 删除链表的节…...

Python:try except 异常处理整理

目录 一、try except异常处理的语句格式 二、获取相关异常信息 &#xff08;1&#xff09;sys.exec_info() 三、traceback模块的常用方式 &#xff08;1&#xff09;traceback.print_tb(tb, limitNone, fileNone) 打印指定堆栈异常信息 &#xff08;2&#xff09;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有什么区别呢&#xff1f; 从今天开始&#xff0c;我们将进入 Java 并发学习阶段。软件并发已经成为现代软件开发的基础能力&#xff0c;而 Java 精心设计的高效并发机制&#xff0c;正是构建大规模应用的基础之一&#xff0c;所以考察并发…...

SVHN数据集下载及使用方法

街景门牌号数据集&#xff08;SVHN&#xff09;&#xff0c;这是一个现实世界数据集&#xff0c;用于开发目标检测算法。它需要最少的数据预处理过程。它与 MNIST 数据集有些类似&#xff0c;但是有着更多的标注数据&#xff08;超过 600,000 张图像&#xff09;。这些数据是从…...

产业安全公开课:2023年DDoS攻击趋势研判与企业防护新思路

2023年&#xff0c;全球数字化正在加速发展&#xff0c;网络安全是数字化发展的重要保障。与此同时&#xff0c;网络威胁日益加剧。其中&#xff0c;DDoS攻击作为网络安全的主要威胁之一&#xff0c;呈现出连年增长的态势&#xff0c;给企业业务稳定带来巨大挑战。2月21日&…...

Docker 容器命令 和安装各种镜像环境

CentOS安装Docker 1.1.卸载&#xff08;可选&#xff09; 如果之前安装过旧版本的Docker&#xff0c;可以使用下面命令卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotat…...

【数据结构】顺序表的深度剖析

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 &#x1f6f8;C语言专栏&#xff1a;https://blog.csdn.net/vhhhbb/category_12174730.html &#x1f680;数据结构专栏&#xff…...

当面试官问“你的SQL能力怎么样”时,怎么回答才不会掉进应聘陷阱?

在某平台看到一个比较实际的问题&#xff0c;在这里分享给职场新人。 SQL已经是职场最常用的一种编程语言&#xff0c;所以应聘技术或非技术岗位&#xff0c;都可能会被问道一个问题&#xff1a;你的SQL能力怎么样&#xff1f; 对于职场新人来说&#xff08;SQL高手可以无视下…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...