vue+elementUi图片上传组件使用详解

作者:情破 时间:2024-05-10 14:14:49 

上传组件封装需求分析

在基于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端的图片上传相对于小程序 要复杂一点,这个封装只能满足当下单图上传的需求也有他的不足之处。当然也可以扩展为多图上传,关于多图上传的网上也有很多例子。这里不再一一赘述。

来源:https://blog.csdn.net/u014106478/article/details/86020527

标签:vue,elementUi,图片上传
0
投稿

猜你喜欢

  • 如何利用Python开发一个简单的猜数字游戏

    2022-05-21 20:38:08
  • 如何利用 Python 绘制动态可视化图表

    2022-11-23 17:14:37
  • 深入理解Vue官方文档梳理之全局API

    2024-05-05 09:08:25
  • python 实现批量xls文件转csv文件的方法

    2023-08-29 10:25:26
  • Python实现视频中添加音频工具详解

    2022-06-03 12:32:28
  • 用SQL语句解决mysql导入大数据文件的问题

    2024-01-13 05:52:23
  • 添加到各大流行网摘 书签的代码

    2008-04-20 14:15:00
  • Python大数据用Numpy Array的原因解读

    2023-06-19 05:14:00
  • ASP在线转flv+缩略图

    2007-08-27 16:18:00
  • Python实现功能完整的个人员管理程序

    2021-03-26 02:31:15
  • MySQL 出现错误1418 的原因分析及解决方法

    2024-01-27 12:06:34
  • Python+OpenCV内置方法实现行人检测

    2023-10-19 12:52:47
  • 详解pandas.DataFrame中删除包涵特定字符串所在的行

    2023-08-23 23:37:45
  • MySQL transaction事务安全示例讲解

    2024-01-25 17:47:38
  • 常见的在Python中实现单例模式的三种方法

    2022-11-08 01:42:09
  • 一场关于YUI3/jQuery的精彩辩论

    2010-11-11 12:50:00
  • Python实现括号匹配方法详解

    2021-05-01 23:06:58
  • 如何在pyqt中实现全局事件实战记录

    2023-07-01 02:25:46
  • 浅谈numpy中np.array()与np.asarray的区别以及.tolist

    2022-06-06 12:32:10
  • Python扩展内置类型详解

    2023-03-19 17:23:36
  • asp之家 网络编程 m.aspxhome.com