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向上无缝滚动,网站公告效果 具体代码
Nov 18 Javascript
js数组去重的常用方法总结
Jan 24 Javascript
判断日期是否能跨月查询的js代码
Jul 25 Javascript
angularjs基础教程
Dec 25 Javascript
基于JavaScript实现快速转换文本语言(繁体中文和简体中文)
Mar 07 Javascript
jquery 属性选择器(匹配具有指定属性的元素)
Sep 06 Javascript
JS中Swiper的使用和轮播图效果
Aug 11 Javascript
Vue的百度地图插件尝试使用
Sep 06 Javascript
vue实现拖拽效果
Dec 23 Javascript
微信小程序实现录制、试听、上传音频功能(带波形图)
Feb 27 Javascript
.netcore+vue 实现压缩文件下载功能
Sep 24 Javascript
React实现动效弹窗组件
Jun 21 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
晶体管单管来复再生式收音机
2021/03/02 无线电
php中使用array_filter()函数过滤空数组的实现代码
2014/08/19 PHP
一个图片地址分解程序(用于PHP小偷程序)
2014/08/23 PHP
THINKPHP项目开发中的日志记录实例分析
2014/12/01 PHP
ThinkPHP框架里隐藏index.php
2016/04/12 PHP
Thinkphp5.0 框架Model模型简单用法分析
2019/10/11 PHP
用javascript动态调整iframe高度的代码
2007/04/10 Javascript
基于Jquery的标签智能验证实现代码
2010/12/27 Javascript
js编码、解码函数介绍及其使用示例
2013/09/05 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
2014/05/08 Javascript
cookie的secure属性详解
2015/04/08 Javascript
node.js读取文件到字符串的方法
2015/06/29 Javascript
Express的路由详解
2015/12/10 Javascript
jQuery实现的给图片点赞+1动画效果(附在线演示及demo源码下载)
2015/12/31 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
2016/11/06 Javascript
node.js中EJS 模板快速入门教程
2017/05/08 Javascript
微信小程序之购物车功能
2020/09/23 Javascript
Ionic3 UI组件之autocomplete详解
2017/06/08 Javascript
js解决软键盘遮挡输入框的问题分享
2017/12/19 Javascript
微信小程序实现获取准确的腾讯定位地址功能示例
2019/03/27 Javascript
微信小程序如何实现五星评价功能
2019/10/15 Javascript
JS时间戳与日期格式互相转换的简单方法示例
2021/01/30 Javascript
[05:01]3.19DOTA2发布会 我们都是刀塔人
2014/03/25 DOTA
Python通过90行代码搭建一个音乐搜索工具
2015/07/29 Python
Python绘图Matplotlib之坐标轴及刻度总结
2019/06/28 Python
Python 面向对象静态方法、类方法、属性方法知识点小结
2020/03/09 Python
求职简历中个人的自我评价
2013/12/01 职场文书
职员竞岗演讲稿
2014/05/14 职场文书
银行服务明星推荐材料
2014/05/29 职场文书
无子女夫妻离婚协议书(4篇)
2014/10/20 职场文书
酒店财务总监岗位职责
2015/04/03 职场文书
运动会200米广播稿
2015/08/19 职场文书
使用Django实现商城验证码模块的方法
2021/06/01 Python
详细谈谈MYSQL中的COLLATE是什么
2021/06/11 MySQL
船舶调度指挥系统——助力智慧海事
2022/02/18 无线电
MySQL 计算连续登录天数
2022/05/11 MySQL