vue 图片裁剪上传组件的实现


Posted in Javascript onNovember 12, 2020

先看一下总体效果:

上传文件做了大小和类型的限制,在动图中无法展现出来。

vue 图片裁剪上传组件的实现

使用file类型的input实现选择本地文件

但是浏览器原生的文件上传按钮的颜值不尽人意,而且按钮上的文字是无法改变的,我需要把这个上传文件的按钮改造一下。

  • 方法1:使用label元素来触发一个隐藏的file类型的 input元素;(缺点:在多人开发时,可能出现重复的元素id,导致难以预料的bug)
<input type="file" id='up_file_input' v-show='false' >
<label for='up_file_input'></label>
  • 方法2:或者在这个label元素的click事件函数中手动触发文件上传按钮的click事件。
<input type="file" v-show='false' ref="inputFileUp" >
<label @click='$refs.inputFileUp.click()'></label>

使用input的change事件获取选择的本地图片并进行校验

上传图片的校验规则及提示语由父组件通过 prop 传递给子组件,格式如下:

const img_valit = {
 type: /^.*\.(jpg|png|jpeg)$/i, // 文件格式校验
 type_error_msg: '上传头像图片只能是 jpg 或者 png 格式!',
 size: 3, // 文件大小校验
 size_error_msg: '上传的图片大小不能超过3MB'
}

这里需要注意: 需要在上传文件按钮的click事件中手动清空这个文件类型输入框的值,解决选择和上次相同的文件之后无法触发 change事件的问题

function fileInputClick(event) {
  event.target.value = "";
}
function coverImgChange(event) {
   const file = event.target.files[0];
   // 在组件的自定义属性中定义一个变量 originalFile 来保存当前上传的文件
   this.$options._myOpt.originalFile = file;
   // 获取对文件的校验规则
   const { type, size, type_error_msg, size_error_msg } = this.img_valit;
   // 校验文件类型和文件大小
   const isJPG_PNG = type.test(file.name), isLt5M = file.size / 1024 / 1024 <= size;
   !isLt5M && this.$message.error(size_error_msg);
   !isJPG_PNG && this.$message.error(type_error_msg);
   // 文件通过校验,打开裁剪弹窗
   if (isJPG_PNG && isLt5M) {
    this.cropImgUrl = window.URL.createObjectURL(file);
    this.dialogVisible = true;
   }
  }

打开弹窗进行图片裁剪

弹窗使用的 Element-UI 中的弹窗, 图片裁剪是第三方插件 vue-cropper。图片裁剪插件中的一些配置可以参考插件官方文档,下面的代码中省略了配置部分的代码。

<el-dialog :visible.sync="dialogVisible" width='800px' title="图片裁剪">
   <div class="dialog-content">
    <div class="cropper-image">
     <vue-cropper
      ref="cropper"
      :img="cropImgUrl"
      @realTime="realTime"
     ></vue-cropper>
    </div>
    <!-- 图片裁剪之后的预览 -->
    <div class="preview-wrapper">
     <div
      class="show-preview"
      :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden'}"
     >
      <div :style="previews.div">
       <img :src="previews.url" class="preview_img" :style="[previews.img]">
      </div>
     </div>
     <p class="preview-text">裁剪结果预览</p>
    </div>
   </div>
   <div slot="footer" class="dialog-footer">
    <button @click="dialogEsc()">取 消</button>
    <button @click="dialogSure()">确 定</button>
   </div>
  </el-dialog>

向服务器发送请求上传图片

上传文件接口中,向后台发送请求的参数为 {image: 文件本身(File类型), filename: 文件名}

function realTime(data) {
  this.previews = data;
}
// 裁剪弹窗中确定按钮的点击事件
function dialogSure() {
   const ajaxConfig = {
    headers: {
     "Content-Type": "multipart/form-data"
    }
   };
   // 上传图片的文件名
   let cropFileName =
    this.$options._myOpt.originalFile.name.match(/([^\/]+)(?=\.)/gi)[0] ||
    Date.now().toString();
   this.$refs.cropper.getCropBlob(blob => {
   // IE 和 Edge 不支持 File 构造函数
    let cropFile = new File(
     [blob],
     cropFileName.toString() + "." + (this.cropperConfig.outputType || "jpg"),
     { type: blob.type }
    );
    let upParams = new FormData();
    upParams.append("image", cropFile);
    upParams.append("filename", cropFile.fileName);
    axios.post(this.up_action, upParams).then(({ data }) => {
     if (data.status === 0) {
      this.coverUlr = window.URL.createObjectURL(blob);
      this.pathToParent({
       fileId: data.result.fileId,
       fileExt: data.result.fileExt
      });
     } else {
      this.coverUlr = "";
      this.pathToParent({
       fileId: "",
       fileExt: ""
      });
     }
    });
   });
   this.dialogVisible = false;
  }
  // 向父组件传递上传文件成功之后后台返回的数据
  function pathToParent(filePath) {
   this.$emit("getFilePath", filePath);
  }

