首頁 > 軟體

vue專案ElementUI元件中el-upload元件與圖片裁剪功能元件結合使用詳解

2022-03-31 13:02:06

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>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com