图片裁剪上传(elementUI + vue-cropper)

777 阅读1分钟

图片裁剪上传(element+vue-cropper)

实现:

  通过element的el-upload的:on-change="handleChange"事件监听选择的本地文件
  选择文件后传递给vue-cropper组件进行裁剪
  裁剪后返回blob格式给el-upload
  通过formData将获取到的Blob格式转换为file形式
  通过el-upload的:http-request="upload"进行上传

image.png 单图上传

封装vue-cropper裁剪组件(单图)

<template>
  <div>
    <div class="cropper-content">
      <!-- 剪裁框 -->
      <div class="cropper">
        <vueCropper 
        ref="cropper" 
        :img="option.img" 
        :outputSize="option.size" 
        :outputType="option.outputType" 
        :info="true" :full="option.full" 
        :canMove="option.canMove" 
        :canMoveBox="option.canMoveBox" 
        :original="option.original" 
        :autoCrop="option.autoCrop" 
        :autoCropWidth="option.autoCropWidth" 
        :autoCropHeight="option.autoCropHeight" 
        :fixedBox="option.fixedBox" 
        @realTime="realTime" 
        :fixed="option.fixed" 
        :fixedNumber="fixedNumber">
        </vueCropper>
      </div>
      <!-- 预览框 -->
      <div class="show-preview" :style="{'width': '300px', 'height': '300px',  'overflow': 'hidden', 'margin': '0 25px', 'display':'flex', 'align-items' : 'center'}">
        <div :style="previews.div" class="preview">
          <img :src="previews.url" :style="previews.img">
        </div>
      </div>
    </div>
    <div class="footer-btn">
      <!-- 缩放旋转按钮 -->
      <div class="scope-btn">
        <el-button type="primary" icon="el-icon-zoom-in" @click="changeScale(1)">放大</el-button>
        <el-button type="primary" icon="el-icon-zoom-out" @click="changeScale(-1)">缩小</el-button>
        <!-- <el-button type="primary" @click="rotateLeft">逆时针旋转</el-button>
        <el-button type="primary" @click="rotateRight">顺时针旋转</el-button> -->
      </div>
      <!-- 确认上传按钮 -->
      <div class="upload-btn">
        <el-button type="primary" @click="uploadImg('blob')">上传</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import { VueCropper } from 'vue-cropper'; 
