vue+elementUi图片上传组件使用详解


Posted in Javascript onAugust 20, 2019

上传组件封装需求分析

在基于elementUI库做的商城后台管理中,需求最大的是商品管理表单这块,因为需要录入各种各样的商品图片信息。加上后台要求要传递小于2M的图片,因此封装了一个upload.vue组件作为上传页面的子组件,它用于管理图片上传逻辑。

upload.vue解析

upload主要用于实现表单上传图片的需求,主要由input +img 构成当没有图片的时候显示默认图片,有图片则显示上传图片,因为input样式不太符合需求所以只是将起设置为不可见,不能将其设置为display:none。否则将将无法触发input的change事件

upload.vue代码如下:

<template>
 <div>
 <div class="upload-box" :style="imgStyle">
 <!-- 用户改变图片按钮的点击 触发上传图片事件 -->
 <input type="file" :ref="imgType$1" @change="upload(formVal$1,imgType$1)" class="upload-input" />
 <!-- img 的 src 用于渲染一个 图片路径 传入图片路径 渲染出图片 -->
 <img :src="formVal$1[imgType$1]?formVal$1[imgType$1]:'static/img/upload.jpg'" />
 </div>
 </div>
</template>
<script>
/* 
 该组件因为要上传多个属性的图片 主图(mainImg) 详细图(detailImg) 规格图 (plusImg) 
 该组件基于压缩插件lrz,所以下方打入该组件
 npm install lrz --save 即可
*/
import lrz from 'lrz';
export default {
 name: 'uploadImg', //组件名字
 props: {
  formVal: {
   type: Object, //props接受对象类型数据(表单对象也可以是纯对象类型)
   required: true,
   default: {}
  },
  imgType: {    //表单对象中的图片属性 example:mainImg
   type: String,
   required: true,
   default: ''
  },
  imgStyle: {
   type: Object,  // 用于显示的图片的样式 
   required: true //必须传递
  }
 },
 created: function() {
  //生命周期函数 
 },
 data: function() {
  /*
   因为该组件需要改变父组件传递过来的值,
   所以将起拷贝一份
  */
  let formVal$1 = this.formVal;
  let imgType$1 = this.imgType;
  return {
   formVal$1,
   imgType$1,
   uploadUrl: url,//你的服务器url地址
  };
 },
 methods: {
  upload: function(formVal, imgType) {
   var self = this;
   //图片上传加载我们在这里加入提示,下方需要主动关闭,防止页面卡死
   var loadingInstance = this.$loading({
    text: '上传中'
   });
   var that = this.$refs[imgType].files[0]; //文件压缩file
   //图片上传路径
   var testUrl = this.uploadUrl; //图片上传路径
   try {
    //lrz用法和上一个一样也是一个压缩插件来的
    lrz(that)
     .then(function(message) {
      var formData = message.formData; //压缩之后我们拿到相应的formData上传
      self.$axios
       .post(testUrl, formData)
       .then(function(res) {
        console.log(res);
        if (res && res.data.iRet == 0) {
         formVal[imgType] = res.data.objData.sUrl;
         //上传成功之后清掉数据防止下次传相同图片的时候不触发change事件 
         self.$refs[imgType].value = '';
         /*
          这里因为使用elementUI中的表单验证,
          当上传图片完成之后还会提示没有上传图片
          所以需要通知父组件清除该验证标记 
          */
         self.$emit('clearValidate', imgType);
         self.$nextTick(() => {
          // 以服务的方式调用的 Loading 需要异步关闭
          loadingInstance.close();
         });
        } else {
         throw res.data.sMsg;
        }
       })
       .catch(function(err) {
        self.$nextTick(() => {
         // 以服务的方式调用的 Loading 需要异步关闭
         loadingInstance.close();
        });
        //接口报错弹出提示
        alert(err);
       });
     })
     .catch(function(err) {
      self.$nextTick(() => {
       loadingInstance.close();
      });
     });
   } catch (e) {
    //关闭加载动画实例
    self.$nextTick(() => {
     loadingInstance.close();
    });
   }
  }
 },
 mounted: function() {},
 watch: {
  /*
  这里需要注意当父组件上传一个图片然后通过重置按钮重置的时候.
   我们需要监听一下,防止上传同一张图片上传失败
  */
  formVal: {
   handle: function(newVal, oldVal) {
    var imgType = this.imgType;
    if (newVal[imgType] == '') {
     //这里使用了原生js写法当然也可以通过ref引用找到,后者更好
     document.getElementsByClassName('upload-input')[0].value = '';
    }
   }
  }
 }
};
</script>
<style scoped>
/*
 这里是默认的设置图片的尺寸。可以通过父组件传值将其覆盖
*/
.upload-box {
 position: relative;
 height: 100px;
 width: 100px;
 overflow: hidden;
}

.upload-box img {
 width: 100%;
 height: 100%;
}

.upload-box .upload-input {
 position: absolute;
 left: 0;
 opacity: 0;
 width: 100%;
 height: 100%;
}
</style>

商品页中使用upload组件

good.vue中我们引入upload组件。并且传递相应表单对象,需上传的图片类型的属性,以及图片显示样式给子组件

good.vue核心代码:

<template>
 <el-form ref="form" :model="form" label-width="80px" label-position="top" :rules="rules">
 <!-- 无关代码略 -->
 <el-form-item label="详情图" prop="sDetailImg" ref="sDetailImg">
  <uploadImg :form-val="form" :img-type="'sDetailImg'" :img-style="detailImgStl" @clearValidate="clearValidate"></uploadImg>
 </el-form-item>
 <el-form-item>
  <el-row style="text-align:center;">
  <el-button type="primary" size="medium" @click.stop="submit('form')" v-if="!form.ID">保存</el-button>
  <el-button type="primary" size="medium" @click.stop="submit('form')" v-else-if="form.ID">修改</el-button>
  <el-button size="medium" @click.stop="resetForm('form')">重置</el-button>
  </el-row>
 </el-form-item>
 </el-form>
 <!-- 略 -->
