Vue3鼠标悬浮个人头像时出现修改头像,点击出现弹框,上传头像使用cropperjs可裁剪预览

news2024/10/7 4:26:25

实现效果:

鼠标悬浮到头像上,下方出现修改头像

点击修改头像出现弹框,弹框中可上传头像,并支持头像的裁剪及预览

 

实现方式: 

1.tempalte中

<div class="img-box">
				<img v-if="avatarImgUrl" :src="avatarImgUrl" class="avatar" />
				<div class="text" @click="toFixImg()">修改头像</div>
			</div>

注意:用服务端做渲染的同学v-if="avatarImgUrl"必须添加,不然会因水合作用图片出现问题。

<el-dialog
			v-model="dialogVisible"
			title="修改图片"
			width="700"
			@close="cancelFixAvatar"
			:close-on-click-modal="false"
		>
			<input
				type="file"
				accept="image/*"
				@change="onFileChange"
				id="myFileInput"
				style="display: none"
				ref="fileInput"
			/>
			<!-- 触发文件选择的按钮 -->
			<button type="button" class="change-img" @click="triggerFileInput">
				选择图片
			</button>
			<!-- 图片裁剪区域 -->
			<div v-if="imageUrl" class="cropper-img">
				<vue-cropper
					:key="imageKey"
					ref="cropper"
					:src="imageUrl"
					style="width: 300px; height: 300px"
					:options="cropperOptions"
				/>
				<div @click="cropImage" class="confirm-btn">点击预览</div>
				<!-- 显示裁剪后的图片(可选) -->
				<div v-if="croppedImageUrl" class="cropped">
					<img
						:src="croppedImageUrl"
						alt="Cropped Image"
						style="width: 200px; height: 200px; border-radius: 50%"
					/>
				</div>
			</div>
			<template #footer>
				<div class="dialog-footer">
					<el-button @click="cancelFixAvatar">取消</el-button>
					<el-button type="primary" @click="fixAvatar"> 确定 </el-button>
				</div>
			</template>
		</el-dialog>

以上为点击修改头像出现的弹框,实现裁剪图片主要使用的是cropperjs插件,需先安装此插件。

npm install cropperjs --save

2.script中 

引入相关文件及定义变量

import 'cropperjs/dist/cropper.css';
import VueCropper from 'vue-cropperjs';
const dialogVisible = ref(false);
const avatarImgUrl = ref('');
const imageUrl = ref('');
const croppedImageUrl = ref('');
const cropperOptions = ref({
	aspectRatio: 1, // 设置裁剪框的比例
	viewMode: 1, // 限制图片的拖动范围
	// ...其他选项
});
const token = ref('');
const croppedImg = ref('');
const imageKey = ref(0); // 使用 key 来强制重新渲染
const cropper = ref(null);

定义使用的相关方法


// 点击“修改头像”
const toFixImg = () => {
	dialogVisible.value = true;
	nextTick(() => {
		document
			.getElementById('myFileInput')
			.addEventListener('change', onFileChange);
	});
};


// 监听上传的头像变化
const onFileChange = (e) => {
	const file = e.target.files[0];
	if (!file) return;
	const reader = new FileReader();
	reader.onload = (e) => {
		imageUrl.value = e.target.result;
		imageKey.value += 1;
	};
	reader.readAsDataURL(file);
};
// 再次点击“选择图片”替换
const triggerFileInput = () => {
	fileInput.value.click();
};
// 裁剪图片
const cropImage = () => {
	cropper.value.getCroppedCanvas().toBlob((blob) => {
		croppedImageUrl.value = URL.createObjectURL(blob);
		let file = new File([blob], 'test.png', { type: blob.type });
		// 这里添加将blob发送到服务器的逻辑,根据个人情况,此处调用的后端接口
		const formData = new FormData();
		formData.append('files', file);
		formData.append('folder', 'avatarArr');
		let uploadFileRequest = new Request(
			config.public.baseUrl +
				'xxxx',
			{
				method: 'post',
				headers: {
					Authorization: token.value,
				},
				body: formData,
			},
		);
		fetch(uploadFileRequest).then((response) => {
			let result = response.text();
			result.then((res) => {
				const resdata = JSON.parse(res);
				if (resdata.code == 200) {
					croppedImg.value = resdata.data[0].fileAddr;
				}
			});
		});
	}, 'image/jpeg');
};
// 修改头像弹框的确定按钮
const fixAvatar = () => {
	if (!croppedImg.value || croppedImg.value == '') {
		ElMessage({
			message: '请预览效果后点击保存',
			type: 'warning',
			customClass: 'mzindex',
		});
		return;
	}
// 此处调用后端提供的保存接口
	
};
// 修改弹框的取消按钮
const cancelFixAvatar = () => {
	imageUrl.value = '';
	croppedImageUrl.value = '';
	imageKey.value = 0;
	dialogVisible.value = false;
};