export default {
  components: { VueCropper },
  data () {
    return {
      previews: {}, // 预览数据
      option: {
        img: '', // 裁剪图片的地址  (默认:空)
        size: 1, // 裁剪生成图片的质量  (默认:1)
        full: true, // 是否输出原图比例的截图 选true生成的图片会非常大  (默认:false)
        outputType: 'png', // 裁剪生成图片的格式  (默认:jpg)
        canMove: true, // 上传图片是否可以移动  (默认:true)
        original: false, // 上传图片按照原始比例渲染  (默认:false)
        canMoveBox: true, // 截图框能否拖动  (默认:true)
        autoCrop: true, // 是否默认生成截图框  (默认:false)
        autoCropWidth: 400, // 默认生成截图框宽度  (默认:80%)
        autoCropHeight: 400, // 默认生成截图框高度  (默认:80%)
        fixedBox: false, // 固定截图框大小 不允许改变  (默认:false)
        fixed: true, // 是否开启截图框宽高固定比例  (默认:true)
        fixedNumber: [1,1.85] // 截图框比例  (默认:[1:1])
      },
      downImg: '#'
    }
  },
  props: ['imgFile', 'fixedNumber'],
  created(){
    this.Update()
  },
  methods: {
    changeScale (num) {
      //  console.log("点击了图片缩放");
      // 图片缩放
      num = num || 1
      this.$refs.cropper.changeScale(num)
    },
    rotateLeft () {
      console.log("点击了向左旋转");
      // 向左旋转
      this.$refs.cropper.rotateLeft()
    },
    rotateRight () {
      console.log("点击了向右旋转");
      // 向右旋转
      this.$refs.cropper.rotateRight()
    },
    Update () {
      this.option.img = this.imgFile.url
    },
    realTime (data) {
      // 实时预览
      this.previews = data
    },
    uploadImg (type) {
      console.log("点击了上传");
      // 将剪裁好的图片回传给父组件
      event.preventDefault()
      let that = this
      if (type === 'blob') {
        this.$refs.cropper.getCropBlob(data => {
          console.log('getCropBlob',data);
          that.$emit('upload', data)
        })
      } else {
        this.$refs.cropper.getCropData(data => {
          console.log('getCropData',data);
          that.$emit('upload', data)
        })
      }
    }
  }
}
</script>
<style>
.cropper-content {
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
}
.cropper-content .cropper {
  width: 350px;
  height: 300px;
}
.cropper-content .show-preview {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  -webkit-justify-content: center;
  overflow: hidden;
  border: 1px solid #cccccc;
  background: #cccccc;
  margin-left: 40px;
}
.preview {
  overflow: hidden;
  border: 1px solid #cccccc;
  background: #cccccc;
}
.footer-btn {
  margin-top: 30px;
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
}
.footer-btn .scope-btn {
  width: 250px;
  display: flex;
  display: -webkit-flex;
  justify-content: space-between;
  -webkit-justify-content: space-between;
}
.footer-btn .upload-btn {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  -webkit-justify-content: center;
}
.footer-btn .btn {
  outline: none;
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  text-align: center;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  outline: 0;
  margin: 0;
  -webkit-transition: 0.1s;
  transition: 0.1s;
  font-weight: 500;
  padding: 8px 15px;
  font-size: 12px;
  border-radius: 3px;
  color: #fff;
  background-color: #67c23a;
  border-color: #67c23a;
}
</style>

封装上传(el-upload)裁剪(vue-cropper)组件单图

<template>
    <div class="component-upload-image">
        <el-upload
            :action="uploadImgUrl"
            :auto-upload="false"
            list-type="picture-card"
            :on-success="handleUploadSuccess"
            :before-upload="handleBeforeUpload"
            :on-error="handleUploadError"
            :on-change="handleChange"
            name="file"
            :show-file-list="false"
            :headers="headers"
            :http-request="upload"
            style="display: inline-block; vertical-align: top"
        >
            <el-image v-if="!value" :src="value">
                <div slot="error" class="image-slot">
                    <i class="el-icon-plus"/>
                </div>
            </el-image>
            <div v-else class="image">
                <el-image :src="value" :style="`width:150px;height:150px;`" fit="fill"/>
                <div class="mask">
                    <div class="actions">
            <span title="预览" @click.stop="dialogVisible = true">
              <i class="el-icon-zoom-in"/>
            </span>
            <span title="移除" @click.stop="removeImage">
              <i class="el-icon-delete"/>
            </span>
                    </div>
                </div>
            </div>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
            <img :src="value" style="display: block; max-width: 100%; margin: 0 auto;">
        </el-dialog>
        <!-- 裁剪弹窗 -->
        <el-dialog :append-to-body="true" :visible.sync="cropperModel" width="800px" :before-close="beforeClose">
            <cropper-photo :img-file="cropperFile" ref="vueCropper" :fixedNumber="fixedNumber" @upload="upload"></cropper-photo>
        </el-dialog>
    </div>
</template>

<script>
import {getToken} from "@/utils/auth";
import CropperPhoto from '@/components/ImageUpload/cropperPhoto'; //封装的裁剪组件
import {uploadImage} from "@/api/storeinfo/video"; //上传图片的接口

