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 相关文章推荐
document 和 document.all 分别什么时候用
Jun 22 Javascript
为jquery.ui.dialog 增加“自动记住关闭时的位置”的功能
Nov 24 Javascript
js 实现图片预加载(js操作 Image对象属性complete ,事件onload 异步加载图片)
Mar 25 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
Dec 25 Javascript
Bootstrap选项卡与Masonry插件的完美结合
Jul 06 Javascript
Sequelize中用group by进行分组聚合查询
Dec 12 Javascript
JavaScript之class继承_动力节点Java学院整理
Jul 03 Javascript
基于javaScript的this指向总结
Jul 22 Javascript
jQuery zTree插件快速实现目录树
Aug 16 jQuery
js中script的上下放置区别,Dom的增删改创建操作实例分析
Dec 16 Javascript
基于node+websocket+html实现腾讯课堂聊天室聊天功能
Mar 04 Javascript
vue使用map代替Aarry数组循环遍历的方法
Apr 30 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警告Cannot use a scalar value as an array的解决方法
2012/01/11 PHP
php中sprintf与printf函数用法区别解析
2014/02/17 PHP
php记录搜索引擎爬行记录的实现代码
2018/03/02 PHP
utf8的编码算法 转载
2006/12/27 Javascript
ext实现完整的登录代码
2008/08/08 Javascript
jQuery 第二课 操作包装集元素代码
2010/03/14 Javascript
js浮动图片的动态效果
2013/07/10 Javascript
文本框(input)获取焦点(onfocus)时样式改变的示例代码
2014/01/10 Javascript
jquery if条件语句的写法
2016/05/19 Javascript
JavaScript每天必学之基础知识
2016/09/17 Javascript
浅谈js在html中的加载执行顺序,多个jquery ready执行顺序
2016/11/26 Javascript
Vue.js第三天学习笔记(计算属性computed)
2016/12/01 Javascript
详解vue与后端数据交互(ajax):vue-resource
2017/03/16 Javascript
require.js中的define函数详解
2017/07/10 Javascript
修改vue+webpack run build的路径方法
2018/09/01 Javascript
详解Vue.js使用Swiper.js在iOS
2018/09/10 Javascript
vue实现动态列表点击各行换色的方法
2018/09/13 Javascript
js实现文章目录索引导航(table of content)
2020/05/10 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
JavaScript实现简单日历效果
2020/09/11 Javascript
vue element和nuxt的使用技巧分享
2021/01/14 Vue.js
python基础教程之python消息摘要算法使用示例
2014/02/10 Python
Python脚本实现自动发带图的微博
2016/04/27 Python
python人民币小写转大写辅助工具
2018/06/20 Python
在Python中输入一个以空格为间隔的数组方法
2018/11/13 Python
python暴力解压rar加密文件过程详解
2019/07/05 Python
详解用Python调用百度地图正/逆地理编码API
2020/07/02 Python
python+selenium+chrome实现淘宝购物车秒杀自动结算
2021/01/07 Python
详解HTML5 录音的踩坑之旅
2017/12/26 HTML / CSS
英国的领先快速时尚零售商:In The Style
2019/03/25 全球购物
汇智创新科技发展有限公司
2015/12/06 面试题
运动会通讯稿150字
2014/02/15 职场文书
留学推荐信范文
2014/05/10 职场文书
2015年前台文员工作总结
2015/05/18 职场文书
小学学习委员竞选稿
2015/11/20 职场文书
高中政治教师教学反思
2016/02/23 职场文书