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 相关文章推荐
网页里控制图片大小的相关代码
Jun 13 Javascript
查询绑定数据岛的表格中的文本并修改显示方式的js代码
Dec 15 Javascript
javascript 伪数组实现方法
Oct 11 Javascript
jQuery表单验证插件formValidator(改进版)
Feb 03 Javascript
使用Math.floor与Math.random取随机整数的方法详解
May 07 Javascript
深入理解Javascript中的循环优化
Nov 09 Javascript
浅析AngularJS Filter用法
Dec 28 Javascript
微信小程序 template模板详解及实例
Feb 21 Javascript
jQuery实现ajax无刷新分页页码控件
Feb 28 Javascript
vue下拉菜单组件(含搜索)的实现代码
Nov 25 Javascript
node.js中ws模块创建服务端和客户端,网页WebSocket客户端
Mar 06 Javascript
Javascript读写cookie的实例源码
Mar 16 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
ADODB结合SMARTY使用~超级强
2006/11/25 PHP
php自定义session示例分享
2014/04/22 PHP
PHP中使用sleep造成mysql读取失败的案例和解决方法
2014/08/21 PHP
php检测url是否存在的方法
2015/04/14 PHP
DEDECMS首页调用图片集里的多张图片
2015/06/05 PHP
php实现比较两个文件夹异同的方法
2015/06/18 PHP
PHP模板引擎Smarty中的保留变量用法分析
2016/04/11 PHP
thinkphp项目如何自定义微信分享描述内容
2017/02/20 PHP
php简单构造json多维数组的方法示例
2017/06/08 PHP
一文掌握PHP Xdebug 本地与远程调试(小结)
2019/04/23 PHP
JS之小练习代码
2008/10/12 Javascript
加速IE的Javascript document输出的方法
2010/12/02 Javascript
JavaScript插入动态样式实现代码
2012/02/22 Javascript
js+css简单实现网页换肤效果
2015/12/29 Javascript
jquery validate表单验证的基本用法入门
2016/01/18 Javascript
AngularJS 遇到的小坑与技巧小结
2016/06/07 Javascript
Angular学习笔记之angular的$filter服务浅析
2016/11/12 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
JavaScript实现图片轮播特效
2019/10/23 Javascript
python根据路径导入模块的方法
2014/09/30 Python
python根据出生日期返回年龄的方法
2015/03/26 Python
python动态网页批量爬取
2016/02/14 Python
Python通过命令开启http.server服务器的方法
2017/11/04 Python
异步任务队列Celery在Django中的使用方法
2018/06/07 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
TensorFlow实现模型评估
2018/09/07 Python
Python识别快递条形码及Tesseract-OCR使用详解
2019/07/15 Python
Python 实现数据结构-堆栈和队列的操作方法
2019/07/17 Python
Pyecharts 中Geo函数常用参数的用法说明
2021/02/01 Python
高校学生干部的自我评价分享
2013/11/04 职场文书
自我评价怎么写正确呢?
2013/12/02 职场文书
护士思想汇报
2014/01/12 职场文书
趣味运动会活动方案
2014/02/12 职场文书
小学开学标语
2014/07/01 职场文书
酒店工程部岗位职责
2015/02/12 职场文书
忠诚教育学习心得体会
2016/01/23 职场文书