export default {
    components:{
        CropperPhoto
    },
    data() {
        return {
            dialogVisible: false,
            uploadImgUrl: process.env.VUE_APP_IMAGE_UPLOAD_PATH, // 上传的图片服务器地址
            headers: {
                Authorization: "Bearer " + getToken(),
            },
            cropperModel: false, // 剪裁组件弹窗开关
            cropperFile: '',
            // fixedNumber:[1,1]
        };
    },
    props: {
        value: {
            type: String,
            default: "",
        },
        astrictSize: {
            type: Number,
            default: 0,
        },
        // 裁剪组件裁剪框比例
        fixedNumber: {
            type: Array,
            default: [1,1.5],
            // default: function(){
            //     return[1,1.5]
            // }
        }
    },
    created(){
        console.log('this.fixedNumber',this.fixedNumber);
    },
    methods: {
        removeImage() {
            this.$emit("input", "");
        },
        handleUploadSuccess(res) {
            this.$emit("input", res.data);
            console.log('handleUploadSuccess',res);
            this.loading.close();
        },
        handleChange(file,fileList){      
            let types = ['image/jpeg','image/jpg','image/png'];
            const isImage = types.includes(file.raw.type);
            const isLtSize = file.raw.size / 1024 / 1024 < 1
            if (!isImage) {
                this.$message.error({
                    message: '上传图片只能是 JPG、JPEG、PNG 格式!',
                    type: 'error'
                });
                return false;
            }
            if (!isLtSize) {
                this.$message.error({
                    message:'上传图片大小不能超过 1MB!',
                    type: "error"
                });
                return false;
            }
            this.cropperModel = true
            this.cropperFile = file
        },
        handleBeforeUpload(file) {
            console.log('handleBeforeUpload',file); 
            this.loading = this.$loading({
                lock: true,
                text: "上传中",
                background: "rgba(0, 0, 0, 0.7)",
            });
        },
        handleUploadError() {
            this.$message({
                type: "error",
                message: "上传失败",
            });
            this.loading.close();
        },
        beforeClose (done) {
            this.cropperModel = false
        },
        // 上传图片
        upload (data) {
             this.loading = this.$loading({
                lock: true,
                text: "上传中",
                background: "rgba(0, 0, 0, 0.7)",
            });
            // console.log('撒花姑娘出', data);
            let files = new window.File([data], "ps.jpg", {type: 'image/jpeg'}) // myBlob.type 自定义文件名
            const formData = new FormData()
            formData.append('file', files)
            // console.log('formData',formData.get('file'));
            uploadImage(formData).then(res => {
                // console.log('res',res);
                // this.value = res.msg
                this.$emit("input", res.msg);
                this.cropperModel = false
                this.$message({
                    type: "success",
                    message: "上传成功",
                })
                this.loading.close();
            }, err => {
                console.log(err);
                this.$message({
                    type: "error",
                    message: "上传失败",
                });
                this.loading.close();
            })
        },
        imgSize(file) {
            // 上传图片前处理函数
            const isSize = new Promise(function(resolve, reject) {
                let width = 750;
                let height = 420;
                let _URL = window.URL || window.webkitURL;
                let image = new Image();
                image.onload = function() {
                let valid = image.width == width && image.height == height;
                valid ? resolve() : reject();
                };
                image.src = _URL.createObjectURL(file);
            }).then(() => {
                return file;
            },() => {
                this.$message.error("上传头像图片尺寸不符合,只能是750*420!");
                return Promise.reject();
                }
            );
            return isSize;
            // console.log('isSize',isSize);
        },
        //将base64转换为blob
        dataURLtoBlob(dataurl) { 
            var arr = dataurl.split(','),
                mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mime });
        },
        //将blob转换为file
        blobToFile(theBlob, fileName){
            theBlob.lastModifiedDate = new Date();
            theBlob.name = fileName;
            return theBlob;
        },
    },
    watch: {},
};
</script>

<style scoped lang="scss">
.image {
    position: relative;

    .mask {
        opacity: 0;
        position: absolute;
        top: 0;
        width: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        transition: all 0.3s;
    }

    &:hover .mask {
        opacity: 1;
    }
}
</style>

