UNIAPP 实现的复杂功能:图片上传与预览功能(支持多张图片上传、预览和删除)

在移动应用中,图片上传是一个常见且实用的功能,尤其是在社交平台、商品发布、个人资料等场景中。UNIAPP 提供了强大的跨平台能力,能够帮助我们实现多张图片上传、预览和删除的功能。本功能将展示如何在 UNIAPP 中实现一个图片上传与预览功能,包括选择图片、上传图片、预览图片和删除已上传的图片。

功能描述

该功能将允许用户:

  1. 选择多张图片:从相册或摄像头选择多张图片。
  2. 预览图片:点击已选择的图片进行预览。
  3. 删除图片:已选择的图片可以被删除。
  4. 上传图片:点击上传按钮,将选择的图片上传到服务器。

技术栈

  1. 图片选择:通过 UNIAPP 的 chooseImage API 选择图片。
  2. 图片预览:通过点击图片显示全屏预览。
  3. 图片删除:可以删除已选择的图片。
  4. 上传图片:通过 uni.uploadFile API 实现图片上传。

1. 前端代码实现

页面实现
<!-- pages/imageUpload/imageUpload.vue -->
<template>
  <view class="container">
    <view class="title">{{ $t('imageUploadTitle') }}</view>

    <!-- 选择图片区域 -->
    <view class="upload-section">
      <button @click="chooseImages">{{ $t('chooseImages') }}</button>
    </view>

    <!-- 图片预览和删除 -->
    <view class="image-preview">
      <view v-for="(image, index) in selectedImages" :key="index" class="image-item">
        <image :src="image" mode="aspectFill" @click="previewImage(image)"></image>
        <button class="delete-btn" @click="deleteImage(index)">×</button>
      </view>
    </view>

    <!-- 上传按钮 -->
    <view class="upload-btn">
      <button @click="uploadImages">{{ $t('uploadImages') }}</button>
    </view>

    <!-- 预览图片 -->
    <image-preview :visible="previewVisible" :image="previewImageSrc" @close="closePreview"></image-preview>
  </view>
</template>

<script>
import ImagePreview from '@/components/ImagePreview.vue'; // 自定义预览组件

export default {
  data() {
    return {
      selectedImages: [], // 已选择的图片列表
      previewVisible: false, // 预览框是否可见
      previewImageSrc: '', // 当前预览的图片
    };
  },
  components: {
    ImagePreview
  },
  methods: {
    // 选择图片
    chooseImages() {
      uni.chooseImage({
        count: 9, // 最多选择9张图片
        sizeType: ['original', 'compressed'], // 原图和压缩图
        sourceType: ['album', 'camera'], // 从相册或相机选择
        success: (res) => {
          // 将选择的图片添加到数组中
          this.selectedImages = [...this.selectedImages, ...res.tempFilePaths];
        },
      });
    },

    // 预览图片
    previewImage(image) {
      this.previewImageSrc = image;
      this.previewVisible = true; // 打开预览框
    },

    // 关闭预览框
    closePreview() {
      this.previewVisible = false;
    },

    // 删除图片
    deleteImage(index) {
      this.selectedImages.splice(index, 1); // 删除指定索引的图片
    },

    // 上传图片
    uploadImages() {
      if (this.selectedImages.length === 0) {
        uni.showToast({
          title: this.$t('noImagesToUpload'),
          icon: 'none',
        });
        return;
      }

      uni.showLoading({
        title: this.$t('uploading'),
      });

      // 模拟上传过程
      this.selectedImages.forEach((image, index) => {
        uni.uploadFile({
          url: 'https://example.com/upload', // 上传接口URL
          filePath: image,
          name: 'file',
          success: (res) => {
            if (res.statusCode === 200) {
              uni.showToast({
                title: this.$t('uploadSuccess'),
                icon: 'success',
              });
            } else {
              uni.showToast({
                title: this.$t('uploadFail'),
                icon: 'none',
              });
            }
          },
          fail: () => {
            uni.showToast({
              title: this.$t('uploadFail'),
              icon: 'none',
            });
          },
          complete: () => {
            if (index === this.selectedImages.length - 1) {
              uni.hideLoading();
            }
          },
        });
      });
    },
  },
};
</script>

<style scoped>
.container {
  padding: 20px;
}
.title {
  font-size: 24px;
  margin-bottom: 20px;
}
.upload-section {
  margin-bottom: 20px;
}
.upload-btn {
  margin-top: 20px;
}
button {
  padding: 10px 20px;
  background-color: #007AFF;
  color: white;
  border-radius: 8px;
  border: none;
}
.image-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.image-item {
  position: relative;
  width: 80px;
  height: 80px;
}
.image-item image {
  width: 100%;
  height: 100%;
  border-radius: 8px;
}
.delete-btn {
  position: absolute;
  top: -5px;
  right: -5px;
  background-color: red;
  color: white;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  font-size: 14px;
  text-align: center;
  line-height: 20px;
}
</style>
图片预览组件(ImagePreview.vue
<template>
  <view v-if="visible" class="preview-container" @click="closePreview">
    <image :src="image" mode="aspectFill" class="preview-image" />
  </view>
</template>

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    image: {
      type: String,
      default: '',
    },
  },
  methods: {
    closePreview() {
      this.$emit('close'); // 触发关闭预览事件
    },
  },
};
</script>

<style scoped>
.preview-container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
}
.preview-image {
  max-width: 90%;
  max-height: 90%;
  border-radius: 8px;
}
</style>

2. 使用说明

1. 选择图片

用户可以点击“选择图片”按钮,从相册或相机中选择多张图片,最多可以选择 9 张图片。选择的图片会显示在页面上,并可以点击查看。

2. 删除图片

每张已选择的图片右上角都有一个删除按钮,点击该按钮后,图片将从选择列表中删除。

3. 图片预览

点击任何已选择的图片,应用会进入全屏模式,展示该图片。点击图片以外的区域关闭预览。

4. 上传图片

点击“上传图片”按钮,用户选择的图片会依次上传到服务器。上传过程中会显示加载中的提示,上传完成后,系统会显示相应的上传成功或失败的提示。

5. 上传接口

图片的上传接口可以替换为实际的上传接口,代码中给出的 URL https://example.com/upload 只是一个示例。

3. 扩展功能

  1. 上传进度:可以显示每张图片的上传进度条。
  2. 图片压缩:上传前可以进行图片压缩,以减少上传的图片大小。
  3. 批量删除:可以实现批量选择和删除图片的功能。
  4. 预览图片全屏滑动:实现预览时可以左右滑动查看多张图片。
  5. 图片大小限制:可以对选择的图片大小进行限制,防止上传过大的图片。

4. 总结

该图片上传与预览功能实现了用户选择、预览、删除和上传图片的需求,UI 设计简洁易用,功能完整且易于扩展。通过 UNIAPP 的多平台能力,可以快速实现该功能,并在多种应用场景中使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值