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

上传组件封装需求分析

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

以上是 vue+elementUi图片上传组件使用详解 的全部内容, 来源链接: utcz.com/z/341943.html

回到顶部