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 相关文章推荐
一些易混淆且不常用的属性,希望有用
Jan 29 Javascript
IE8下关于querySelectorAll()的问题
May 13 Javascript
javascript 星级评分效果(手写)
Dec 24 Javascript
让jQuery与其他JavaScript库并存避免冲突的方法
Dec 23 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
Oct 28 Javascript
浅析bootstrap原理及优缺点
Mar 19 Javascript
SVG动画vivus.js库使用小结(实例代码)
Sep 14 Javascript
利用vue + element实现表格分页和前端搜索的方法
Dec 25 Javascript
element-ui树形控件后台返回的数据+生成组织树的工具类
Mar 05 Javascript
vue 实现tab切换保持数据状态
Jul 21 Javascript
JavaScript十大取整方法实例教程
Dec 03 Javascript
vue3 自定义图片放大器效果的示例代码
Jul 23 Vue.js
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
Protoss热键控制
2020/03/14 星际争霸
在php中取得image按钮传递的name值
2006/10/09 PHP
PHP flock 文件锁详细介绍
2012/12/29 PHP
php5.5中类级别的常量使用介绍
2013/10/02 PHP
CodeIgniter多语言实现方法详解
2016/01/20 PHP
Yii2分页的使用及其扩展方法详解
2016/05/23 PHP
php无限级分类实现方法分析
2016/10/19 PHP
PHP基于socket实现客户端和服务端通讯功能
2017/07/13 PHP
yii2中关于加密解密的那些事儿
2018/06/12 PHP
thinkPHP框架实现的简单计算器示例
2018/12/07 PHP
Prototype Hash对象 学习
2009/07/19 Javascript
js 页面元素的几个用法总结
2013/11/18 Javascript
javascript实现全角与半角字符的转换
2015/01/07 Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
2015/03/04 Javascript
jQuery EasyUI Dialog拖不下来如何解决
2015/09/28 Javascript
Angular 4根据组件名称动态创建出组件的方法教程
2017/11/01 Javascript
用Axios Element实现全局的请求loading的方法
2018/03/15 Javascript
基于Vue实现拖拽效果
2018/04/27 Javascript
你应该了解的JavaScript Array.map()五种用途小结
2018/11/14 Javascript
Python 实现一个颜色色值转换的小工具
2016/12/06 Python
Python基于time模块求程序运行时间的方法
2017/09/18 Python
详解Python基础random模块随机数的生成
2019/03/23 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
2019/03/30 Python
Python2与Python3的区别点整理
2019/12/12 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
2020/06/11 Python
使用 css3 transform 属性来变换背景图的方法
2019/05/07 HTML / CSS
民族团结先进个人材料
2014/02/05 职场文书
生日寄语大全
2014/04/08 职场文书
2014年党风建设工作总结
2014/11/19 职场文书
大连星海广场导游词
2015/02/10 职场文书
干货!开幕词的写作方法
2019/04/02 职场文书
《飘》英文读后感五篇
2019/10/11 职场文书
慰问信(范文3篇)
2019/10/23 职场文书
python利用pandas分析学生期末成绩实例代码
2021/07/09 Python
MySQL 中如何归档数据的实现方法
2022/03/16 SQL Server
Python采集爬取京东商品信息和评论并存入MySQL
2022/04/12 Python