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 相关文章推荐
jQuery的.live()和.die() 使用介绍
Sep 10 Javascript
JS简单实现多级Select联动菜单效果代码
Sep 06 Javascript
node.js实现爬虫教程
Aug 25 Javascript
JavaScript用二分法查找数据的实例代码
Jun 17 Javascript
封装运动框架实战左右与上下滑动的焦点轮播图(实例)
Oct 17 Javascript
详解Webpack实战之构建 Electron 应用
Dec 25 Javascript
angular4自定义表单控件[(ngModel)]的实现
Nov 23 Javascript
通过实例讲解JS如何防抖动
Jun 15 Javascript
解决layui-table单元格设置为百分比在ie8下不能自适应的问题
Sep 28 Javascript
Node.js API详解之 dns模块用法实例分析
May 15 Javascript
express异步函数异常捕获示例详解
Nov 30 Javascript
three.js 实现露珠滴落动画效果的示例代码
Mar 01 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
什么是短波收听SWL
2021/03/01 无线电
关于JavaScript的面向对象和继承有利新手学习
2013/01/11 Javascript
利用javascript实现web页面中指定区域打印
2013/10/30 Javascript
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
Google Maps API地图应用示例分享
2014/10/23 Javascript
javascript中Number对象的toString()方法分析
2014/12/20 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
javascript函数式编程程序员的工具集
2015/10/11 Javascript
JavaScript中字面量与函数的基本使用知识
2015/10/20 Javascript
jquery实现模拟百分比进度条渐变效果代码
2015/10/29 Javascript
jQuery自定义图片缩放拖拽插件imageQ实现方法(附demo源码下载)
2016/05/27 Javascript
AngularJS操作键值对象类似java的hashmap(填坑小结)
2016/11/12 Javascript
vue2.0开发实践总结之入门篇
2016/12/06 Javascript
jquery 禁止鼠标右键并监听右键事件
2017/04/27 jQuery
Vue2.x中的Render函数详解
2017/05/30 Javascript
在vue-cli脚手架中配置一个vue-router前端路由
2017/07/03 Javascript
vue中配置mint-ui报css错误问题的解决方法
2017/10/11 Javascript
详解create-react-app 自定义 eslint 配置
2018/06/07 Javascript
在layui tab控件中载入外部html页面的方法
2019/09/04 Javascript
原生js实现下拉框选择组件
2021/01/20 Javascript
Python实现批量把SVG格式转成png、pdf格式的代码分享
2014/08/21 Python
python读取文本中数据并转化为DataFrame的实例
2018/04/10 Python
Python数据分析:手把手教你用Pandas生成可视化图表的教程
2018/12/15 Python
使用python对文件中的单词进行提取的方法示例
2018/12/21 Python
Python利用PyExecJS库执行JS函数的案例分析
2019/12/18 Python
Python读入mnist二进制图像文件并显示实例
2020/04/24 Python
HTML5之WebGL 3D概述(下)—借助类库开发及框架介绍
2013/01/31 HTML / CSS
希腊香水和化妆品购物网站:Parfimo.gr
2019/10/03 全球购物
No7 Beauty美国官网:英国国民护肤品牌
2019/10/31 全球购物
Stührling手表官方网站:男女高品质时尚手表的领先零售商
2021/01/07 全球购物
威盛公司软件C++工程师笔试题面试题
2012/07/16 面试题
linux面试题参考答案(5)
2016/11/05 面试题
会计电算化专业个人的自我评价
2013/11/24 职场文书
竞聘演讲稿精彩开头和结尾
2014/05/14 职场文书
springboot项目以jar包运行的操作方法
2021/06/30 Java/Android
Redis 异步机制
2022/05/15 Redis