【vue+el-upload+vue-cropper】vue图片上传,vue-cropper图片裁剪后上传

在这里插入图片描述

一. 先看效果演示

在这里插入图片描述

二. 图片上传

用的el-upload加el-image组件
html部分

<el-dialog>
...//无关代码已省略
	<div v-for="item in imgArr" :key="item.index">
      <span>{{ item.name }}</span>
      <el-upload action="#" list-type="picture-card" :on-change="onChange.bind(null, item.index)" :auto-upload="false" :file-list="item.fileList" :class="{ hide: item.hideUpload }">
          <i slot="default" class="el-icon-plus"></i>
          <div slot="file" slot-scope="{ file }">
            <el-image class="el-upload-list__item-thumbnail" :src="item.aimgSrc" alt="" :onerror="defaultImg" :preview-src-list="item.fileList"></el-image>
            <span class="el-upload-list__item-actions">
            	// 预览按钮
              <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                <i class="el-icon-zoom-in"></i>
              </span>
              	// 删除按钮
              <span class="el-upload-list__item-delete" @click="handleRemove(file, item.index)">
                <i class="el-icon-delete"></i>
              </span>
              	// 裁剪按钮
              <span v-if="item.index == 6" class="el-upload-list__item-delete" @click="beforeCrop(file)">
                <i class="el-icon-scissors"></i>
              </span>
            </span>
          </div>
        </el-upload>
	</div>
</el-dialog>
....

注释:
el-upload
:on-change=“onChange.bind(null, item.index)” 不加.bind会报错,
:auto-upload=“false” 表示不自动上传,也就是手动上传
:file-list=“item.fileList” 上传的图片列表,数组对象格式[{url:xxxx}]
:class=“{ hide: item.hideUpload }” 到el-image使用,上传完后影藏那个加号和虚线框

el-image
:οnerrοr=“defaultImg” 图片加载失败,报错时候的默认图片.
:preview-src-list=“item.fileList” 预览的图片列表,同:file-list=“item.fileList”

预览,删除,裁剪,三个按钮,目前功能与预览无关,预览功能有空再另写吧

js部分


      imgArr: [
        // aimgFile调接口, aimgSrc回显, hideUpload影藏加号, fileList预览大图
        { index: 0, name: '图片A:', aimgFile: '', aimgSrc: '', hideUpload: false, fileList: [] },
        { index: 1, name: '图片A:', aimgFile: '', aimgSrc: '', hideUpload: false, fileList: [] },
        { index: 2, name: '图片A:', aimgFile: '', aimgSrc: '', hideUpload: false, fileList: [] },
        { index: 3, name: '图片A:', aimgFile: '', aimgSrc: '', hideUpload: false, fileList: [] },
        { index: 4, name: '图片A:', aimgFile: '', aimgSrc: '', hideUpload: false, fileList: [] },
        { index: 5, name: '图片A:', aimgFile: '', aimgSrc: '', hideUpload: false, fileList: [] },
        { index: 6, name: '图片A:', aimgFile: '', aimgSrc: '', hideUpload: false, fileList: [] },
      ],
      files :'', //裁剪图片的标记
      
    // 上传图片 index 图片下标 file图片内容 flag裁剪图片的标记
    onChange(index, file, flag) {
      this.files = file.raw
      const isJPG = file.raw.type === 'image/jpeg' || file.raw.type == 'image/png'
      const isLt2M = file.raw.size / 1024 / 1024 < 2
      if (!isJPG) {
        this.$message.error('上传图片只能是 JPG 或 PNG 格式!')
        this.handleRemove(file.raw, index)
        return
      }
      if (!isLt2M) {
        this.$message.error('上传图片大小不能超过 2MB!')
        this.handleRemove(file.raw, index)
        return
      }
      // 上传图片
      const fileData = new FormData()
      fileData.append('imgFile', file.raw)
      fileData.append('imgType', 1)
      // 调接口
      doctorAccessoryUpload(fileData).then((res) => {
        if (res) {
          this.imgArr[index].hideUpload = true
          this.imgArr[index].aimgSrc = file.url
          this.imgArr[index].aimgFile = res.result
          // 裁剪后上传
          if (flag === 1) this.imgArr[index].fileList = [{ url: file.url }]
        } else {
          this.handleRemove(file.raw, index)
        }
      })
    },
    // 删除上传图片
    handleRemove(file, index) {
      this.imgArr[index].aimgSrc = ''
      this.imgArr[index].aimgFile = ''
      this.imgArr[index].fileList = []
      this.imgArr[index].hideUpload = false
    },
