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函数般调用正则
Apr 08 Javascript
多种方法实现360浏览器下禁止自动填写用户名密码
Jun 16 Javascript
javascript表单验证和Window详解
Dec 11 Javascript
jquery图片轮播特效代码分享
Apr 20 Javascript
jquery+css实现下拉列表功能
Sep 03 jQuery
jQuery实现的粘性滚动导航栏效果实例【附源码下载】
Oct 19 jQuery
Vue Components 数字键盘的实现
Sep 18 Javascript
微信小程序全局变量的设置、使用、修改过程解析
Sep 24 Javascript
从表单校验看JavaScript策略模式的使用详解
Oct 17 Javascript
vue实现前端列表多条件筛选
Oct 26 Javascript
在JavaScript中如何使用宏详解
May 06 Javascript
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
May 25 Vue.js
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中如何判断一个网页请求是ajax请求还是普通请求
2013/08/10 PHP
php中的动态调用实例分析
2015/01/07 PHP
PHP实现获取文件后缀名的几种常用方法
2015/08/08 PHP
微信公众平台开发之配置与请求
2015/08/26 PHP
学习php设计模式 php实现桥梁模式(bridge)
2015/12/07 PHP
jQuery AJAX回调函数this指向问题
2010/02/08 Javascript
jQuery EasyUI API 中文文档 - ComboTree组合树
2011/10/11 Javascript
js 完美图片新闻轮转效果,腾讯大粤网首页图片轮转改造而来
2011/11/21 Javascript
JavaScript的事件绑定(方便不支持js的时候)
2013/10/01 Javascript
JavaScript 实现的 zip 压缩和解压缩工具包Zip.js使用详解
2015/12/14 Javascript
jQuery点击输入框显示验证码图片
2016/05/19 Javascript
webpack+vue.js快速入门教程
2016/10/12 Javascript
微信小程序开发一键登录 获取session_key和openid实例
2016/11/23 Javascript
浅谈js算法和流程控制
2016/12/29 Javascript
jQuery基于ajax操作json数据简单示例
2017/01/05 Javascript
纯原生js实现table表格的增删
2017/01/05 Javascript
微信小程序 登录实例详解
2017/01/16 Javascript
ionic 3.0+ 项目搭建运行环境的教程
2017/08/09 Javascript
详解Webstorm 新建.vue文件支持高亮vue语法和es6语法
2017/10/26 Javascript
vue-i18n结合Element-ui的配置方法
2019/05/20 Javascript
使用 js 简单的实现 bind、call 、aplly代码实例
2019/09/07 Javascript
JavaScript 闭包的使用场景
2020/09/17 Javascript
Python数据类型详解(三)元祖:tuple
2016/05/08 Python
python 3.6.2 安装配置方法图文教程
2018/09/18 Python
Django框架 查询Extra功能实现解析
2019/09/04 Python
pytorch 多分类问题,计算百分比操作
2020/07/09 Python
python从Oracle读取数据生成图表
2020/10/14 Python
神经网络训练采用gpu设置的方式
2021/03/03 Python
狗狗玩具、零食和咀嚼物的月度送货服务:Super Chewer
2018/08/22 全球购物
ManoMano英国:欧洲第一家专注于DIY和园艺市场的电商平台
2020/03/12 全球购物
DIY蛋糕店的创业计划书范文
2013/12/26 职场文书
平民服装店创业计划书
2014/01/17 职场文书
2014年安全生产大检查方案
2014/05/13 职场文书
生产工厂门卫岗位职责
2014/09/26 职场文书
python中使用 unittest.TestCase单元测试的用例详解
2021/08/30 Python
怎么禁用Win11输入法 最新Win11输入法关闭教程
2022/08/05 数码科技