| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- <template>
- <view class="image-uploader">
- <up-upload
- :source-type="['camera', 'album']"
- :fileList="fileList"
- @afterRead="handleAfterRead"
- @delete="handleDelete"
- :maxCount="maxCount"
- :previewFullImage="true"
- :multiple="multiple"
- :disabled="disabled"
- :deletable="!disabled"
- >
- <view class="upload-btn" v-if="fileList.length < maxCount">
- <u-icon name="plus" size="40" color="#c0c4cc"></u-icon>
- </view>
- </up-upload>
- </view>
- </template>
- <script setup>
- import { ref, watch } from "vue";
- import { $upload, Toast } from "@/utils";
- import { t } from "@/locale";
- const props = defineProps({
- // 初始图片列表
- modelValue: {
- type: Array,
- default: () => [],
- },
- // 最大上传数量
- maxCount: {
- type: Number,
- default: 1,
- },
- // 是否多选
- multiple: {
- type: Boolean,
- default: false,
- },
- disabled: {
- type: Boolean,
- default: false,
- },
- // 上传按钮文字
- uploadText: {
- type: String,
- default: "上传图片",
- },
- // 上传接口地址
- uploadUrl: {
- type: String,
- default: "",
- },
- });
- const emit = defineEmits(["update:modelValue", "success", "delete", "error"]);
- const uToast = ref(null);
- const fileList = ref([]);
- // 监听父组件传入的值
- watch(
- () => props.modelValue,
- (newVal) => {
- fileList.value = newVal.map((item) => {
- return typeof item === "string" ? { url: item } : item;
- });
- },
- { immediate: true }
- );
- // 文件读取完成后处理
- const handleAfterRead = async (event) => {
- const files = event.file;
- try {
- const uploadFiles = Array.isArray(files) ? files : [files];
- const results = await Promise.all(
- uploadFiles.map((file) => {
- return $upload(file.url);
- })
- );
- const newFiles = results.map((res) => ({
- url: res.data.url,
- name: res.data.name,
- status: "success",
- }));
- fileList.value = [...fileList.value, ...newFiles];
- emit("update:modelValue", fileList.value);
- emit("success", newFiles);
- Toast(t("成功"));
- } catch (error) {
- emit("error", error);
- Toast(t("失败"));
- }
- };
- const handleDelete = (event) => {
- const { index } = event;
- const deletedFile = fileList.value[index];
- fileList.value.splice(index, 1);
- emit("update:modelValue", fileList.value);
- emit("delete", deletedFile);
- };
- defineExpose({
- clearFiles: () => {
- fileList.value = [];
- emit("update:modelValue", []);
- },
- });
- </script>
- <style lang="less" scoped>
- .image-uploader {
- padding: 10rpx;
- .upload-btn {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 150rpx;
- height: 150rpx;
- border: 1px dashed #c0c4cc;
- border-radius: 8rpx;
- background-color: #f5f7fa;
- .upload-text {
- margin-top: 10rpx;
- font-size: 24rpx;
- color: #909399;
- }
- }
- }
- </style>
|