多图裁剪组件

<template>
  <div>
    <div class="cropper-content">
      <!-- 剪裁框 -->
      <div class="cropper">
        <vueCropper 
        ref="cropper" 
        :img="option.img" 
        :outputSize="option.size" 
        :outputType="option.outputType" 
        :info="true" :full="option.full" 
        :canMove="option.canMove" 
        :canMoveBox="option.canMoveBox" 
        :original="option.original" 
        :autoCrop="option.autoCrop" 
        :autoCropWidth="option.autoCropWidth" 
        :autoCropHeight="option.autoCropHeight" 
        :fixedBox="option.fixedBox" 
        @realTime="realTime" 
        :fixed="option.fixed" 
        :fixedNumber="fixedNumber">
        </vueCropper>
      </div>
      <!-- 预览框 -->
      <div class="show-preview" :style="{'width': '300px', 'height': '300px',  'overflow': 'hidden', 'margin': '0 25px', 'display':'flex', 'align-items' : 'center'}">
        <div :style="previews.div" class="preview">
          <img :src="previews.url" :style="previews.img">
        </div>
      </div>
    </div>
    <div class="footer-btn">
      <!-- 缩放旋转按钮 -->
      <div class="scope-btn">
        <el-button type="primary" icon="el-icon-zoom-in" @click="changeScale(1)">放大</el-button>
        <el-button type="primary" icon="el-icon-zoom-out" @click="changeScale(-1)">缩小</el-button>
        <!-- <el-button type="primary" @click="rotateLeft">逆时针旋转</el-button>
        <el-button type="primary" @click="rotateRight">顺时针旋转</el-button> -->
      </div>
      <!-- 确认上传按钮 -->
      <div class="upload-btn">
        <el-button type="primary" @click="uploadImg('blob')">上传</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import { VueCropper } from 'vue-cropper';
// import VueCropper from 'vue-cropper'
export default {
  components: { VueCropper },
  data () {
    return {
      previews: {}, // 预览数据
      option: {
        img: '', // 裁剪图片的地址  (默认:空)
        size: 1, // 裁剪生成图片的质量  (默认:1)
        full: true, // 是否输出原图比例的截图 选true生成的图片会非常大  (默认:false)
        outputType: 'png', // 裁剪生成图片的格式  (默认:jpg)
        canMove: true, // 上传图片是否可以移动  (默认:true)
        original: false, // 上传图片按照原始比例渲染  (默认:false)
        canMoveBox: true, // 截图框能否拖动  (默认:true)
        autoCrop: true, // 是否默认生成截图框  (默认:false)
        autoCropWidth: 400, // 默认生成截图框宽度  (默认:80%)
        autoCropHeight: 400, // 默认生成截图框高度  (默认:80%)
        fixedBox: false, // 固定截图框大小 不允许改变  (默认:false)
        fixed: true, // 是否开启截图框宽高固定比例  (默认:true)
        // fixedNumber: [1,1.85] // 截图框比例  (默认:[1:1])
      },
      downImg: '#',
      loading: false
    }
  },
  props:['imgFile','fixedNumber'],
  created(){
    this.loading = true
    this.Update()
  },
  methods: {
    changeScale (num) {
      //  console.log("点击了图片缩放");
      // 图片缩放
      num = num || 1
      this.$refs.cropper.changeScale(num)
    },
    rotateLeft () {
      console.log("点击了向左旋转");
      // 向左旋转
      this.$refs.cropper.rotateLeft()
    },
    rotateRight () {
      console.log("点击了向右旋转");
      // 向右旋转
      this.$refs.cropper.rotateRight()
    },
    Update () {
      this.option.img = ''
      // console.log('this.imgFile',this.imgFile);
      this.option.img = this.imgFile.url
      this.loading = false
    },
    realTime (data) {
      // 实时预览
      this.previews = data
    },
    uploadImg (type) {
      this.loading = this.$loading({
          lock: true,
          text: "上传中",
          background: "rgba(0, 0, 0, 0.7)",
      });
      // console.log("点击了上传");
      const emitArr = []
      // 将剪裁好的图片回传给父组件
      event.preventDefault()
      let that = this
      if (type === 'blob') {
        this.$refs.cropper.getCropBlob(data => {
          // console.log('getCropBlob',data);
          that.$emit('upload', data)
           this.loading.close();
        })
      } else {
        this.$refs.cropper.getCropData(data => {
          // console.log('getCropData',data);
          that.$emit('upload', data)
          this.loading.close();
        })
      }
    }
  }
}
</script>
<style>
.cropper-content {
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
}
.cropper-content .cropper {
  width: 350px;
  height: 300px;
}
.cropper-content .show-preview {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  -webkit-justify-content: center;
  overflow: hidden;
  border: 1px solid #cccccc;
  background: #cccccc;
  margin-left: 40px;
}
.preview {
  overflow: hidden;
  border: 1px solid #cccccc;
  background: #cccccc;
}
.footer-btn {
  margin-top: 30px;
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
}
.footer-btn .scope-btn {
  width: 250px;
  display: flex;
  display: -webkit-flex;
  justify-content: space-between;
  -webkit-justify-content: space-between;
}
.footer-btn .upload-btn {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  -webkit-justify-content: center;
}
.footer-btn .btn {
  outline: none;
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  text-align: center;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  outline: 0;
  margin: 0;
  -webkit-transition: 0.1s;
  transition: 0.1s;
  font-weight: 500;
  padding: 8px 15px;
  font-size: 12px;
  border-radius: 3px;
  color: #fff;
  background-color: #67c23a;
  border-color: #67c23a;
}
</style>