// 监听头像的改变
watch(
	() => store.fetchImage(),
	(newVal) => {
		if (newVal) {
			avatarImgUrl.value = `${config.public.baseUrl}/digit-trade-platform-system/file/${newVal}`;
		}
	},
	{ immediate: true },
	{ deep: true },
);

3.style中

.img-box {
			position: relative;
			display: inline-block;
			width: 100px; /* 或者你需要的大小 */
			height: 100px; /* 和宽度相同,形成圆形 */
			.avatar {
				width: 100%;
				height: 100%;
				object-fit: cover;
				border-radius: 50%;
				cursor: pointer;
			}
            .icon{
                position: absolute;
                bottom: 0;
                right: 0;
            }
			.text {
				position: absolute;
				bottom: 0; /* 文本定位在底部 */
				left: 50%; /* 水平居中 */
				width: 60%;
				padding: 5px 0;
				transform: translateX(-50%); /* 文本水平居中 */
				background-color: rgba(0, 0, 0, 0.5); /* 半透明背景 */
				color: white;
				text-align: center;
				border-radius: 0 0 50% 50% / 50%; /* 底部平直的圆角 */
				opacity: 0;
				transition: opacity 0.3s ease; /* 添加过渡效果 */
				font-size: 11px;
				cursor: pointer;
			}
			/* 鼠标悬浮在头像上时显示文本 */
			.avatar:hover + .text,
			.text:hover {
				opacity: 1; /* 鼠标悬浮时显示文本 */
			}
		}



.change-img {
		background-color: $mainColor; /* Green */
		border: none;
		color: white;
		text-align: center;
		text-decoration: none;
		display: inline-block;
		font-size: 16px;
		margin: 4px 2px;
		cursor: pointer;
		border-radius: 4px;
		width: 100px;
		height: 40px;
		line-height: 40px;
	}
	.cropper-img {
		width: 100%;
		margin: 20px 0;
		display: flex;
		.confirm-btn {
			margin: 140px 20px 0 20px;
			width: 100px;
			height: 36px;
			background-color: $mainColor;
			color: #fff;
			text-align: center;
			line-height: 36px;
			border-radius: 4px;
			cursor: pointer;
		}
		.cropped {
			margin-top: 60px;
		}
	}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开始报名啦!智能可观测运维技术 MeetUp 议题硬核来袭

「龙蜥社区“走进系列”MeetUp」是由龙蜥社区与生态合作伙伴联合主办的系列月度活动&#xff0c;每期走进一家企业&#xff0c;聚焦龙蜥社区和合作伙伴的技术、产品和创新动态&#xff0c;展示硬核技术&#xff0c;共建繁荣生态。 龙蜥社区“走进系列”第 11 期走进中兴通讯-智…

【Axure高保真原型】动态统计中继器表格项目数

今天和大家分享动态统计中继器表格项目数的原型模板&#xff0c;具体包括以下功能&#xff1a; 表格下方可以自动根据表格内容统计表格的总项目数、启用和禁用数、选中和未选中数 我们可以点击开发切换启用和禁用 点击多选按钮&#xff0c;选中或取消选中对应行内容 选中后可…

关于Markdown的使用与创建

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

《收获,不止oracle》读书笔记一:oracle体系结构

从图中可以看出,oracle数据库是由实例和一组数据库文件组成。实例是由oracle开辟的内存区和一组后台进程组成的。

【多线程】线程状态

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 枚举线程所有状态2. 线程转移2.1 示意图2.2 观察 NEW 、 RUNNABLE 、 TERMINATED 状态的转换2.3 观察 WAI…

fastsam-pytorch基于YOLACT方法的实例分割分支的目标检测器模型

FastSAM 论文 Fast Segment Anything 模型结构 以yolov8-seg的instance segmentation为基础&#xff0c;检测时集成instance segmentation分支,主要分为两步全实例分割(all instance Segmentation)和基于prompt的mask输出(Prompt-guided Selection)&#xff0c;仅使用了2%的…

采用了宽电压设计的测径仪为什么仍旧需要到现场勘察电力环境

关键字: 测径仪宽电压设计,测径仪电压范围,电压影响测径仪,测径仪车间电压 设备宽电压设计是指该设备能够在一定范围的电压波动内正常工作&#xff0c;而不会因为电压的轻微变化而导致性能下降或损坏。宽电压设计通常涉及到电源电路的优化和设计&#xff0c;以确保设备在电压波…

POSIX信号量以及读写者模型/环形队列

POSIX信号量 POSIX信号量和SystemV信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步,他的本质是一个计数器,对共享资源进行等待或释放 POSIX信号量的重要概念 1.计数器:信号量维护一个计数器&#xff0c;它…

AI大佬都在说下一个爆点是智能体,建议开发者抢占先机!

