前言:使用element上传图片以后,文件file下的url是blob:http//localhost:8080地址,后端很差处理css
问题如上图所示html
采用比较笨的js解决方法,将bolb文件打开,读取src属性(这是一个base64的数据流),把src的内容一块儿发送给后端。node
这是一个上传图片子组件demoajax
<template> <el-upload class="upload-demo" action="" ref="upload" :auto-upload='false' :on-change='changeUpload' accept="image/jpeg,image/gif,image/png,image/bmp"> <div size="small" class="upload_btn"><div style="height:40px"></div><i class="iconfont icon-jiahao"></i><p style="line-height:0">点击上传</p></div> </el-upload> </template> <script> export default { name: 'regShopImg', data () { return { imageUrl: '', imgthing: {} } }, props: ['imgN', 'nameN'], methods: { changeUpload (file, fileList) { console.log(file) // 判断图片大小 if (fileList[0].size < 1100000) { // 判断图片格式是否为jpg,png,jepg,gif var fileName=fileList[0].name // var suffixIndex=fileName.lastIndexOf(".") // var suffix=fileName.substring(suffixIndex+1).toUpperCase() var suffix = fileName.substring(fileName.lastIndexOf(".")+1).toUpperCase() if (suffix=="BMP"||suffix=="JPG"||suffix=="JPEG"||suffix=="PNG"||suffix=="GIF") { this.fileList = fileList this.$nextTick( () => { var i = this.imgN let uploadLists = document.getElementsByClassName('el-upload-list') let uploadListsN = uploadLists[i] let uploadListLi = uploadListsN.children uploadListsN.setAttribute('style', 'position: absolute;height: 160px;margin-top: 0;margin-left: 300px;width: 260px;overflow: hidden') let liA = uploadListLi[0] // 试着获取bolb里面的数据------------S //获取图片的Blob值 function getImageBlob(url, cb) { var xhr = new XMLHttpRequest() xhr.open("get", url, true) xhr.responseType = "blob" xhr.onload = function() { if (this.status == 200) { if(cb) cb(this.response) } } xhr.send() } function preView(url){ let reader = new FileReader() getImageBlob(url, function(blob){ reader.readAsDataURL(blob) }) reader.onload = function(e) { // 获取bolb里面数据时,生成预览 var img = document.createElement("img") img.src = e.target.result // 获取bolb里面数据时,生成预览 let imgElement = document.createElement('img') imgElement.setAttribute('src', fileList[0].url) imgElement.setAttribute('style', 'max-width:100%;padding-left:0') if (liA.lastElementChild.nodeName !== 'IMG') { liA.appendChild(imgElement) } // 把base64的信息放到imgthing的file里 file.base64 = e.target.result } } preView(fileList[0].url) // 试着获取bolb里面的数据-------------E // 不获取bolb里面数据时,生成预览 // let imgElement = document.createElement('img') // imgElement.setAttribute('src', fileList[0].url) // imgElement.setAttribute('style', 'max-width:100%;padding-left:0') // if (liA.lastElementChild.nodeName !== 'IMG') { // liA.appendChild(imgElement) // } } ) // 修改nameN名字对应的数据,在一个页面使用多个不一样字段图片上传,为了复用组件 if (this.nameN === 'identityCard_Z') { this.imgthing.identityCard_Z = file } if (this.nameN === 'identityCard_F') { this.imgthing.identityCard_F = file } if (this.nameN === 'identityCard_S') { this.imgthing.identityCard_S = file } this.$emit('imgthing', this.imgthing) } else { this.$message.error('文件类型不正确,请从新上传!') } } else { this.$message.error('图片大小超过1M,请从新上传') } } } } </script> <style scoped lang="scss"> // 上传 .upload-demo{width:260px;height:160px; .upload_btn{width:260px;height:160px;background:#f2f2f2} .el-upload__tip{margin:0;float:left} } </style>
父组件上传demo后端
<template> <!-- 表单信息 --> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <!-- 第三步-提交资质内容 --> <div v-if="this.active === 3"> <el-form-item label="身份证号码" prop="identityCard"> <el-input type="identity" v-model="ruleForm.identityCard" style="width:260px" placeholder="请输入身份证号"></el-input> </el-form-item> <el-form-item label="身份证正面" prop="identityCard_Z"> <RegShopImg :imgN='0' :nameN='identityCard_Z' @imgthing = 'imgthing' v-model="ruleForm.identityCard_Z"></RegShopImg> </el-form-item> <el-form-item label="身份证反面" prop="identityCard_F"> <RegShopImg :imgN='1' :nameN='identityCard_F' @imgthing = 'imgthing' v-model="ruleForm.identityCard_F"></RegShopImg> </el-form-item> <el-form-item label="手持身份证" prop="identityCard_S"> <RegShopImg :imgN='2' :nameN='identityCard_S' @imgthing = 'imgthing' v-model="ruleForm.identityCard_S"></RegShopImg> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')" class="btn_submit">提 交 资 质</el-button> </el-form-item> </div> </el-form> </template> <script> import RegShopImg from '@/components/common/regShopImg' //上传图片的子组件 import Qs from 'qs' // post方式下引入qs插件字符串化传输信息 export default { name: 'regShop', data () { return { active: 3, // 分步骤走的断定 ajaxRegisterUrl: '', // 注册提交页面 imgN: '', // 上传信息的名字对应的index序号 nameN: '', // 上传信息的名字 identityCard_Z: 'identityCard_Z', identityCard_F: 'identityCard_F', identityCard_S: 'identityCard_S', Imgthing: {}, //子组件上传的信息 ruleForm: { // 提交信息的表单对象 identityCard_Z: '', identityCard_F: '', identityCard_S: '', }, rules: { // 必填断定规则 identityCard_Z: [ {required: true, message: '请上传身份证正面图片', trigger: 'blur'} ], identityCard_F: [ {required: true, message: '请上传身份证反面图片', trigger: 'blur'} ], identityCard_S: [ {required: true, message: '请上传手持身份证图片', trigger: 'blur'} ] } } }, methods: { // 第三步:证件照片上传 imgthing (imgthing) { // 合并对象 this.Imgthing = Object.assign(this.Imgthing, imgthing) // 填充到ruleForm对应项,用来判断是否有数据 this.ruleForm.identityCard_Z = this.Imgthing.identityCard_Z this.ruleForm.identityCard_F = this.Imgthing.identityCard_F this.ruleForm.identityCard_S = this.Imgthing.identityCard_S }, // 总表单提交 submitForm (formName) { this.$refs[formName].validate((valid) => { if (valid) { // 因为base64的数据流比较大,get方式放不下,必须采用post方式 let data = Qs.stringify(this.ruleForm) this.$ajax.post(this.ajaxRegisterUrl, data) .then((res) => { console.log(res) if (res.status === 1) { this.$message.success('恭喜您,注册成功!') } }) } else { this.$message.error('提交资料有误,注册失败!') return false } }) } }, components: { 'RegShopImg': RegShopImg } } </script> <style scoped lang="scss"> </style>
多添加了一个base64的数据app
另外一种思路是利用element已有的方式,将图片上传和表单上传分开。ide
图片上传只上传文件,利用上传成功handleAvatarSuccess(res, file)的方法,获取后端对上传图片存储位置的路径,并将其传给父组件。提交表单的时候,提交图片部分仅仅是路径。post
1.js 获取图片url的Blob值并预览:https://www.cnblogs.com/tujia/p/6483255.html ui