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 相关文章推荐
javascript整除实现代码
Nov 23 Javascript
JQuery实现简单验证码提示解决方案
Dec 20 Javascript
JS针对浏览器窗口关闭事件的监听方法集锦
Jun 24 Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
Jul 05 Javascript
AngularJs  E2E Testing 详解
Sep 02 Javascript
vue.js 表格分页ajax 异步加载数据
Oct 18 Javascript
原生JS查找元素的方法(推荐)
Nov 22 Javascript
jQuery 如何实现一个滑动按钮开关
Dec 01 Javascript
基于vue的fullpage.js单页滚动插件
Mar 20 Javascript
关于jQuery库冲突的完美解决办法
May 20 jQuery
vue-router路由参数刷新消失的问题解决方法
Jun 17 Javascript
javascript中可能用得到的全部的排序算法
Mar 05 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中static静态变量的使用方法详解
2010/06/04 PHP
PHP 获取远程网页内容的代码(fopen,curl已测)
2011/06/06 PHP
教你如何使用php session
2013/10/28 PHP
php遍历目录与文件夹的多种方法详解
2013/11/14 PHP
php5.2以下版本无json_decode函数的解决方法
2014/05/25 PHP
ThinkPHP中pathinfo的访问模式、路径访问模式及URL重写总结
2014/08/23 PHP
详解PHP中instanceof关键字及instanceof关键字有什么作用
2015/11/05 PHP
phpstudy后门rce批量利用脚本的实现
2019/12/12 PHP
js变量作用域及可访问性的探讨
2006/11/23 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
node.js中的fs.utimes方法使用说明
2014/12/15 Javascript
AngularJS入门教程之服务(Service)
2016/07/27 Javascript
AngularJS ng-blur 指令详解及简单实例
2016/07/30 Javascript
jquery层级选择器的实现(匹配后代元素div)
2016/09/05 Javascript
Bootstrap modal使用及点击外部不消失的解决方法
2016/12/13 Javascript
详解如何在Angular中快速定位DOM元素
2017/05/17 Javascript
JS数组去重常用方法实例小结【4种方法】
2018/05/28 Javascript
Vue-cli3项目配置Vue.config.js实战记录
2018/07/29 Javascript
layerUI下的绑定事件实例代码
2018/08/17 Javascript
命令行批量截图Node脚本示例代码
2019/01/25 Javascript
openlayers4实现点动态扩散
2020/08/17 Javascript
python获取指定目录下所有文件名列表的方法
2015/05/20 Python
详解python时间模块中的datetime模块
2016/01/13 Python
Python计算一个给定时间点前一个月和后一个月第一天的方法
2018/05/29 Python
Python删除n行后的其他行方法
2019/01/28 Python
使用Tensorflow将自己的数据分割成batch训练实例
2020/01/20 Python
Python模拟伯努利试验和二项分布代码实例
2020/05/27 Python
一款基于css3的列表toggle特效实例教程
2015/01/04 HTML / CSS
利达恒信公司.NET笔试题面试题
2016/03/05 面试题
大二学期个人自我评价
2014/01/13 职场文书
安全责任书怎么写
2014/07/28 职场文书
党员个人整改措施
2014/10/24 职场文书
2014年教研室工作总结
2014/12/06 职场文书
2014年小学语文工作总结
2014/12/20 职场文书
好员工观后感
2015/06/17 职场文书
宣传部部长竞选稿
2015/11/21 职场文书