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

vue+element上传图片

一、html页面上传图片

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div><input type="file" id="fileInput" /><img id="imagePreview" src="" alt="Image Preview" /></div>
</body>
</html>
<script>const fileInput = document.getElementById('fileInput');const imagePreview = document.getElementById('imagePreview');fileInput.addEventListener('change', (event) => {// 获取用户选择的第一个文件const file = event.target.files[0]; if (file) {const objectURL = URL.createObjectURL(file); // 创建临时 URLimagePreview.src = objectURL; // 设置为 img 标签的 src}});
</script>

 

二、vue选择图片和上传图片

 

1.:auto-upload="false"取消自动上传,点击上传头像按钮上传

2.:on-change文件上传成功时的钩子,(选择图片后,把图片格式转换为base64格式)

3.点击button按钮和upload组件都可以选择图片

4.上传图片(发送请求更新头像,userStore重新更新数据,给用户提示)

<template><PageContainer title="更换头像"><el-uploadref="uploadRef"class="avatar-uploader":auto-upload="false":show-file-list="false":before-upload="beforeAvatarUpload":on-change="onSelectFile"><img v-if="imageUrl" :src="imageUrl" class="avatar" /><el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon></el-upload><div class="btns"><el-button icon="Plus" type="primary" @click="onSelectFn">选择图片</el-button><el-button icon="Upload" type="success" @click="onUpdateFn">上传头像</el-button></div></PageContainer>
</template>
<script setup>
import { ref } from "vue";
import { ElMessage } from "element-plus";
import { Plus, Upload } from "@element-plus/icons-vue";
import PageContainer from "@/components/PageContainer.vue";
import { updateAvatarApi } from "@/api/user";
import { useUserStore } from "@/store";
//基于store的数据拿到imageUrl的初始值
const userStore = useUserStore();
//图片上传
const imageUrl = ref(userStore.userInfo.user_pic);
const uploadRef = ref();
const beforeAvatarUpload = (rawFile) => {if (rawFile.type !== "image/jpeg") {ElMessage.error("Avatar picture must be JPG format!");return false;} else if (rawFile.size / 1024 / 1024 > 2) {ElMessage.error("Avatar picture size can not exceed 2MB!");return false;}return true;
};
const onSelectFile = (uploadFile) => {//基于fileReader读取图片做预览const reader = new FileReader();// 将文件读入为Data URLreader.readAsDataURL(uploadFile.raw);// 获取Base64字符串reader.onload = () => {imageUrl.value = reader.result;};
};
const onSelectFn = () => {uploadRef.value.$el.querySelector("input").click();
};
const onUpdateFn = async () => {//发送请求更新头像await updateAvatarApi(imageUrl.value);//userStore重新渲染await userStore.getuserInfo();//提示用户ElMessage.success("修改成功");
};
</script>
<style lang="scss">
.avatar-uploader .avatar {width: 178px;height: 178px;display: block;
}
.avatar-uploader .el-upload {border: 1px dashed var(--el-border-color);border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;text-align: center;
}
.btns {margin-top: 20px;
}
</style>

三、表单中上传图片 

 

1.在表单中使用upload组件

2.URL.createObjectURL 是一个在 JavaScript 中用于创建一个指向 BlobFile 对象的临时 URL 的方法。这种方法非常有用,尤其是在处理文件上传或生成动态内容时,比如图像预览。imageUrl.value = URL.createObjectURL(uploadFile.raw);

  1. 生成临时 URL: 它为 BlobFile 对象生成一个可以在浏览器中使用的 URL。这个 URL 是临时的,仅在页面生命周期内有效。

  2. 文件预览: 在用户选择文件后,可以使用这个 URL 显示图像预览。比如,当用户上传一张图片时,可以生成这个 URL 并将其设置为 <img> 标签的 src 属性。

3.使用 Axios 来获取网络图片并将其转换为 File 对象。以下是具体的实现步骤:

  1. 使用 Axios 请求获取图片的 Blob 数据。
  2. 将 Blob 数据转换为 File 对象。
<template><el-drawer v-model="drawerVisible" direction="rtl"><template #header><h4>{{ formModel.id ? "编辑文章" : "添加文章" }}</h4></template><template #default><el-form :model="formModel" :rules="rules" ref="formRef"><el-form-item label="文章标题" prop="title"><el-input v-model="formModel.title"></el-input></el-form-item><el-form-item label="文章分类" props="cate_id"><ChannelSelectv-model:modelValue="formModel.cate_id"width="100%"></ChannelSelect></el-form-item><el-form-item label="文章封面" prop="cover_img"><el-uploadclass="avatar-uploader":auto-upload="false":show-file-list="false":before-upload="beforeAvatarUpload":on-change="onSelectFile"><img v-if="imageUrl" :src="imageUrl" class="avatar" /><el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon></el-upload></el-form-item><el-form-item label="文章内容" prop="content"><div class="editor"><QuillEditorref="editorRef"v-model:content="formModel.content"theme="snow"contentType="html"/></div></el-form-item><el-form-item label=" "><div><el-button type="primary" @click="onPublisg('已发布')">发布</el-button><el-button @click="onPublisg('草稿')">草稿</el-button></div></el-form-item></el-form></template></el-drawer>
</template>
<script setup>
import { ref, nextTick } from "vue";
import ChannelSelect from "@/view/article/component/ChannelSelect.vue";
import {addArticlePublishApi,getArticleInfoApi,editArticleInfoApi,
} from "@/api/article.js";
import { QuillEditor } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
import { ElMessage } from "element-plus";
import { baseURL } from "@/utils/request";
const drawerVisible = ref(false);
const emit = defineEmits(["success"]);
const deaultFormModel = {title: "",cate_id: "",cover_img: "",content: "",state: "",
};
const formModel = ref({ ...deaultFormModel });
const formRef = ref();
const editorRef = ref();
const open = async (row) => {drawerVisible.value = true;if (row.id) {const res = await getArticleInfoApi(row.id);formModel.value = res.data.data;console.log(res);imageUrl.value = `${baseURL}${res.data.data.cover_img}`;//提交给后台需要的格式是file格式对象,需要将网络图片地址转为file对象,将 File 对象赋值给表单模型const file = await convertImageUrlToFile(imageUrl,formModel.value.cover_img);formModel.value.cover_img = file;} else {formModel.value = { ...deaultFormModel };console.log("editorRef.value", editorRef.value);imageUrl.value = "";await nextTick(() => {editorRef.value.setHTML("");});}
};
defineExpose({ open });
//图片上传
const imageUrl = ref("");
const beforeAvatarUpload = (rawFile) => {if (rawFile.type !== "image/jpeg") {ElMessage.error("Avatar picture must be JPG format!");return false;} else if (rawFile.size / 1024 / 1024 > 2) {ElMessage.error("Avatar picture size can not exceed 2MB!");return false;}return true;
};
const onSelectFile = (uploadFile) => {imageUrl.value = URL.createObjectURL(uploadFile.raw);formModel.value.cover_img = uploadFile.raw;
};
const onPublisg = async (state) => {formModel.value.state = state;const fd = new FormData();for (let key in formModel.value) {fd.append(key, formModel.value[key]);}if (formModel.value.id) {await editArticleInfoApi(fd);ElMessage.success("修改成功");drawerVisible.value = false;emit("success", "emit");} else {await addArticlePublishApi(fd);ElMessage.success("添加成功");drawerVisible.value = false;console.log("drawerVisible.value", drawerVisible.value);emit("success", "add");}
};
const convertImageUrlToFile = async (imageUrl, fileName = "image.jpg") => {// 使用 Axios 获取图片const response = await axios.get(imageUrl, {responseType: "blob", // 设置响应类型为 blob});// 创建 File 对象const file = new File([response.data], fileName, {type: response.data.type,});return file;
};
</script>
<style lang="scss" scoped>
.avatar-uploader .avatar {width: 178px;height: 178px;display: block;
}
.avatar-uploader .el-upload {border: 1px dashed var(--el-border-color);border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;transition: var(--el-transition-duration-fast);
}.avatar-uploader .el-upload:hover {border-color: var(--el-color-primary);
}.el-icon.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;text-align: center;
}
.editor {width: 100%;.ql-editor {min-height: 200px !important;}
}
</style>

 

 

相关文章:

vue+element上传图片

一、html页面上传图片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> <…...

用ChatGPT提升工作效率:从理论到实际应用

伴人工智能技术的迅速演进&#xff0c;像ChatGPT这类语言模型已成为提升工作效率的关键工具。这类模型不仅具备处理海量数据的能力&#xff0c;还能自动化许多日常任务&#xff0c;从而提高决策的准确性。本文将深入探讨如何在工作中利用ChatGPT等AI工具提升效率&#xff0c;涵…...

8、Node.js Express框架

五、Express框架 5.1概念 Express框架是一个基于Node.js平台的极简、灵活的WEB开发框架:www.express.com.cn 简单来说,Express是一个封装好的工具包,封装了很多功能,便于我们开发WEB应用 5.2安装 npm i express5.3 Express初体验 //01-express初体验.js //1.导入exrp…...

STM32F103C8T6学习笔记3--按键控制LED灯

1、实验内容 S4、S5分别接PB12和PB13&#xff0c;实验要求&#xff0c;按下S4&#xff0c;D1亮&#xff0c;D2灭&#xff1b;按下S5&#xff0c;D2亮&#xff0c;D1灭。 由于按键学习的是GPIO口的输入功能&#xff0c;和输出功能的配置略有区别。本次通过按键触发相应功能没有…...

Unity3D Shader实现法线贴图功能详解

在Unity3D中&#xff0c;Shader是一种强大的工具&#xff0c;可以帮助开发人员实现各种复杂的视觉效果&#xff0c;其中法线贴图功能就是其中之一。法线贴图是一种纹理映射技术&#xff0c;通过在模型表面上放置法线贴图纹理来模拟真实世界中的细节和凹凸&#xff0c;使模型看起…...

【含开题报告+文档+源码】基于SpringBoot+Vue的校园设备报修系统

开题报告 随着高校规模的不断扩大和设施设备的日益完善&#xff0c;传统的校园设备报修方式已经无法满足日益增长的维修需求。这种方式往往存在信息不准确、报修流程冗长、反馈不及时等问题&#xff0c;给高校维修工作带来了很大的困扰。为了提高设备故障处理的效率和准确性&a…...

电赛入门之软件stm32keil+cubemx

hal库可以帮我们一键生成许多基本配置&#xff0c;就不需要自己写了&#xff0c;用多了hal库就会发现原来用基本库的时候都过的什么苦日子&#xff08;笑 下面我们以f103c8t6&#xff0c;也就是经典的最小核心板来演示 一、配置工程 首先来新建一个工程 这里我们配置rcc和sys&…...

STM32F103C8T6学习笔记2--LED流水灯与蜂鸣器

1、简要说明与电路图 LED灯与蜂鸣器都是GPIO的输出操作&#xff0c;给高低电平实现。GPIO操作也是后续操作的基础&#xff0c;没有什么难度&#xff0c;记不住寄存器没关系&#xff0c;只要把流程理清楚就可以了。 端口配置成推挽输出模式&#xff0c;高低电平均有驱动能力。 …...

Docker命令备忘录----Linux运维

1. Docker简介 Docker 是一个开源平台&#xff0c;旨在帮助开发人员和运维人员通过容器技术加速应用的开发、测试和部署。它提供了轻量级的隔离环境&#xff0c;使应用程序及其依赖能够快速打包并运行在任何环境中。 Docker的核心组件包括镜像&#xff08;Image&#xff09;、…...

Golang new() make var []int 使用的具体区别

一、数组和切片的初始化 1 var []int 格式 func main() {var t1 []intt1 append(t1, 1)fmt.Println(t1) //正常输出 1var t11 []intt11[0] 11 //panic: runtime error: index out of range [0] with length 0fmt.Println(t11)var t12 [1]intt12[0] 12fmt.Println(t12) /…...

【Linux驱动开发】多线程调用驱动时的并发与竞争(原子操作、自旋锁、信号量、互斥锁)

【Linux驱动开发】多线程调用驱动时的并发与竞争&#xff08;原子操作、自旋锁、信号量、互斥锁&#xff09; 文章目录 多线程调用驱动原子操作原子变量操作原子位操作调用方法 自旋锁读写锁顺序锁调用方法 信号量互斥锁&#xff08;互斥体&#xff09;中断中使用附录&#xf…...

qt QComboBox详解

QComboBox是一个下拉选择框控件&#xff0c;用于从多个选项中选择一个。通过掌握QComboBox 的用法&#xff0c;你将能够在 Qt 项目中轻松添加和管理组合框组件&#xff0c;实现复杂的数据选择和交互功能。 重要方法 addItem(const QString &text)&#xff1a;将一个项目添…...

redis做缓存,mysql的数据怎么与redis进行同步(双写一致性)

基于业务做选择,强一致性和允许延迟再加消息队列 强一致性:当修改了数据库的数据同时更新缓存的数据,缓存和数据库的数据保持一致 读操作:缓存命中,直接返回数据,缓存没有命中,查询数据库,写入缓存,设定过期时间 写操作:延迟双删 :先删除缓存,修改数据库,等待延迟(数据库主从节…...

WPF触发器

WPF触发器 触发器&#xff08;Trigger&#xff09;通常指的是一种事件驱动机制&#xff0c;用于响应特定的事件或条件。WPF触发器是WPF中一种强大的功能&#xff0c;允许开发者在样式和模板中定义条件逻辑&#xff0c;以响应属性值的变化。WPF提供了多种触发器来实现样式和模板…...

反序列化漏洞的运行原理及防御方法

反序列化漏洞是当前网络安全领域中的一种严重安全威胁&#xff0c;其运行原理和防御方法对于保障应用程序和系统安全至关重要。本文将深入探讨反序列化漏洞的运行原理&#xff0c;并提出有效的防御策略。 ### 反序列化漏洞的运行原理 序列化是指将对象的状态信息转换为可以存储…...

护眼大路灯哪个牌子好?口碑最好的护眼灯品牌​​

护眼大路灯哪个牌子好&#xff1f;作为一名专业的测评师&#xff0c;我发现有大量的家长都反应自己家孩子在学习时经常出现&#xff0c;揉眼睛、频繁眨眼、眼睛痒等问题&#xff0c;而这些问题多半是与不良光线有光&#xff0c;这些现象使我更加关注护眼大路灯的选择&#xff0…...

Redis 初学者指南

Redis 初学者指南 1. 什么是 Redis&#xff1f;2. Redis 的基本概念3. 安装 Redis3.1 使用 Docker 安装3.2 从源码编译安装 4. 基本操作4.1 启动 Redis 服务4.2 连接 Redis 客户端4.3 常用命令 5. Redis 的数据结构5.1 字符串5.2 列表5.3 集合5.4 散列5.5 有序集合 6. 高级特性…...

node.js_npm : 无法加载文件 D:\Program Files\nodejs\npm.ps1

这个错误信息表明 PowerShell 因为执行策略的限制而阻止了 npm.ps1 脚本的运行。PowerShell 的执行策略是一种安全功能&#xff0c;用于限制哪些脚本可以运行&#xff0c;以防止恶意脚本的执行。 要解决这个问题&#xff0c;你可以按照以下步骤操作&#xff1a; 查看当前的执行…...

技术星河中的璀璨灯塔 —— 青云交的非凡成长之路

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

使用 Git 命令将本地项目上传到 GitLab

步骤详解 1. 在 GitLab 上创建一个新项目 登录你的 GitLab 账号。点击“New project”创建一个新的空项目。为项目设置名称、描述等信息。 2. 关联远程 Git 仓库 1.初始化本地 Git 仓库 git init 2.关联远程仓库&#xff1a; git remote add origin https://gitlab-lizz…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...