vue项目ElementUI组件中el-upload组件与图片裁剪功能组件结合使用详解
vue项目ElementUI组件中el-upload组件与裁剪功能组件结合使用,供大家参考,具体内容如下
如下图所示,点击上传组件,选择文件后,会立马弹出图片裁剪功能组件的页面
问题描述:
1.在使用upload组件中,如果修改fileList中的内容,浏览器会报错
2.获取上传的文件,传递给图片裁剪组件(在on-change中获取文件并传递个裁剪组件)
3.要获取裁剪后的图片即File文件(将裁剪后的图片返回出去)
4.获取到裁剪后的file调用上传的接口
由于el-upload组件默认使用的是
“选取文件后立即进行上传”,可通过auto-upload属性进行修改,将auto-upload设置为false;
同时也不显示已上传的文件列表,通过show-file-list属性修改,将show-file-list设置为false。
获取上传的组件说明:使用elementUI 提供的方法 on-change,获取已上传的组件
elementUI中upload组件部分属性如下:
关于裁剪组件,请看裁剪组件链接文档
本案例主要代码如下:
<el-form-item label="公司logo" prop="logo"> <el-upload class="avatar-uploader" ref="upload" :action="uploadLogo" :show-file-list="false" :file-list="photoList" :on-change="changePhotoFile" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" :headers="headerObj" :auto-upload="false" > <img v-if="imageUrl" :src="imageUrl" class="avatar"> <div v-else class=" avatar-uploader-icon"> <div> <i class="my-icon-plus"></i> <p class="my-icon-word">添加</p> </div> </div> <!--<i v-else class="el-icon-plus avatar-uploader-icon"></i>--> </el-upload> <my-cropper ref="myCropper" @getFile="getFile" @upAgain="upAgain"></my-cropper> </el-form-item>
对应的方法
changePhotoFile(file, fileList){ if (fileList.length > 0) { this.photoList = [fileList[fileList.length - 1]] } this.handleCrop(file); }, handleCrop(file){ this.$nextTick(()=>{ this.$refs.myCropper.open(file.raw || file) }) }, // 点击弹框重新时触发 upAgain(){ this.$refs['upload'].$refs["upload-inner"].handleClick(); }, getFile(file){ const formData = new FormData(); formData.append("file",file) uploadSelfCompanyLogo(formData).then(res =>{ if (res.code === 0) { this.companyInfo.logo = res.filename; this.companyInfo.imageUrl = res.url; this.imageUrl = res.url; //上传成功后,关闭弹框组件 // this.handleCrop(file); this.$refs.myCropper.close() } else { this.$message.error('上传出错'); } }) },
整个vue代码,包含上面的代码
<template> <div class="form-out"> <el-form :rules="rules" :model="companyInfo" class="form" ref="registForm" label-position="left" label-width="92px" > <div class="personal-info"> <p class="tag"> <span class="light-slash">/</span> <span class="slash">/</span> <span class="tag-main">公司信息</span> <span class="slash">/</span> <span class="light-slash">/</span> </p> <el-form-item label="公司全称" prop="companyName"> <span class="com-name">{{companyInfo.companyName}}</span> </el-form-item> <el-form-item label="公司简称" prop="shortened"> <el-input style="width: 540px;height: 42px" v-model="companyInfo.shortened" placeholder="请填写当前公司简称" clearable ></el-input> </el-form-item> <el-form-item label="行业领域" prop="industry"> <el-select class="inputSelect" v-model="companyInfo.industry" placeholder="请选择行业领域" clearable > <el-option v-for="item in industryOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> <el-form-item label="公司规模" prop="scale"> <el-select class="inputSelect" v-model="companyInfo.scale" placeholder="请选择公司规模" clearable > <el-option v-for="item in scaleOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> <el-form-item label="公司性质" prop="nature"> <el-select v-model="companyInfo.nature" placeholder="请选择公司性质" clearable > <el-option v-for="item in natureOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> <el-form-item label="公司logo" prop="logo"> <el-upload class="avatar-uploader" ref="upload" :action="uploadLogo" :show-file-list="false" :file-list="photoList" :on-change="changePhotoFile" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" :headers="headerObj" :auto-upload="false" > <img v-if="imageUrl" :src="imageUrl" class="avatar"> <div v-else class=" avatar-uploader-icon"> <div> <i class="my-icon-plus"></i> <p class="my-icon-word">添加</p> </div> </div> <!--<i v-else class="el-icon-plus avatar-uploader-icon"></i>--> </el-upload> <my-cropper ref="myCropper" @getFile="getFile" @upAgain="upAgain"></my-cropper> </el-form-item> <el-form-item label="公司简介" prop="intro"> <el-input type="textarea" v-model="companyInfo.intro"></el-input> </el-form-item> </div> <div class="submit"> <el-button class="next-button" type="primary" size="medium" :class="[nextFlag ?'next-button-bg-blue':'next-button-bg-grew']" @click="companyRegister"> 确定 </el-button> <span class="return-back" @click="returnBackFun"> 返回上一步 </span> </div> </el-form> </div> </template> <script> import debounce from "../../../common/debounce"; import DataDict from "../../../common/DataDict"; import {createCompanyBase,uploadSelfCompanyLogo} from '../../../network/request' import MyCropper from "./cropper.vue" export default { name: "ComFormThree", components:{MyCropper}, data(){ //信用代码验证 var checkCreditCode = (rules, value, callback) => { let position = new RegExp(/^([0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}|[1-9]\d{14})$/); if(!position.test(value)) { callback(new Error('请输入正确的统一社会信用代码!')); } else { callback(); } } return{ nextFlag:false, uploadLogo: process.env.VUE_APP_BASE_URL + '/business/pub/iface/uploadCompanyLogo',//上传共公司logo地址 imageUrl: '', companyInfo: { companyName: '', logo:'', creditCode: '', shortened: '', industry:null, scale:null, nature:null, companyId:null, imageUrl:'', intro:'' }, photoList:[], industryOptions:DataDict.industryOptions,//行业领域数据字典 scaleOptions:DataDict.scaleOptions,//公司规模数据字典 natureOptions:DataDict.natureOptions,//公司性质数据字典 rules: { companyName:[ { required: true}, ], creditCode:[ { required: true, message: '请输入统一社会信用代码', trigger: 'blur' }, { validator: checkCreditCode, trigger: 'blur' } ], logo:[{ required: true},], intro:[{ required: true, message: '请填写公司简介',trigger: 'blur' },], shortened:[{ required: true, message: '请填写公司简称',trigger: 'blur'},], industry:[{ required: true, message: '请选择行业领域', trigger: 'change'},], scale: [ { required: true, message: '请选择公司规模', trigger: 'change' } ], nature: [ { required: true, message: '请选择公司性质', trigger: 'change' } ], }, } }, mounted() { // console.log("this.$store.personInfo.companyName",this.$store.getters.personInfo.companyName); this.companyInfo.companyName = this.pCompanyName; }, activated() { this.companyInfo.companyName = this.pCompanyName; }, computed:{ pCompanyName(){ return this.$store.getters.personInfo.companyName; } }, watch:{ companyInfo: { handler(val){ (val.companyName !== '' && val.creditCode !=='' && val.creditCode.length>0 && val.logo !== '' && val.logo.length>0 && val.shortened !== '' && val.shortened.length >0 && val.industry !== null && val.nature !== null && val.scale != null ) ? this.nextFlag = true : this.nextFlag = false; }, deep: true } }, /*mounted() { console.log("uploadLogo====",this.uploadLogo); },*/ methods:{ //上传图片触发 handleCrop(file){ this.$nextTick(()=>{ this.$refs.myCropper.open(file.raw || file) }) }, // 点击弹框重新时触发 upAgain(){ this.$refs['upload'].$refs["upload-inner"].handleClick(); }, getFile(file){ const formData = new FormData(); formData.append("file",file) uploadSelfCompanyLogo(formData).then(res =>{ if (res.code === 0) { this.companyInfo.logo = res.filename; this.companyInfo.imageUrl = res.url; this.imageUrl = res.url; //上传成功后,关闭弹框组件 // this.handleCrop(file); this.$refs.myCropper.close() } else { this.$message.error('上传出错'); } }) // this.$refs.upload.submit(); }, companyRegister:debounce(function () { this.doCompanyRegister(); },500), //下一步 doCompanyRegister(){ this.$store.commit('addcompanyObjInfo',this.companyInfo); createCompanyBase(this.companyInfo).then(res =>{ if (res.code === 0 && res.msg === 'success') { console.log("创建成功"); /*this.$message.success('公司创建成功~'); this.$router.push("/client/auditPage");*/ } }) }, //头像上传成功之后的方法,进行回调 handleAvatarSuccess(res,file) { if (res.code === 0) { this.companyInfo.logo = res.filename; this.companyInfo.imageUrl = res.url; this.imageUrl = res.url; // this.handleCrop(file); } else { this.$message.error('上传出错'); } }, //上传图片时会被调用 changePhotoFile(file, fileList){ if (fileList.length > 0) { this.photoList = [fileList[fileList.length - 1]] } this.handleCrop(file); }, //头像上传之前的方法 beforeAvatarUpload(file) { const isJPG = file.type === 'image/jpeg' || 'image/jpg' || 'image/gif' || 'image/png'; const isLt6M = file.size / 1024 / 1024 < 6; if (!isJPG) { this.$message.error( '上传头像图片只能是 JPG、JPEG、GIF或PNG 格式!' ); } if (!isLt6M) { this.$message.error('上传头像图片大小不能超过 6MB!'); } console.log("275==",file) return isJPG && isLt6M; }, //返回上一步 returnBackFun(){ let obj = {formType:3} this.$emit("returnBackTwo",obj) } } } </script> <style scoped lang="less"> .form-out{ width: 1100px; border-radius: 10px; background: #fff; .form { padding: 40px 120px; margin: 0 auto; display: table; .tag { text-align: center; margin: 0 0 40px 0; .tag-main{ display: inline-block; font-size:16px; font-family:PingFangSC-Semibold,PingFang SC; font-weight:600; color:#222222; padding: 0 10px } .slash { color: #437FFF; font-weight: bold; font-size: 16px; } .light-slash { color: #437fff; font-weight: bold; font-size: 16px; opacity: 0.5; } } .com-name{ display: inline-block; /*width:224px;*/ height:22px; font-size:16px; font-family:PingFangSC-Regular,PingFang SC; font-weight:400; color:rgba(51,51,51,1); line-height:22px; } .avatar { width: 80px; height: 80px; /* border-radius: 30px;*/ vertical-align: middle; } .avatar-desc { color: #999; font-size: 12px; padding-left: 10px; } .tag-other { margin-top: 40px; } .submit { display: flex; justify-content: center; margin-top: 40px; .submit-button { background: #437FFF; width: 390px; margin-top: 20px; font-size: 22px; } .next-button{ width:140px; height:42px; border-radius:6px; font-size:16px; color: #999999; border: 1px solid transparent; font-family:PingFangSC-Regular,PingFang SC; font-weight:400; } .return-back{ display: inline-block; height:42px; line-height: 42px; width:70px; font-size:14px; font-family:PingFangSC-Medium,PingFang SC; font-weight:500; color:rgba(102,102,102,1); margin-left: 50px; &:hover{ cursor: pointer; } } .next-button-bg-grew{ background:#E5E5E5; } .next-button-bg-blue{ background:#437FFF; color:#FFFFFF } } } } </style> <style scoped> .el-input__inner { width:540px; height:42px; background:rgba(249,249,249,1); border-radius:2px; border: 1px solid transparent; } .el-form-item__label{ font-size:16px; font-family:PingFangSC-Regular,PingFang SC; font-weight:400; color:#222222; } input::-webkit-input-placeholder { height:21px; font-size:15px; font-weight:400; color:rgba(204,204,204,1); line-height:21px; } input::-ms-input-placeholder { height:21px; font-size:15px; font-weight:400; color:rgba(204,204,204,1); line-height:21px; } .my-icon-plus{ background: url("../../../assets/img/upload/upload_plus.png") no-repeat; background-size: 24px 24px; width: 24px; height: 24px; display: inline-block; } .my-icon-word{ height:17px; font-size:12px; font-family:PingFangSC-Regular,PingFang SC; font-weight:400; color:#437FFF; line-height:17px; } </style> <style > .form-out .avatar-uploader .el-upload { /*border: 1px dashed #d9d9d9;*/ border: 1px dashed #437FFF; border-radius: 6px; cursor: pointer; position: relative; /* overflow: hidden;*/ } .form-out .avatar-uploader .el-upload:hover { border-color: #409EFF; } .form-out .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 80px; height: 80px; text-align: center; display: flex; align-items: center; justify-content: center; } .form-out .avatar { width: 80px; height: 80px; display: block; } </style>
上一篇:Vue实现文本展开收起功能
栏 目:vue
下一篇:vue filters和directives访问this的问题详解
本文标题:vue项目ElementUI组件中el-upload组件与图片裁剪功能组件结合使用详解
本文地址:http://www.codeinn.net/misctech/226737.html