Vant3 Uploader 文件上傳

2021-09-09 16:51 更新

介紹

用于將本地的圖片或文件上傳至服務(wù)器,并在上傳過程中展示預覽圖和上傳進度。目前 Uploader 組件不包含將文件上傳至服務(wù)器的接口邏輯,該步驟需要自行實現(xiàn)。

實例演示

引入

通過以下方式來全局注冊組件,更多注冊方式請參考組件注冊。

import { createApp } from 'vue';
import { Uploader } from 'vant';

const app = createApp();
app.use(Uploader);

代碼演示

基礎(chǔ)用法

文件上傳完畢后會觸發(fā) after-read 回調(diào)函數(shù),獲取到對應(yīng)的 file 對象。

<van-uploader :after-read="afterRead" />
export default {
  setup() {
    const afterRead = (file) => {
      // 此時可以自行將文件上傳至服務(wù)器
      console.log(file);
    };

    return {
      afterRead,
    };
  },
};

文件預覽

通過 v-model 可以綁定已經(jīng)上傳的文件列表,并展示文件列表的預覽圖。

<van-uploader v-model="fileList" multiple />
import { ref } from 'vue';

export default {
  setup() {
    const fileList = ref([
      { url: 'https://img.yzcdn.cn/vant/leaf.jpg' },
      // Uploader 根據(jù)文件后綴來判斷是否為圖片文件
      // 如果圖片 URL 中不包含類型信息,可以添加 isImage 標記來聲明
      { url: 'https://cloud-image', isImage: true },
    ]);

    return {
      fileList,
    };
  },
};

上傳狀態(tài)

通過 status 屬性可以標識上傳狀態(tài),uploading 表示上傳中,failed 表示上傳失敗,done 表示上傳完成。

<van-uploader v-model="fileList" :after-read="afterRead" />
import { ref } from 'vue';

export default {
  setup() {
    const fileList = ref([
      {
        url: 'https://img.yzcdn.cn/vant/leaf.jpg',
        status: 'uploading',
        message: '上傳中...',
      },
      {
        url: 'https://img.yzcdn.cn/vant/tree.jpg',
        status: 'failed',
        message: '上傳失敗',
      },
    ]);

    const afterRead = (file) => {
      file.status = 'uploading';
      file.message = '上傳中...';

      setTimeout(() => {
        file.status = 'failed';
        file.message = '上傳失敗';
      }, 1000);
    };

    return {
      fileList,
      afterRead,
    };
  },
};

限制上傳數(shù)量

通過 max-count 屬性可以限制上傳文件的數(shù)量,上傳數(shù)量達到限制后,會自動隱藏上傳區(qū)域。

<van-uploader v-model="fileList" multiple :max-count="2" />
import { ref } from 'vue';

export default {
  setup() {
    const fileList = ref([]);

    return {
      fileList,
    };
  },
};

限制上傳大小

通過 max-size 屬性可以限制上傳文件的大小,超過大小的文件會被自動過濾,這些文件信息可以通過 oversize 事件獲取。

<van-uploader multiple :max-size="500 * 1024" @oversize="onOversize" />
import { Toast } from 'vant';

export default {
  setup() {
    const onOversize = (file) => {
      console.log(file);
      Toast('文件大小不能超過 500kb');
    };

    return {
      onOversize,
    };
  },
};

如果需要針對不同類型的文件來作出不同的大小限制,可以在 max-size 屬性中傳入一個函數(shù),在函數(shù)中通過 file.type 區(qū)分文件類型,返回 true 表示超出限制,false 表示未超出限制。

<van-uploader multiple :max-size="isOverSize" />
import { Toast } from 'vant';

export default {
  setup() {
    const isOverSize = (file) => {
      const maxSize = file.type === 'image/jpeg' ? 500 * 1024 : 1000 * 1024;
      return file.size >= maxSize;
    };
    return {
      isOverSize,
    };
  },
};

自定義上傳樣式

通過默認插槽可以自定義上傳區(qū)域的樣式。

<van-uploader>
  <van-button icon="plus" type="primary">上傳文件</van-button>
</van-uploader>

自定義預覽樣式

通過 preview-cover 插槽可以自定義覆蓋在預覽區(qū)域上方的內(nèi)容。

<van-uploader v-model="fileList">
  <template #preview-cover="{ file }">
    <div class="preview-cover van-ellipsis">{{ file.name }}</div>
  </template>
</van-uploader>