以上就是vue 图片裁剪上传组件的实现的详细内容,更多关于vue 图片裁剪上传组件的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
怎么让脚本或里面的函数在所有图片都载入完毕的时候执行
Oct 17 Javascript
javascript 对象的定义方法
Jan 10 Javascript
分享别人写的一个小型js框架
Aug 13 Javascript
Javascript 表单之间的数据传递代码
Dec 04 Javascript
javascript URL锚点取值方法
Feb 25 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
Sep 01 Javascript
JavaScript实现的一个倒计时的类
Mar 12 Javascript
解析js如何获取css样式
Dec 11 Javascript
简单谈谈关于 npm 5.0 的新坑
Jun 08 Javascript
AngularJS 控制器 controller的详解
Oct 17 Javascript
打字效果动画的4种实现方法(超简单)
Oct 18 Javascript
在vue项目中使用Nprogress.js进度条的方法
Jan 31 Javascript
js前端传json后台接收‘‘被转为quot的问题解决
Nov 12 #Javascript
使用Vant完成DatetimePicker 日期的选择器操作
Nov 12 #Javascript
JavaScript 实现拖拽效果组件功能(兼容移动端)
Nov 11 #Javascript
vant 中van-list的用法说明
Nov 11 #Javascript
让Vue响应Map或Set的变化操作
Nov 11 #Javascript
vue项目中使用rem,在入口文件添加内容操作
Nov 11 #Javascript
VUE前端从后台请求过来的数据进行转换数据结构操作
Nov 11 #Javascript
You might like
帖几个PHP的无限分类实现想法~
2007/01/02 PHP
php启用zlib压缩文件的配置方法
2013/06/12 PHP
php字符串截取的简单方法
2013/07/04 PHP
php像数组一样存取和修改字符串字符
2014/03/21 PHP
PHP获取当前文件的父目录方法汇总
2016/07/21 PHP
Js的MessageBox
2006/12/03 Javascript
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
2009/02/18 Javascript
JQuery实现的在新窗口打开链接的方法小结
2010/04/22 Javascript
eval与window.eval的差别分析
2011/03/17 Javascript
常用的几段javascript代码分享
2014/03/25 Javascript
教你如何在 Javascript 文件里使用 .Net MVC Razor 语法
2014/07/23 Javascript
JavaScript中发布/订阅模式的简单实例
2014/11/05 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
2016/06/07 Javascript
layui问题之渲染数据表格时,仅出现10条数据的解决方法
2019/09/12 Javascript
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
python实现无证书加密解密实例
2014/10/27 Python
Python中的条件判断语句基础学习教程
2016/02/07 Python
python使用sqlite3时游标使用方法
2018/03/13 Python
python 将大文件切分为多个小文件的实例
2019/01/14 Python
用python 实现在不确定行数情况下多行输入方法
2019/01/28 Python
计算机二级python学习教程(1) 教大家如何学习python
2019/05/16 Python
Python多进程入门、分布式进程数据共享实例详解
2019/06/03 Python
python爬虫实现POST request payload形式的请求
2020/04/30 Python
英国最全面的橄榄球联盟门票网站:Live Rugby Tickets
2018/10/06 全球购物
一套Delphi的笔试题二
2013/05/11 面试题
医药代表个人求职信范本
2013/12/19 职场文书
银行办理业务介绍信
2014/01/18 职场文书
大学毕业自我评价
2014/02/02 职场文书
《母亲的恩情》教学反思
2014/02/13 职场文书
2014年清明节寄语
2014/04/03 职场文书
垃圾桶标语
2014/06/24 职场文书
租房协议书范文
2014/08/20 职场文书
职场干货:简历中的自我评价应该这样写!
2019/05/06 职场文书
自定义函数实现单词排序并运用于PostgreSQL(实现代码)
2021/04/22 PostgreSQL
Python-typing: 类型标注与支持 Any类型详解
2021/05/10 Python
Mysql 如何合理地统计一个数据库里的所有表的数据量
2022/04/18 MySQL