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 相关文章推荐
js AspxButton的客户端操作
Jun 26 Javascript
jQuery 表单验证扩展代码(二)
Oct 20 Javascript
js异常捕获方法介绍
Apr 10 Javascript
jquery如何判断表格同一列不同行input数据是否重复
May 14 Javascript
jquery获得当前html页面源码的方法
Jul 14 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
Sep 28 Javascript
webstrom Debug 调试vue项目的方法步骤
Jul 17 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
Sep 20 Javascript
js中的reduce()函数讲解
Jan 18 Javascript
详解vue挂载到dom上会发生什么
Jan 20 Javascript
微信小程序实现点击按钮后修改颜色
Dec 05 Javascript
小程序实现背景音乐播放和暂停
Jun 19 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
人族 Terran 基本策略
2020/03/14 星际争霸
php&amp;java(一)
2006/10/09 PHP
PHP中header和session_start前不能有输出原因分析
2013/01/11 PHP
php使用gettimeofday函数返回当前时间并存放在关联数组里
2015/03/19 PHP
PHP编程计算文件或数组中单词出现频率的方法
2017/05/22 PHP
php精度计算的问题解析
2019/06/21 PHP
学习JS面向对象成果 借国庆发布个最新作品与大家交流
2009/10/03 Javascript
js 动态加载事件的几种方法总结
2013/12/25 Javascript
JS数组的赋值介绍
2014/03/10 Javascript
jquery css 设置table的奇偶行背景色示例
2014/06/03 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
JavaScript常用小技巧小结
2014/12/29 Javascript
JQuery点击行tr实现checkBox选中的简单实例
2016/05/26 Javascript
微信小程序Server端环境配置详解(SSL, Nginx HTTPS,TLS 1.2 升级)
2017/01/12 Javascript
vue移动端城市三级联动组件使用详解
2019/07/26 Javascript
JavaScript装饰者模式原理与用法实例详解
2020/03/09 Javascript
微信小程序连接服务器展示MQTT数据信息的实现
2020/07/14 Javascript
python实现按任意键继续执行程序
2016/12/30 Python
详解python中executemany和序列的使用方法
2017/08/12 Python
numpy使用技巧之数组过滤实例代码
2018/02/03 Python
python 缺失值处理的方法(Imputation)
2019/07/02 Python
python命名空间(namespace)简单介绍
2019/08/10 Python
解决django接口无法通过ip进行访问的问题
2020/03/27 Python
GLAMGLOW格莱魅美国官网:美国知名的面膜品牌
2016/12/31 全球购物
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
Urban Outfitters德国官网:美国跨国生活方式零售公司
2018/05/21 全球购物
日本订房网站,预订日本星级酒店/温泉旅馆:Relux(支持中文)
2020/01/03 全球购物
Miller Harris官网:英国小众香水品牌
2020/09/24 全球购物
英国最受欢迎的母婴精品品牌:JoJo Maman BéBé
2021/02/17 全球购物
文明礼仪小标兵事迹
2014/01/12 职场文书
走进敬老院活动总结
2014/07/10 职场文书
谢师宴答谢词
2015/01/05 职场文书
接待员岗位职责范本
2015/04/15 职场文书
网吧温馨提示
2015/07/17 职场文书
解决numpy数组互换两行及赋值的问题
2021/04/17 Python
springboot @ConfigurationProperties和@PropertySource的区别
2021/06/11 Java/Android