现在大模型行至一年&#xff0c;风口与炒作如影随形&#xff0c;相信很多人身处其中但仍然感到很迷失&#xff0c;这个行业到底发展到什么程度了&#xff0c;作为普通开发者还有什么可以抓住的机会&#xff1f;从AI大佬的观点中&#xff0c;我们能获得一些行业变化的新风向。 …

corona渲染器与vray比哪个好?支持云渲染平台吗

​在视觉渲染技术领域&#xff0c;V-Ray和Corona都以其卓越的性能和广泛应用赢得了高度评价。这两款渲染器各有其独特的优势&#xff0c;使得在它们之间做出选择并非易事。不同的应用场景和用户需求可能会让它们各自展现出不同的优势。 一、corona渲染器跟vray怎么样 在比较V-…

Paragon NTFS For Mac 15软件下载_Paragon NTFS For Mac 15官网最新版下载

Paragon NTFS For Mac 15是一款强大的Mac读写工具。paragon ​​ntfs for mac​​​中文版为您轻松解决Mac不能识别 Windows NTFS文件难题&#xff0c;简单自如读写NTFS外置存储文件。在Mac OS X下全读/写访问NTFS的任何分区&#xff0c;paragon ntfs for mac中文版实现在Windo…

java 面试题--基础

文章目录 基础java SE 、 EE 、 ME 的区别jdk 和 jre 区别&#xff1f;java 的日志级别基本数据类型 特性关键字finalabstractsuperswitchfortry catch 接口和抽象类的区别接口抽象类适用场景 类的加载循序静态代码块 传参问题访问修饰符运算符 反射java 里的应用为什么反射的性…

Cascadia Code 字体

维护一个很老的程序&#xff0c;打开了尘封已久的 Visual Studio 2010&#xff0c;默认的字体看着非常不舒服&#xff0c;于是更换了一下字体。当尝试更换成 Cascadia Code 字体之后&#xff0c;一下子舒服了。 之前比较习惯 Consolas 字体&#xff0c;以后记住了&#xff0c;C…

音乐管理系统 SpringBoot + vue

文章目录 1、简要介绍2、数据库设计3、解决的问题1、图片和音频的上传和存储2、分页功能 4、数据返回 也算是进行了半个学期&#xff0c;跟着老师讲的进行 后端使用SpringBoot 前端 vue layui jdk 18 项目地址&#xff1a;gitee 1、简要介绍 只有管理端&#xff0c;但是对用…

俄罗斯ozon爆款推荐丨ozon学生受众产品

在俄罗斯电商平台OZON上&#xff0c;学生受众是一个庞大且活跃的群体。为了满足他们的需求&#xff0c;OZON平台上涌现出了一系列受学生欢迎的爆款产品。以下是一些针对学生受众的OZON爆款推荐&#xff1a; OZON选品工具&#xff1a;D。DDqbt。COM/74rD Top1 UNO纸牌游戏 俄语…

线程本地化存储如何保证线程安全

线程本地化存储如何保证线程安全 1、背景2、详细分析1、背景 在并发编程中,可能最害怕听到一个词就是线程不安全。因为它意味着程序运行的时候,可能出现数据的读取或写入不准确等情况发生, 2、详细分析 可能对于每个工程师来说都不陌生,就是我们工作中常见的一个环节,…

图片怎么弄成黑白的?关于将图片改成黑白的几种方法

图片怎么弄成黑白的&#xff1f;黑白照片以其独特的艺术魅力和经典的视觉效果&#xff0c;依然在摄影和图像处理中占据重要地位。无论是为了追求怀旧的氛围&#xff0c;还是为了突出图像的构图和光影效果&#xff0c;许多人都希望将彩色图片转换成黑白图片。这不仅可以赋予图像…

Tomcat Websocket应用实例研究

概述 本文介绍了如何根据Tomcat给出的websocket实例&#xff0c;通过对实例的学习&#xff0c;定制自己基于websocket的应用。 环境及版本&#xff1a; Ubuntu 22.04.4 LTSApache Tomcat/10.1.20openjdk 11.0.23 2024-04-16浏览器&#xff1a;Chrome 相关资源及链接 Class…

大模型精调:实现高效迁移学习的艺术

在人工智能领域&#xff0c;大型预训练模型&#xff08;以下简称“大模型”&#xff09;已经取得了令人瞩目的成果。这些模型通过在海量数据上进行预训练&#xff0c;能够捕捉到丰富的特征信息&#xff0c;为各种下游任务提供强大的支持。然而&#xff0c;如何将这些大模型应用…

如何用Vue3打造一个炫酷的树状图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 基于 Vue.js 的 Treemap 可视化组件 应用场景介绍 Treemap 可视化组件是一种强大的工具&#xff0c;用于以直观的方式展示分层数据。它将数据点绘制为矩形&#xff0c;其中每个矩形的大小与数据点的大小成正比…