多图裁剪上传组件

<template>
    <div>
        <el-upload ref="multiImageUpload"
                   :action="uploadImgUrl"
                   :headers="headers"
                   multiple
                   accept="image/png, image/jpeg"
                   list-type="picture-card"
                   :on-change="handleChange"
                   :on-preview="handlePictureCardPreview"
                   :on-remove="handleRemove"
                   :file-list="imageList"
                   :auto-upload="false"
                   :http-request="upload"
                   :show-file-list="true"
                   v-loading="loading"
                   element-loading-text="拼命上传中"
                   element-loading-spinner="el-icon-loading"
                   element-loading-background="rgba(0, 0, 0, 0.8)">
            <i class="el-icon-plus"></i>
        </el-upload>
         <el-dialog :visible.sync="previewImage" title="预览" width="800" append-to-body>
            <img :src="previewImageUrl" style="display: block; max-width: 100%; margin: 0 auto;">
        </el-dialog>
        <!-- 裁剪弹窗 -->
        <el-dialog :append-to-body="true" :visible.sync="cropperModel" v-if="cropperModel" width="800px" :before-close="beforeClose">
            <cropper-photo :img-file="cropperFile" ref="vueCropper" :fixedNumber="fixedNumber" @upload="upload"></cropper-photo>
        </el-dialog>
    </div>
</template>