<style>
  .preview-cover {
    position: absolute;
    bottom: 0;
    box-sizing: border-box;
    width: 100%;
    padding: 4px;
    color: #fff;
    font-size: 12px;
    text-align: center;
    background: rgba(0, 0, 0, 0.3);
  }
</style>

上傳前置處理

通過傳入 beforeRead 函數(shù)可以在上傳前進行校驗和處理,返回 true 表示校驗通過,返回 false 表示校驗失敗。支持返回 Promise 對 file 對象進行自定義處理,例如壓縮圖片。

<van-uploader :before-read="beforeRead" />
import { Toast } from 'vant';

export default {
  setup() {
    // 返回布爾值
    const beforeRead = (file) => {
      if (file.type !== 'image/jpeg') {
        Toast('請上傳 jpg 格式圖片');
        return false;
      }
      return true;
    };

    // 返回 Promise
    const asyncBeforeRead = (file) => {
      return new Promise((resolve, reject) => {
        if (file.type !== 'image/jpeg') {
          Toast('請上傳 jpg 格式圖片');
          reject();
        } else {
          const img = new File(['foo'], 'bar.jpg', {
            type: 'image/jpeg',
          });
          resolve(img);
        }
      });
    };

    return {
      beforeRead,
      asyncBeforeRead,
    };
  },
};

禁用文件上傳

通過 disabled 屬性禁用文件上傳。

<van-uploader disabled />

自定義單個圖片預覽

在 v-model 數(shù)組中設(shè)置單個預覽圖片屬性,支持 imageFit deletable previewSize beforeDelete。

<van-uploader v-model="fileList" :deletable="false" />
import { ref } from 'vue';
import { Toast } from 'vant';

export default {
  setup() {
    const fileList = ref([
      { url: 'https://img.yzcdn.cn/vant/leaf.jpg' },
      {
        url: 'https://img.yzcdn.cn/vant/sand.jpg',
        deletable: true,
        beforeDelete: () => {
          Toast('自定義單個預覽圖片的事件和樣式');
        },
      },
      {
        url: 'https://img.yzcdn.cn/vant/tree.jpg',
        deletable: true,
        imageFit: 'contain',
        previewSize: 120,
      },
    ]);

    return { fileList };
  },
};

API

Props