三. 裁剪图片

下载vueCropper插件

	npm i vue-cropper --save  // 我的版本是^0.6.4

另起一个dialog

      <!-- 图片裁剪 -->
      <el-dialog title="图片裁剪" :visible.sync="cropDialog" width="40%" :modal="true" :close-on-click-modal="false" center @close="cropCancles" v-dialogDrag>
        <div class="cropBox">
          <template>
            <div>
              <vueCropper
                @mouseenter.native="enter"
                @mouseleave.native="leave"
                ref="cropper"
                :img="option.uploadImg"
                :outputSize="option.size"
                :outputType="option.outputType"
                :info="true"
                :full="option.full"
                :canMove="option.canMove"
                :canMoveBox="option.canMoveBox"
                :original="option.original"
                :autoCrop="option.autoCrop"
                :fixed="option.fixed"
                :fixedNumber="option.fixedNumber"
                :centerBox="option.centerBox"
                :infoTrue="option.infoTrue"
                :fixedBox="option.fixedBox"
              ></vueCropper>
            </div>
          </template>
          <div>
            <img :src="cropImg" alt="" />
          </div>
        </div>
        <div slot="footer">
          <el-button @click="cropCancles">取 消</el-button>
          <el-button type="primary" @click="cropConfirm">裁剪图片</el-button>
        </div>
      </el-dialog>
      <script>
      import { VueCropper } from 'vue-cropper'
      export default {
  		components: { VueCropper },
  		data() {
		    return {
	          cropDialog: false,
		      option: {
		        uploadImg: '', // 原图地址
		        info: true, // 裁剪框的大小信息
		        outputSize: 1, // 裁剪生成图片的质量
		        outputType: 'jpeg', // 裁剪生成图片的格式
		        canScale: true, // 图片是否允许滚轮缩放
		        autoCrop: true, // 是否默认生成截图框
		        fixedBox: true, // 固定截图框大小 不允许改变
		        fixed: true, // 是否开启截图框宽高固定比例
		        fixedNumber: [3, 4], // 截图框的宽高比例
		        full: false, // 是否输出原图比例的截图
		        canMove: true, //是否可以移动原图
		        canMoveBox: true, // 截图框能否拖动
		        original: false, // 上传图片按照原始比例渲染
		        centerBox: true, // 截图框是否被限制在图片里面
		        infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
		      },
		      cropImg: require('../../public/img/default.png'),
			}
		}
		  //开始裁剪
	    enter() {
	      if (this.option.uploadImg == '') {
	        return
	      }
	      this.$refs.cropper.startCrop()
	    },
	    //停止裁剪
	    leave() {
	      this.$refs.cropper.stopCrop()
	      this.$refs.cropper.getCropData((data) => {
	        this.cropImg = data
	      })
	    },
	    // 裁剪前
	    beforeCrop(file) {
	      this.option.uploadImg = file.url
	      this.cropDialog = true
	      setTimeout(() => {
	        this.$refs.cropper.getCropData((data) => {
	          this.cropImg = data
	        })
	      }, 500)
	    },
	    // 确认裁剪
	    cropConfirm() {
	      //获取截图的base64格式数据
	      this.$refs.cropper.getCropData((data) => {
	        this.cropImg = data
	        this.handleRemove(this.files, this.imgArr.length - 1)
	        this.cropCancles()
	        setTimeout(() => {
	          this.onChange(this.imgArr.length - 1, { raw: this.dataURLtoFile(data, 'Default.jpg'), url: data }, 1)
	        }, 1000)
	      })
	    },
	    // 取消裁剪
	    cropCancles() {
	      this.cropDialog = false
	      this.option.uploadImg = ''
	      this.cropImg = require('../../public/img/default.png')
	    },
	    // base64转file
	    dataURLtoFile(dataurl, filename) {
	      let arr = dataurl.split(',')
	      let mime = arr[0].match(/:(.*?);/)[1]
	      let bstr = atob(arr[1])
	      let n = bstr.length
	      let u8arr = new Uint8Array(n)
	      while (n--) {
	        u8arr[n] = bstr.charCodeAt(n)
	      }
	      return new File([u8arr], filename, { type: mime })
	    },
	  }
      </script>

