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

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

时间:2024-06-18 17:32:18浏览次数:27  
标签:个人头像 const text value 弹框 头像 ref

实现效果:

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

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

 

实现方式: 

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;
		}
	}

标签:个人头像,const,text,value,弹框,头像,ref
From: https://blog.csdn.net/weixin_43312391/article/details/139778855

相关文章

  • springboot + uniapp 头像上传功能及样式模版
    springboot+uniapp头像上传和预览功能及样式模版该头像上传使用uni.chooseImage方法从本地相册选择图片或使用相机拍照。再通过uni.uploadFile将本地资源上传到服务器。具体使用方法请参考uniapp官网API。以下是前端效果图:上传之后效果点击头像预览效果......
  • unicloud持久化小程序获取的临时微信头像url路径(教程)
    自2022年10月25日后,用户头像昵称获取规则作了调整:getUserInfo接口获取用户头像将统一返回默认灰色头像,昵称将统一返回“微信用户”。如业务需获取用户头像昵称,可以使用「头像昵称填写能力」头像选择需要将 button 组件 open-type 的值设置为 chooseAvatar,当用......
  • vue 弹框共用
    1.以本人项目为例修改新增使用同一个模态框<el-buttontype="warning"@click="AddCategory">新增一级分类目录</el-button><Dialogref="myDialog"@updateViews="updateViews":input="input":cid="cid"></Dia......
  • minio的一个基础使用案例:用户头像上传
    文章目录一、minio下载安装(Windows)二、案例需求分析三、后端接口开发一、minio下载安装(Windows)1.下载minio服务端和客户端minio下载地址2.手动搭建目录/minio/binmc.exeminio.exe/data/logs手动创建minio应用程序目录,如......
  • SpringBoot实现上传头像(查看头像)
    SpringBoot实现上传头像给功能和查看头像功能文章目录目录文章目录1.上传头像1.这里的AppConfig记得定义一下 2.引入AppConfig3.上传文件代码 2.获取头像 1.实现readFile方法1.上传头像首先我的代码中在application.properties中设置了上传文件的根目录......
  • 微信小程序加载、更新和生命周期、分享、转发、获取头像、获取昵称、手机号、客服功能
    【上拉下拉加载】1后端和路飞项目的课程表相对应234-----wxml-------567<viewwx:for="{{goods}}"wx:key="index">{{item.name}}</view>8910------js-----------111213Page({14data:{15page:1,16goods:[]......
  • el-dialog嵌套时内部弹框遮罩层的问题
    Copyright©1999-2020,CSDN.NET,AllRightsReserved打开APP沙雕在人间关注el-dialog遮罩层的问题原创2021-08-3011:11:15阅读量8.1kAI必读沙雕在人间码龄6年关注在一个el-dialog中点击再出现一个el-dialog时会出现一个遮罩层的问题在这里插入图片......
  • Ai+姓氏头像壁纸项目,含直播搭建教程
    1.前言小伙伴们大家好,欢迎来到天夏Ai,这里专注于分享人工智能精品资源:Ai副业项目、Ai效率神器!和你一起共享Ai信息,分享Ai副业项目资源,开启智能副业赚钱新时代!今天为大家带来Ai+姓氏头像壁纸项目,拒绝割韭菜,只讲干货!下方数据可以看到,人们对头像壁纸的需求量还是很大的......
  • 用ESP8266-NodeMCU开发板显示一下我的QQ头像
    诶,说好的自己写esp8266的开发板固件的我回来了。20年说好的,今天回来还愿了ESP8266串口WiFi模块-WiFi杀手今天我们把OLED显示屏也接上,我此次买的是4脚的OLED(128*64),不支持彩色显示的。NodeMCU开发板NodeMCU是一个开源的IoT物联网硬件开发板,由于它支持WIFI功能且使用方法十......
  • 关于Vue弹框组件this.$confirm
    确定后不能刷新页面列表show_tank(record){varthat=thisthis.$confirm({title:'您确定要选择吗?',content:'选择后不可修改',closable:true,//是否显示右上角的xmaskClosable:true,//触发阴影层的点击......