vue项目ElementUI组件中el-upload组件与图片裁剪功能组件结合使用详解

 更新时间:2022年03月31日 11:38:34   作者:帅_帅  
这篇文章主要介绍了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 cli3.0创建Vue项目的简单过程记录

    Vue cli3.0创建Vue项目的简单过程记录

    Vue CLI是一个基于Vue.js进行快速开发的完整系统,下面这篇文章主要给大家介绍了关于Vue cli3.0创建Vue项目的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • vue如何实现清空this.$route.query的值

    vue如何实现清空this.$route.query的值

    这篇文章主要介绍了vue如何实现清空this.$route.query的值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • vue中实现监听数组内部元素

    vue中实现监听数组内部元素

    这篇文章主要介绍了vue中实现监听数组内部元素方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue3父子组件通信、兄弟组件实时通信方式

    vue3父子组件通信、兄弟组件实时通信方式

    这篇文章主要介绍了vue3父子组件通信、兄弟组件实时通信方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 解决Vue的组件属性this不存在问题

    解决Vue的组件属性this不存在问题

    这篇文章主要介绍了解决Vue的组件属性this不存在问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 使用Vue做一个简单的todo应用的三种方式的示例代码

    使用Vue做一个简单的todo应用的三种方式的示例代码

    这篇文章主要介绍了使用Vue做一个简单的todo应用的三种方式的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • vue项目使用$router.go(-1)返回时刷新原来的界面操作

    vue项目使用$router.go(-1)返回时刷新原来的界面操作

    这篇文章主要介绍了vue项目使用$router.go(-1)返回时刷新原来的界面操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 深入浅出分析vue2和vue3的区别

    深入浅出分析vue2和vue3的区别

    这篇文章主要介绍了vue2和vue3的区别,较为详细的分析了vue2与vue3的常见区别与使用方法,需要的朋友可以参考下
    2023-06-06
  • springboot vue测试平台前端项目查询新增功能

    springboot vue测试平台前端项目查询新增功能

    这篇文章主要为大家介绍了springboot+vue测试平台前端项目实现查询新增功能,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 深入理解vue-class-component源码阅读

    深入理解vue-class-component源码阅读

    这篇文章主要介绍了深入理解vue-class-component源码阅读,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-02-02

最新评论