ok 结束了,记录一下

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

客服呼叫中心的语音质检工作

语音质检是呼叫中心运营中必不可缺少的一个环节&#xff0c;呼叫中心语音质检对坐席起着直接监督的作用&#xff0c;也正是这种监督约束推动着客服人员不断提升自身的业务能力。 而客服呼叫中心的质检结果中还蕴藏了大量有价值的信息&#xff0c;可以通过日常的质检工作真正发现…

EtherCAT超高速实时运动控制卡XPCIE1032H上位机C#开发(一):驱动安装与建立连接

XPCIE1032H功能简介 XPCIE1032H是一款基于PCI Express的EtherCAT总线运动控制卡&#xff0c;可选6-64轴运动控制&#xff0c;支持多路高速数字输入输出&#xff0c;可轻松实现多轴同步控制和高速数据传输。 XPCIE1032H集成了强大的运动控制功能&#xff0c;结合MotionRT7运动…

OTA包添加自定义内容

起因 新开一条线&#xff0c;需要上传的OTA包里加点内容&#xff0c;好让后台校验它是否是当前这条线(短期最小改动)。 开整 之前看过ota包结构&#xff0c;整包和差分包里都有一个payload_properties.txt文件&#xff0c;所以最简单的就是给这个txt文件里追加点自定义内容&…

制造企业如何做好进销存管理工作?

本文你将了解&#xff1a;什么是进销存管理系统&#xff1f;国内制造信息化的发展现状如何&#xff1f;进销存管理系统的功能有哪些&#xff1f; 接下来搭建进销存管理系统教学中用到的图片和系统都来自简道云的进销存管理系统 这也是我们公司目前正在用的进销存管理系统&…

el-form-item的label的长度单独改掉,用vue3样式穿透的写法,加上css选择器查找特定的id拿到元素

为了让这个会员卡号这几个字和下面的表格对齐&#xff0c;需要改el-form-item的label的长度 如果直接改el-form的label-width,那么所有的el-form-item的label都会改&#xff0c;我不希望这样 我希望只改第1个会员卡号的label长度 给这个el-form-item添加一个id :deep(.el-for…

vnpy_ctp源码下载后转变为python可用的处理过程

目录 写在前面 下载源码并解压 创建python项目 环境 过程 编译vnpy_ctp源码 验证可用性 写在前面 window系统中必须安装有Visual Studio ,后面源码安装时需要进行C编译 下载源码并解压 GitHub - vnpy/vnpy_ctp: VeighNa框架的CTP交易接口 下载zip压缩包 解压 要在…

Mysql数据备份 —Navicat

一 Navicat 对于表的备份 根据自己的需求来选择 可以直接备份数据表 操作简单明了 二 Navicat 对于库的备份 对于数据库 直接通过转储SQL文件 保存结构和数据 需要新创建数据库 字符集和编码格式要对应 否则容易乱码 运行刚才生成的文件即可

【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固

​ 摘要 在开发iOS应用时&#xff0c;保护应用程序的安全是非常重要的。本文将介绍一种使用ipaguard混淆加固的方法来保护iOS应用的安全。通过字符串混淆、类名和方法名混淆、程序结构混淆加密以及反调试、反注入等主动保护策略&#xff0c;可以有效地保护应用程序的安全性。 …

案例精选|聚铭综合日志分析系统为中电飞华业务数据安全保驾护航