</template>
<script>
 import uploadImg from "../common/uploadImg"; //图片上传
 export default {
 name: "good", //组件名字用户缓存 
 data: function() {
  return {
  form: {
  ID: NULL,
  //其他字段略
  sDetailImg: "" //商品详细图
  },
  detailImgStl: {
  width: "350px",
  height: "150px"
  },
  rules: {
  sDetailImg: [{
  required: true,
  message: "请填写详细图信息",
  trigger: "change"
  }],
  }
  }
 },
 methods: {
  //这里监听子组件回写的信息,用户清除上传成功之后还显示图片未上传的bug
  clearValidate: function(imgName) {
  //清空图片上传成功提示图片没有上传的验证字段
  this.$refs[imgName].clearValidate();
  },
  //重置表单
  resetForm: function(formName) {
  this.confirm("确认重置表单", function(self) {
  self.$refs[formName].resetFields();
  })

  }
 },
 }
</script>

写在最后

关于图片上传之前我也写过一个小程序版本,总体看来pc端的图片上传相对于小程序 要复杂一点,这个封装只能满足当下单图上传的需求也有他的不足之处。当然也可以扩展为多图上传,关于多图上传的网上也有很多例子。这里不再一一赘述。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 联动的无限级封装类,数据采用非Ajax方式,随意添加联动
Jun 29 Javascript
Javascript中 关于prototype属性实现继承的原理图
Apr 16 Javascript
jQuery scrollFix滚动定位插件
Apr 01 Javascript
JS实现完全语义化的网页选项卡效果代码
Sep 15 Javascript
基于jQuery下拉选择框插件支持单选多选功能代码
Jun 07 Javascript
如何解决hover在ie6中的兼容性问题
Dec 15 Javascript
ReactJs设置css样式的方法
Jun 08 Javascript
js实现网页的两个input标签内的数值加减(示例代码)
Aug 15 Javascript
详解webpack性能优化——DLL
Oct 20 Javascript
vue微信分享 vue实现当前页面分享其他页面
Dec 02 Javascript
详解webpack运行Babel教程
Jun 13 Javascript
vue全局自定义指令-元素拖拽的实现代码
Apr 14 Javascript
vue集成chart.js的实现方法
Aug 20 #Javascript
微信小程序实现定位及到指定位置导航的示例代码
Aug 20 #Javascript
微信小程序使用车牌号输入法的示例代码
Aug 20 #Javascript
JS中的算法与数据结构之字典(Dictionary)实例详解
Aug 20 #Javascript
Vue实现购物车详情页面的方法
Aug 20 #Javascript
详解解决小程序中webview页面多层history返回问题
Aug 20 #Javascript
JavaScript使用表单元素验证表单的示例代码
Aug 20 #Javascript
You might like
PHP iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
分享一个php 的异常处理程序
2014/06/22 PHP
PHP连接MySQL数据库操作代码实例解析
2020/07/11 PHP
jQuery 使用手册(六)
2009/09/23 Javascript
juqery 学习之三 选择器 可见性 元素属性
2010/11/25 Javascript
对JavaScript客户端应用编程的一些建议
2015/06/24 Javascript
JavaScript类型系统之布尔Boolean类型详解
2016/06/26 Javascript
JQuery.validationEngine表单验证插件(推荐)
2016/12/10 Javascript
基于jQuery实现照片墙自动播放特效
2017/01/12 Javascript
Javascript中document.referrer隐藏来源的方法
2017/01/16 Javascript
Javascript中click与blur事件的顺序详析
2017/04/25 Javascript
详解ES6之用let声明变量以及let loop机制
2017/07/15 Javascript
jQuery读取本地的json文件(实例讲解)
2017/10/31 jQuery
在vue项目中使用Jquery-contextmenu插件的步骤讲解
2019/01/27 jQuery
JavaScript数据结构与算法之二叉树插入节点、生成二叉树示例
2019/02/21 Javascript
详解JavaScript的数据类型以及数据类型的转换
2019/04/20 Javascript
实用Javascript调试技巧分享(小结)
2019/06/18 Javascript
node.js实现上传文件功能
2019/07/15 Javascript
vue实现列表滚动的过渡动画
2020/06/29 Javascript
python在linux中输出带颜色的文字的方法
2014/06/19 Python
python爬虫_微信公众号推送信息爬取的实例
2017/10/23 Python
Python中enumerate函数代码解析
2017/10/31 Python
numpy 返回函数的上三角矩阵实例
2019/11/25 Python
Python学习之time模块的基本使用
2021/01/17 Python
Farfetch阿联酋:奢侈品牌时尚购物平台
2019/07/26 全球购物
Linux上比较文件的命令都有哪些
2012/02/24 面试题
建筑工程专业毕业生自荐信
2013/10/19 职场文书
技术学校毕业生求职信分享
2013/12/02 职场文书
电话销售经理岗位职责
2013/12/07 职场文书
写好自荐信的几个要点
2013/12/26 职场文书
应用艺术专业个人的自我评价
2014/01/03 职场文书
学习自我鉴定
2014/02/01 职场文书
公共机构节能宣传周活动总结
2014/07/09 职场文书
2019新员工试用期转正工作总结范文
2019/08/21 职场文书
导游词之上饶龟峰
2019/10/25 职场文书
vue实现锚点定位功能
2021/06/29 Vue.js