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 相关文章推荐
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft区别分析
Mar 12 Javascript
jQuery1.3.2 升级到jQuery1.4.4需要修改的地方
Jan 06 Javascript
浅谈JavaScript编程语言的编码规范
Oct 21 Javascript
给jqGrid数据行添加修改和删除操作链接(之一)
Nov 04 Javascript
非主流的textarea自增长实现js代码
Dec 20 Javascript
jQuery Tools tab使用介绍
Jul 14 Javascript
JS、DOM和JQuery之间的关系示例分析
Apr 09 Javascript
JS是按值传递还是按引用传递
Jan 30 Javascript
JS实现加载时锁定HTML页面元素的方法
Jun 24 Javascript
JavaScript正则表达式的贪婪匹配和非贪婪匹配
Sep 05 Javascript
vue 文件目录结构详解
Nov 24 Javascript
JavaScript原生实现观察者模式的示例
Dec 15 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
PHP4和PHP5共存于一系统
2006/11/17 PHP
解析thinkphp import 文件内容变量失效的问题
2013/06/20 PHP
PHP字符串的连接的简单实例
2013/12/30 PHP
PHP自定义多进制的方法
2016/11/03 PHP
php简单中奖算法(实例)
2017/08/15 PHP
EXT中xtype的含义分析
2010/01/07 Javascript
Javascript公共脚本库系列(一): 弹出层脚本
2011/02/24 Javascript
日历查询的算法 如何计算某一天是星期几
2012/12/12 Javascript
用Jquery.load载入页面实现局部刷新
2014/01/22 Javascript
javascript动态创建及删除元素的方法
2014/12/22 Javascript
JavaScript中的数组操作介绍
2014/12/30 Javascript
EditPlus 正则表达式 实战(3)
2016/12/15 Javascript
node文件上传功能简易实现代码
2017/06/16 Javascript
Vue学习之路之登录注册实例代码
2017/07/06 Javascript
微信小程序radio组件使用详解
2018/01/31 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
vue.js实现插入数值与表达式的方法分析
2018/07/06 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
2018/09/12 Javascript
Electron-vue开发的客户端支付收款工具的实现
2019/05/24 Javascript
nuxt框架中对vuex进行模块化设置的实现方法
2019/09/06 Javascript
JS async 函数的含义和用法实例总结
2020/04/08 Javascript
如何基于layui的laytpl实现数据绑定的示例代码
2020/04/10 Javascript
基于javascript处理nginx请求过程详解
2020/07/07 Javascript
[01:55]TI9显影之尘系列 - Evil Geniuses
2019/08/22 DOTA
Python multiprocessing.Manager介绍和实例(进程间共享数据)
2014/11/21 Python
python随机生成指定长度密码的方法
2015/04/04 Python
Python实现的快速排序算法详解
2017/08/01 Python
Python实现基本数据结构中栈的操作示例
2017/12/04 Python
numpy.linspace 生成等差数组的方法
2018/07/02 Python
Python实现将字符串的首字母变为大写,其余都变为小写的方法
2019/06/11 Python
python 实现朴素贝叶斯算法的示例
2020/09/30 Python
介绍一下如何利用路径遍历进行攻击及如何防范
2014/01/19 面试题
幼儿园开学寄语
2014/04/03 职场文书
电子商务系毕业生自荐信
2014/05/29 职场文书
2014年政协委员工作总结
2014/12/01 职场文书
班主任自我评价范文
2015/03/11 职场文书