上传图片回显,自定义图片回显样式
这段代码是一个Vue组件,主要实现了图片上传和预览的功能。组件接收了父组件传递的图片列表、最大图片数量和上传状态等属性。在模板中,使用了uni-easyinput
组件和u-upload
组件来实现图片上传和预览功能。在方法中,实现了删除图片、上传图片和预览图片的逻辑。整体功能包括图片上传、预览、删除和限制最大图片数量等。
父组件使用:
parentImgList
中传入的值双向,子组件更新则父组件更新,是图片URL数组
isUploading
是当前是否正在上传中
<upload-image :parentImgList.sync="form.imgList" :isUploading.sync="isUploading"></upload-image>
组件内容
<template><view><view class="photo-box flex-row"><view class="photo" v-for="(item, index) in imgList" :key="index"><view class="delete-btn" @click="deletePhoto(index, 'after')"><img src="@/assets/icon/delete.svg" /></view><view class="photo-image" @click="viewImage(item)"><img :src="item" /></view></view><!-- v-bind="$attrs" 接收父组件的传值,并赋给<u-upload>;某一属性如果子组件(本组件)已经设值,子组件的值覆盖父组件的;以maxCount属性为例,这里设了5,那么不管父组件传多少,实际用的值一直是5。 --><u-uploadv-bind="$attrs":maxCount="maxCount"name="fileList"uploadIcon="plus"width="110"height="110":previewFullImage="true"multiple@afterRead="handleAfterRead"@delete="deletePic"v-if="!isUpload && imgList.length < 6"><view class="upload-content"><u-icon name="plus" color="#6E9CFE" size="20"></u-icon></view></u-upload><view class="upload-content" v-if="isUpload && imgList.length < 6">{{ isUpload }}</view></view><view style="color: #999;font-size: 9px;margin-top: 2px;">最多上传六张</view><!-- 模态框显示大图 --><view v-if="showModal" class="modal" @click="showModal = false"><img :src="currentImage" class="modal-image" /></view><van-overlay :show="isUploading"><van-loading size="35px">图片上传中...</van-loading></van-overlay></view>
</template><script>
import { photoUploadFileAPI } from "@/api/upload.js"; // 与后端商量好的上传图片接口,使用 uni.uploadFile
import { Loading, Notify } from 'vant-green'; // vant的组件
export default {name: "img-upload",props: {parentImgList: {type: Array,default: () => {return [];},},maxCount: {type: Number,default: 6,},isUploading: {type: Boolean,default: false}},data() {return {fileList: [],imgList: [],showModal: false,currentImage: "",isUpload: '',chooseImgNumber: 0};},watch: {parentImgList: {handler(val) {// console.log("父组件传递的数据", val);if (val) {this.imgList = val;}},deep: true,},imgList(val) {// console.log("女此案你看见", val);this.$emit("update:parentImgList", val);},},mounted() {console.log("fileList", this.value);},methods: {// s删除修改状态下原本有的照片deletePhoto(index) {this.imgList.splice(index, 1);console.log(`点击删除序号为${index}的照片`, this.imgList);},// 新增图片async handleAfterRead(event) {// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式this.chooseImgNumber++this.$emit('update:isUploading', true)let lists = [].concat(event.file);console.log('上传的图片', lists, lists.length, event.file)this.isUpload = '上传中...'for (let i = 0; i < lists.length; i++) {if (this.imgList.length < 6) {const result = await photoUploadFileAPI(lists[i].url);console.log("result>>>图片上传结果", result);if (result.success) {this.imgList.push(result.data);this.chooseImgNumber--} else {Notify({ type: 'danger', message: '图片上传失败' });}} else {Notify({ type: 'warning', message: '最多上传6张图片' })}}this.isUpload = ''this.$emit('update:isUploading', false)// console.log("fileList2", this.fileList, this.imgList, this.chooseImgNumber);// this.$emit('input', this.imgList);},viewImage(image) {this.currentImage = image;this.showModal = true;},},
};
</script><style lang="scss" scoped>
.photo-box {margin-right: 10px;flex-wrap: wrap;.photo {position: relative;.photo-image {width: 95px;height: 95px;margin-right: 10px;margin-bottom: 5px;img {width: 100%;/* 使图片宽度填满容器 */height: 100%;/* 使图片高度填满容器 */object-fit: cover;/* 保持比例并裁剪 */border-radius: 4px;}}.delete-btn {position: absolute;right: 8px;top: 0;background-color: rgba($color: #000000, $alpha: 0.1);width: 18px;border-radius: 20px;height: 18px;// font-size: 40rpx;text-align: center;// line-height: 50rpx;color: #555;}}
}.modal {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, 0.8);display: flex;justify-content: center;align-items: center;z-index: 99999999999;
}.modal-image {max-width: 90%;max-height: 90%;
}.upload-content {display: flex;justify-content: center;align-items: center;width: 100px;height: 102px;border-radius: 3px;margin-top: 1px;border: 1px dashed #5a9fff;// background: #f4f8ff;box-sizing: border-box;
}
</style>
<style>
.van-loading, .van-loading__spinner {/* margin-top: 45%; */
}
.van-overlay {padding-top: 45vh;text-align: center;
}
</style>