參數(shù) 說明 類型 默認值
v-model 已上傳的文件列表 FileListItem[] -
accept 允許上傳的文件類型,詳細說明 string image/*
name 標識符,可以在回調(diào)函數(shù)的第二項參數(shù)中獲取 number | string -
preview-size 預覽圖和上傳區(qū)域的尺寸,默認單位為 px number | string 80px
preview-image 是否在上傳完成后展示預覽圖 boolean true
preview-full-image 是否在點擊預覽圖后展示全屏圖片預覽 boolean true
preview-options 全屏圖片預覽的配置項,可選值見 ImagePreview object -
multiple 是否開啟圖片多選,部分安卓機型不支持 boolean false
disabled 是否禁用文件上傳 boolean false
readonly v3.1.5 是否將上傳區(qū)域設(shè)置為只讀狀態(tài) boolean false
deletable 是否展示刪除按鈕 boolean true
show-upload 是否展示上傳區(qū)域 boolean true
lazy-load 是否開啟圖片懶加載,須配合 Lazyload 組件使用 boolean false
capture 圖片選取模式,可選值為 camera (直接調(diào)起攝像頭) string -
after-read 文件讀取完成后的回調(diào)函數(shù) Function -
before-read 文件讀取前的回調(diào)函數(shù),返回 false 可終止文件讀取,
支持返回 Promise
Function -
before-delete 文件刪除前的回調(diào)函數(shù),返回 false 可終止文件讀取,
支持返回 Promise
Function -
max-size v3.0.17 文件大小限制,單位為 byte number | string | (file: File) => boolean -
max-count 文件上傳數(shù)量限制 number | string -
result-type 文件讀取結(jié)果類型,可選值為 file text string dataUrl
upload-text 上傳區(qū)域文字提示 string -
image-fit 預覽圖裁剪模式,可選值見 Image 組件 string cover
upload-icon 上傳區(qū)域圖標名稱或圖片鏈接 string photograph
注意:accept、capture 和 multiple 為瀏覽器 input 標簽的原生屬性,移動端各種機型對這些屬性的支持程度有所差異,因此在不同機型和 WebView 下可能出現(xiàn)一些兼容性問題。

Events

事件名 說明 回調(diào)參數(shù)
oversize 文件大小超過限制時觸發(fā) 同 after-read
click-upload v3.1.5 點擊上傳區(qū)域時觸發(fā) event: MouseEvent
click-preview 點擊預覽圖時觸發(fā) 同 after-read
close-preview 關(guān)閉全屏圖片預覽時觸發(fā) -
delete 刪除文件預覽時觸發(fā) 同 after-read

Slots

名稱 說明 參數(shù)
default 自定義上傳區(qū)域 -
preview-cover 自定義覆蓋在預覽區(qū)域上方的內(nèi)容 item: FileListItem

回調(diào)參數(shù)

before-read、after-read、before-delete 執(zhí)行時會傳遞以下回調(diào)參數(shù):

參數(shù)名 說明 類型
file file 對象 object
detail 額外信息,包含 name 和 index 字段 object

ResultType 可選值

result-type 字段表示文件讀取結(jié)果的類型,上傳大文件時,建議使用 file 類型,避免卡頓。

描述
file 結(jié)果僅包含 File 對象
text 結(jié)果包含 File 對象,以及文件的文本內(nèi)容
dataUrl 結(jié)果包含 File 對象,以及文件對應(yīng)的 base64 編碼

方法

通過 ref 可以獲取到 Uploader 實例并調(diào)用實例方法,詳見組件實例方法。

方法名 說明 參數(shù) 返回值
closeImagePreview 關(guān)閉全屏的圖片預覽 - -
chooseFile 主動調(diào)起文件選擇,由于瀏覽器安全限制,只有在用戶觸發(fā)操作的上下文中調(diào)用才有效 - -

類型定義

通過 UploaderInstance 獲取 Uploader 實例的類型定義。

import { ref } from 'vue';
import type { UploaderInstance } from 'vant';

const uploaderRef = ref<UploaderInstance>();

uploaderRef.value?.chooseFile();

樣式變量

組件提供了下列 CSS 變量,可用于自定義樣式,使用方法請參考  ConfigProvider 組件

名稱 默認值 描述
--van-uploader-size 80px -
--van-uploader-icon-size 24px -
--van-uploader-icon-color var(--van-gray-4) -
--van-uploader-text-color var(--van-gray-6) -
--van-uploader-text-font-size var(--van-font-size-sm) -
--van-uploader-upload-background-color var(--van-gray-1) -
--van-uploader-upload-active-color var(--van-active-color) -
--van-uploader-delete-color var(--van-white) -
--van-uploader-delete-icon-size 14px -
--van-uploader-delete-background-color rgba(0, 0, 0, 0.7) -
--van-uploader-file-background-color var(--van-background-color) -
--van-uploader-file-icon-size 20px -
--van-uploader-file-icon-color var(--van-gray-7) -
--van-uploader-file-name-padding 0 var(--van-padding-base) -
--van-uploader-file-name-margin-top var(--van-padding-xs) -
--van-uploader-file-name-font-size var(--van-font-size-sm) -
--van-uploader-file-name-text-color var(--van-gray-7) -
--van-uploader-mask-text-color var(--van-white) -
--van-uploader-mask-background-color fade(var(--van-gray-8), 88%) -
--van-uploader-mask-icon-size 22px -
--van-uploader-mask-message-font-size var(--van-font-size-sm) -
--van-uploader-mask-message-line-height var(--van-line-height-xs) -
--van-uploader-loading-icon-size 22px -
--van-uploader-loading-icon-color var(--van-white) -
--van-uploader-disabled-opacity var(--van-disabled-opacity) -

常見問題

拍照上傳的圖片被旋轉(zhuǎn) 90 度?

部分手機在拍照上傳時會出現(xiàn)圖片被旋轉(zhuǎn) 90 度的問題,這個問題可以通過 compressorjs 或其他開源庫進行處理。

compressorjs 是一個開源的圖片處理庫,提供了圖片壓縮、圖片旋轉(zhuǎn)等能力。

示例

使用 compressorjs 進行處理的示例代碼如下:

<van-uploader :before-read="beforeRead" />
import Compressor from 'compressorjs';

export default {
  setup() {
    const beforeRead = (file) => {
      return new Promise((resolve) => {
        // compressorjs 默認開啟 checkOrientation 選項
        // 會將圖片修正為正確方向
        new Compressor(file, {
          success: resolve,
          error(err) {
            console.log(err.message);
          },
        });
      });
    };

    return {
      beforeRead,
    };
  },
};

上傳 HEIC/HEIF 格式的圖片后無法展示?

目前 Chrome、Safari 等瀏覽器不支持展示 HEIC/HEIF 格式的圖片,因此上傳后無法在 Uploader 組件中進行預覽。

[HEIF] 格式的兼容性請參考 caniuse


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號