動態

詳情 返回 返回

uniapp微信小程序圖片上傳-預覽-刪除 - 動態 詳情

貼幾個可在線訪問的圖片數據,圖片數據最好包含id、url、loading、success的狀態
分別對應:

  • id === key
  • url === url
  • loading === 上傳中
  • success === 上傳成功的狀態
 const imgList = ref([
     { id:1, url: 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-2.jpeg', loading: false, success: true },
     { id:2, url: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', loading: true, success: true },
     { id:3, url: 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-1.jpeg', loading: false, success: false },
     { id:4, url: 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-3.jpeg', loading: false, success: true }
 ]);

這裏沒有用任何ui庫的上傳組件,使用uniapp內置api實現
1、uni.chooseMedia選取文件
2、uni.uploadFile上傳文件
3、上傳後添加imgList數據

頁面結構

<view @click="onPickerFile">圖片上傳</view>

選取文件

<script setup>
const onPickerFile = () => {
  // 最多選取9張,類型為image,可以拍攝或選取相冊,視頻類型最長30秒,默認後置攝像頭
    uni.chooseMedia({
        count: 9, 
        mediaType: ['image'], 
        sourceType: ['album', 'camera'],
        maxDuration: 30,
        camera: 'back',
        success(res) {
      // res.tempFiles是一個數組,內含選取的文件臨時路徑
            console.log(res.tempFiles);
      // 遍歷上傳每一張,這樣做是為了單獨管理圖片的loading狀態,你也可以一次性上傳多張
            res.tempFiles.forEach((item) => {
                uoloadFile(item);
            });
        },
        fail(err) {
            console.log('選取失敗', err);
        }
    });
};
</script>


上傳文件

<script setup>

const imgList = ref([]);
const uoloadFile = (itemFile) => {
  // 生成一個隨機數id,這裏最好用uuid
    let fileId = String(Math.random())
  // 上傳前先默認將臨時路徑添加到列表,loading中
    imgList.value.push({
        id: fileId,
        url: itemFile.tempFilePath,
        loading: true,
        success: true
    });
    uni.uploadFile({
        url: `https://test/uploadFiles`, //僅為示例,非真實的接口地址
        filePath: itemFile.tempFilePath, // 這裏為圖片臨時路徑
        name: 'files', // 後端接口接的參數,比如Request body參數為:files:array<string>
        header: {
            'content-type': 'multipart/form-data',
            authorization: `你的token`
        },
        success: (res) => {
      // 上傳完成,根據id匹配到我們剛才預先添加的圖片項
            const targetItem = imgList.value.find((item) => item.id === fileId);
            if (res.statusCode == 200) {
        // uni.uploadFile上傳完成後,data數據是序列化的,這裏反序列化取出來
                let data = JSON.parse(res.data);
        // 更新圖片項的url、loading、success
                targetItem.url = data.data[0];
                targetItem.loading = false;
                targetItem.success = true;
            } else {
        // 如果上傳失敗,則置空url、success為false
        // 頁面上可根據 !laoding && !success 顯示上傳失敗
                targetItem.url = '';
                targetItem.loading = false;
                targetItem.success = false;
            }
        },
        fail(err) {
            console.log('上傳失敗', err);
      // 找出當前對應的圖片項
            const targetItem = imgList.value.find((item) => item.id === fileId);
      // 如果上傳失敗,則置空url、success為false
      // 頁面上可根據 !laoding && !success 顯示上傳失敗
            targetItem.url = '';
            targetItem.loading = false;
            targetItem.success = false;
        }
    });
};
};
</script>

上傳後返回的數據示例

你的頁面結構應該有如下幾個要素

<template>
<view>
  // 遍歷渲染
    <view v-for="(item, index) in imgList" :key="item">
    // 圖片
        <image mode="aspectFill" :src="item.url" @click="onImage(item)" />
    // 蒙層,用於上傳中、上傳失敗,絕對定位,覆蓋整個圖片上方
        <view class="img-mask" v-if="item.loading || !item.success">
      // 上傳的loading,根據v-if="item.loading"判斷
            <uni-load-more :showText="false" color="#f7f7f7" iconType="circle" :status="'loading'" v-if="item.loading" />
            // 如果上傳失敗,則在蒙層內顯示,根據v-if="!item.loading && !item.success"判斷
      <view class="loading-text" v-if="!item.loading && !item.success">上傳失敗</view>
        </view>
    // 刪除按鈕,上傳中禁用刪除,絕對定位,在圖片的右上角
        <view class="close-btn" v-if="!item.loading" @click="onDeleteImage(item)">
            刪除
        </view>
    </view>
</view>
</template>

圖片刪除

const onDeleteImage = (item) => {
    let index = imgList.value.findIndex((img) => img.url === item.url);
    if (index == -1) return;
    imgList.value.splice(index, 1);
};

圖片預覽

const onImage = (e) => {
  // 得到url數組
    let urls = imgList.value.filter((item) => !item.loading && item.success).map((item) => item.url);
    // 當前圖片的index
  let index = urls.findIndex((url) => url == e.url);
  // 預覽
    uni.previewImage({
        urls,
        current: index
    });
};

參考資料:
uni.chooseMedia
uni.previewImage
uni.uploadFile
image

Add a new 評論

Some HTML is okay.