<script>
import {getToken} from "@/utils/auth";
import CropperPhoto from '@/components/ImageUpload/cropperPhoto2'; //图片裁剪组件
import {uploadImage} from "@/api/storeinfo/video"; //图片上传接口
export default {
    components:{
        CropperPhoto
    },
    data() {
        return {
            //图片列表
            imageList: [],
            //已上传文件字符串
            uploadedFileStr: "",
            //图片预览
            previewImage: false,
            //预览图地址
            previewImageUrl: "",
            //上传是否完成
            uploadComplete: true,
            dialogVisible: false,
            uploadImgUrl: '', // 上传的图片服务器地址
            headers: {
                // Authorization: "Bearer " + getToken(),
            },
            cropperModel: false, // 剪裁组件弹窗开关
            cropperFile: '',
            cropperBlobFile:[],
            uploadReponse:[],
            loading: false
        };
    },
    props: {
        value: {
            type: String,
            default: "",
        },
        //父组件传递过来的 需要处理 图片列表
        parentImageList: {
            type: String,
            default: ""
        },
        fixedNumber: {
            type: Array,
            default: [1,1.5],
            // default: function(){
            //     return[1,1.5]
            // }
        }
    },
    watch: {
         parentImageList: function (newValue, oldValue) {
            // console.log("newValue", newValue, "--oldValue", oldValue);
            // console.log(newValue.length);
            //转为数组
            if (newValue.length === 0) {
                console.log("点击了新增");
                this.imageList.length = 0;
                this.$refs["multiImageUpload"].clearFiles();
            }
            if (newValue.length > 0) {
                if (newValue === "odd" || newValue === "even") {
                    console.log("点击了新增");
                    this.imageList.length = 0;
                    this.$refs["multiImageUpload"].clearFiles();
                } else {
                    let split = newValue.split(",");
                    //先清空原有数据
                    this.imageList.length = 0;
                    if (split != null) {
                        for (let i = 0; i < split.length; i++) {
                            this.imageList.push({name: i, url: split[i]})
                        }
                    }
                }
            }
        }
    },
    created() {
        this.initImageList(this.parentImageList);
        // console.log("图片墙初始化:" + this.parentImageList);
        
    },
    methods: {
        beforeUploadPicture(file) {
            console.log("上传前" + file);
        },
        // 上传图片时调用 file上传后的文件结果
        uploadProgress(event, file, fileList) {
            // console.log(event, file, fileList);
            // this.uploadComplete = false;
        },
        // 上传图片成功 res = file.response
        uploadSuccess(res, file, fileList) {
            console.log("上传图片成功");
            console.log(res, file, fileList);
            console.log("上传图片成功");
            // this.uploadComplete = true;
            // this.fileChange(fileList);
        },
        // 上传图片出错
        uploadError(err, file, fileList) {
            this.$message.error("上传出错");
        },
        // 移除图片
        handleRemove(file, fileList) {
            console.log("移除图片");
            console.log(file, fileList)
            console.log("移除图片");
            this.fileChange(fileList);
        },
        handleChange(file,fileList){        
            this.cropperFile = ''
            let types = ['image/jpeg','image/jpg','image/png'];
            for (let i = 0; i < fileList.length; i++) {
                // console.log('fileList[i]',fileList[i]);
                const isImage = types.includes(fileList[fileList.length-1].raw.type);
                const isLtSize = fileList[fileList.length-1].raw.size / 1024 / 1024 < 1
                if (!isImage) {
                    this.imageList.pop()
                    this.$message.error({
                        message: '上传图片只能是 JPG、JPEG、PNG 格式!',
                        type: 'error'
                    });
                    return false;
                    this.cropperModel = false
                }
                if (!isLtSize) {
                    this.imageList.pop()
                    this.$message.error({
                        message:'上传图片大小不能超过 1MB!',
                        type: "error"
                    });
                    return false;
                    this.cropperModel = false
                }
                
            this.cropperModel = true
            this.cropperFile = fileList[fileList.length-1]
            this.imageList.pop()
            }
        },
        // 上传图片
        upload (data) {
            // console.log('uploaddata',data);
            this.loading = true
            let files = new window.File([data], "ps.jpg", {type: 'image/jpeg'}) // myBlob.type 自定义文件名
            const formData = new FormData()
            formData.append('file', files)
            const imageArrayList  = []
            uploadImage(formData).then(res => {
                // console.log('uploadImagess',res);
                this.cropperModel = false
                const response = {response:{code: res.code, data: res.msg}}
                // console.log('response',response);
                this.uploadReponse.push(response)
                // console.log('this.uploadReponse',this.uploadReponse);
                this.fileChange(this.uploadReponse);
                this.$message({
                    type: "success",
                    message: "上传成功",
                })
               
                this.loading = false
            }, err => {
                console.log(err);
                this.$message({
                    type: "error",
                    message: "上传失败",
                });
                this.loading = false
            })
        },
        // 设置photo值
        fileChange(fileList) {
            // console.log("fileChange", fileList);
            let temp_str = '';
            if (fileList.length > 0) {
                //列表有数据
                for (let i = 0; i < fileList.length; i++) {
                    // console.log(fileList[i]);
                    //判断原有数据还是上传返回的数据
                    //原有数据
                    // console.log(typeof (fileList[i].response) == "undefined");
                    if (typeof (fileList[i].response) == "undefined") {
                        if (i === 0) {
                            temp_str += fileList[i].url;
                        } else {
                            // 最终photo的格式是所有已上传的图片的url拼接的字符串(逗号隔开)
                            temp_str += ',' + fileList[i].url;
                        }
                    } else {
                        //上传返回数据
                        if (fileList[i].response.code === 200) {
                            if (i === 0) {
                                temp_str += fileList[i].response.data;
                            } else {
                                // 最终photo的格式是所有已上传的图片的url拼接的字符串(逗号隔开)
                                temp_str += ',' + fileList[i].response.data;
                            }
                        }
                    }
                }
                this.uploadedFileStr = temp_str;
            }
            // console.log("temp_str" + temp_str);
            this.sendMsgToParent();
        },
        // 图片预览
        handlePictureCardPreview(file) {
            // console.log('handlePictureCardPreview',file);
            this.previewImageUrl = file.url;
            this.previewImage = true;
        },
        //初始化图片列表 data为字符串 第一次 created, 其他走监听器
        //数组转换为 [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]格式
        initImageList(data) {
            // console.log('initImageList',data);
            if (data === "odd" || data === "even") {
                this.imageList.length = 0;
            } else {
                //转为数组
                if (data.length > 0) {
                    let split = data.split(",");
                    if (split != null) {
                        for (let i = 0; i < split.length; i++) {
                            this.imageList.push({name: i, url: split[i]})
                        }
                    }
                } else {
                    this.imageList.length = 0;
                }
            }
        },
        //向父组件传值
        sendMsgToParent() {
            this.$emit("getFileListStr", this.uploadedFileStr);
        },
        beforeClose (done) {
            this.cropperModel = false
        },
    }
};
</script>