当下&#xff0c;云和网正从过去的独立走向融合&#xff0c;各行各业从“上网”纷纷演进到“上云”。“上云&#xff0c;才能更好地拥抱数字时代”。云网融合高质量发展对信息基础设施能力提出了新要求&#xff0c;同时运营商在产业数字化领域的业务探索也需要强大的云网能力支…

安科瑞故障电弧探测器在建筑电气的设计与应用

安科瑞 崔丽洁 【摘要】&#xff1a;电气设备是建筑中不可缺少的一部分&#xff0c;具有较为重要的作用和意义&#xff0c;在应用过程中不仅能够提升建筑本身实用性能&#xff0c;而且可为消费者提供更加优良的生活环境。但设备一旦在运行过程中出现故障&#xff0c;不仅会影响…

ros1 基础学习10 -全局字典参数的定义,获取,改值

全局字典参数的定义&#xff0c;获取&#xff0c;改值 一、参数模型二、 创建功能包三、参数命令行的使用(rosparam)四、使用程序来使用参数&#xff08;C&#xff09;4.1创建代码4.2编译4.3 编译文件 测试 在ROS Master中&#xff0c;存在一个参数服务器&#xff08;Parameter…

数学函数3D可视化工具来了

前面已经跟大家分享了两个数学可视化工具&#xff0c;manim和geogebra。 按理讲不应该再重复推荐类似的工具了&#xff0c;感觉犯了软件开发常说的忌讳&#xff1a;重复造轮子。 有的人也会抱怨手里的工具多了都不知道用哪一个了。 但遇到好用的工具又忍不住分享出来&#x…

04-SpringBoot的基础配置及其配置文件分类,解决Yaml文件失效问题

SpringBoot的配置 SpringBoot是用来提高Spring程序的开发效率的,使用SpringBoot后几乎不用做任何配置功能就有了,因为很多功能已经有默认配置帮我们做好了 配置文件的相关配置 在一个项目中不同的技术对应不同的配置文件并且这些配置文件的格式也不统一 SpringBoot提供了一…

Linux之IPC通信共享内存(一次拷贝)与消息队列、管道、信号量、socket(两次拷贝)总结(六十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

工业废水处理设备公司如何挑选

在选择工业废水处理设备公司时&#xff0c;需要从以下几个方面进行考虑&#xff1a; 公司实力和资质&#xff1a;选择具有相关资质和经验的废水处理设备公司&#xff0c;能够提供高质量的设备和服务。可以通过查询公司的官方网站、客户评价等信息来了解公司的实力和资质。设备…

大厂面试题-数据库连接池有什么用?它有哪些关键参数?

从这几个方面来回答&#xff1a; 首先&#xff0c;数据库连接池是一种池化技术&#xff0c;池化技术的核心思想是实现资源的复用&#xff0c;避免资源重复创建销毁的开销。 而在数据库的应用场景里面&#xff0c;应用程序每次向数据库发起CRUD操作的时候&#xff0c;都需要创…

AI生成技术威胁版权保护,水印技术和法律完善是关键/安圭拉小岛以.ai域名注册赚得3000万美元 |魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; &#x1f525;资讯预览 AI生成技术威胁版权保护&#xff0c;水印技术和法律完善是关键 Sam Altman对…

【Git】Git图形化工具SSH协议IDEA集成Git的使用讲解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Git》。&#x1f3af;&#x1f3af; &#x1f449…

企业年会/年终活动如何邀请媒体记者报道?

​媒体邀约是企业或组织进行宣传的重要手段之一。通过邀请媒体参加活动&#xff0c;可以增加活动的曝光度和知名度&#xff0c;吸引更多的关注和参与。同时&#xff0c;媒体报道还可以提高企业或组织的权威性和可信度&#xff0c;从而让公众更容易接受其传达的信息。 企业年会或…

实时疫情地图及全国监测动态大屏可视化【可视化项目案例-02】

🎉🎊🎉 你的技术旅程将在这里启航! 🚀🚀 本文选自专栏:可视化技术专栏100例 可视化技术专栏100例,包括但不限于大屏可视化、图表可视化等等。订阅专栏用户在文章底部可下载对应案例源码以供大家深入的学习研究。 🎓 每一个案例都会提供完整代码和详细的讲解,不…