当前位置: 首页 > 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…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...

GraphRAG优化新思路-开源的ROGRAG框架

目前的如微软开源的GraphRAG的工作流程都较为复杂&#xff0c;难以孤立地评估各个组件的贡献&#xff0c;传统的检索方法在处理复杂推理任务时可能不够有效&#xff0c;特别是在需要理解实体间关系或多跳知识的情况下。先说结论&#xff0c;看完后感觉这个框架性能上不会比Grap…...