<style>

</style>

上传图片接口

export function uploadImage(data){
  return request({
    url: '/Ossupload/upload',
    method: 'post',
    Headers: {
      'Content-Type': 'multipart/form-data'
    },
    data: data
  })
}

页面内使用

<template>
     <el-form-item label="项目图片" prop="image">
        <imageUpload :astrictSize=1 :fixedNumber=fixedNumber v-model="form.image"/>
     </el-form-item>
     <el-form-item label="轮播照片" prop="luboimages" >
        <multi-image :parent-image-list="tempImageStr" :fixedNumber=fixedNumberMore @getFileListStr="getFileListStr"></multi-image>
     </el-form-item>
</template>

import ImageUpload from '@/components/ImageUpload/index2'; //引入封装的上传裁剪组件单图
import multiImage from "@/components/multiImage/multiImage2"; //引入封装的上传裁剪组件多图

export default {
    name: "Project",
    components: {
        ImageUpload,
        multiImage
    },
    data() { 
      return {
        fixedNumber: [1,1],
        fixedNumberMore: [1.5,1], 
        form:{
            image: '' //单图图片地址
        },
        luboimages: null,
        tempImageStr:[] //多图图片地址
      }
    },
    methods: {
      //获取照片字符串
        getFileListStr(str) {
            console.log("照片轮播图字符串", str);
            this.form.luboimages = str;
            this.tempImageStr = str
        }
    }
    
}