| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 | import { createVNode as _createVNode, mergeProps as _mergeProps } from "vue";import { ref, reactive, defineComponent, onBeforeUnmount } from "vue";import { pick, extend, toArray, isPromise, truthProp, getSizeStyle, makeArrayProp, makeStringProp, makeNumericProp } from "../utils/index.mjs";import { bem, name, isOversize, filterFiles, isImageFile, readFileContent } from "./utils.mjs";import { useCustomFieldValue } from "@vant/use";import { useExpose } from "../composables/use-expose.mjs";import { Icon } from "../icon/index.mjs";import { ImagePreview } from "../image-preview/index.mjs";import UploaderPreviewItem from "./UploaderPreviewItem.mjs";const uploaderProps = {  name: makeNumericProp(""),  accept: makeStringProp("image/*"),  capture: String,  multiple: Boolean,  disabled: Boolean,  readonly: Boolean,  lazyLoad: Boolean,  maxCount: makeNumericProp(Infinity),  imageFit: makeStringProp("cover"),  resultType: makeStringProp("dataUrl"),  uploadIcon: makeStringProp("photograph"),  uploadText: String,  deletable: truthProp,  afterRead: Function,  showUpload: truthProp,  modelValue: makeArrayProp(),  beforeRead: Function,  beforeDelete: Function,  previewSize: [Number, String, Array],  previewImage: truthProp,  previewOptions: Object,  previewFullImage: truthProp,  maxSize: {    type: [Number, String, Function],    default: Infinity  }};var stdin_default = defineComponent({  name,  props: uploaderProps,  emits: ["delete", "oversize", "click-upload", "close-preview", "click-preview", "update:modelValue"],  setup(props, {    emit,    slots  }) {    const inputRef = ref();    const urls = [];    const getDetail = (index = props.modelValue.length) => ({      name: props.name,      index    });    const resetInput = () => {      if (inputRef.value) {        inputRef.value.value = "";      }    };    const onAfterRead = (items) => {      resetInput();      if (isOversize(items, props.maxSize)) {        if (Array.isArray(items)) {          const result = filterFiles(items, props.maxSize);          items = result.valid;          emit("oversize", result.invalid, getDetail());          if (!items.length) {            return;          }        } else {          emit("oversize", items, getDetail());          return;        }      }      items = reactive(items);      emit("update:modelValue", [...props.modelValue, ...toArray(items)]);      if (props.afterRead) {        props.afterRead(items, getDetail());      }    };    const readFile = (files) => {      const {        maxCount,        modelValue,        resultType      } = props;      if (Array.isArray(files)) {        const remainCount = +maxCount - modelValue.length;        if (files.length > remainCount) {          files = files.slice(0, remainCount);        }        Promise.all(files.map((file) => readFileContent(file, resultType))).then((contents) => {          const fileList = files.map((file, index) => {            const result = {              file,              status: "",              message: ""            };            if (contents[index]) {              result.content = contents[index];            }            return result;          });          onAfterRead(fileList);        });      } else {        readFileContent(files, resultType).then((content) => {          const result = {            file: files,            status: "",            message: ""          };          if (content) {            result.content = content;          }          onAfterRead(result);        });      }    };    const onChange = (event) => {      const {        files      } = event.target;      if (props.disabled || !files || !files.length) {        return;      }      const file = files.length === 1 ? files[0] : [].slice.call(files);      if (props.beforeRead) {        const response = props.beforeRead(file, getDetail());        if (!response) {          resetInput();          return;        }        if (isPromise(response)) {          response.then((data) => {            if (data) {              readFile(data);            } else {              readFile(file);            }          }).catch(resetInput);          return;        }      }      readFile(file);    };    let imagePreview;    const onClosePreview = () => emit("close-preview");    const previewImage = (item) => {      if (props.previewFullImage) {        const imageFiles = props.modelValue.filter(isImageFile);        const images = imageFiles.map((item2) => {          if (item2.file && !item2.url && item2.status !== "failed") {            item2.url = URL.createObjectURL(item2.file);            urls.push(item2.url);          }          return item2.url;        }).filter(Boolean);        imagePreview = ImagePreview(extend({          images,          startPosition: imageFiles.indexOf(item),          onClose: onClosePreview        }, props.previewOptions));      }    };    const closeImagePreview = () => {      if (imagePreview) {        imagePreview.close();      }    };    const deleteFile = (item, index) => {      const fileList = props.modelValue.slice(0);      fileList.splice(index, 1);      emit("update:modelValue", fileList);      emit("delete", item, getDetail(index));    };    const renderPreviewItem = (item, index) => {      const needPickData = ["imageFit", "deletable", "previewSize", "beforeDelete"];      const previewData = extend(pick(props, needPickData), pick(item, needPickData, true));      return _createVNode(UploaderPreviewItem, _mergeProps({        "item": item,        "index": index,        "onClick": () => emit("click-preview", item, getDetail(index)),        "onDelete": () => deleteFile(item, index),        "onPreview": () => previewImage(item)      }, pick(props, ["name", "lazyLoad"]), previewData), pick(slots, ["preview-cover", "preview-delete"]));    };    const renderPreviewList = () => {      if (props.previewImage) {        return props.modelValue.map(renderPreviewItem);      }    };    const onClickUpload = (event) => emit("click-upload", event);    const renderUpload = () => {      if (props.modelValue.length >= props.maxCount || !props.showUpload) {        return;      }      const Input = props.readonly ? null : _createVNode("input", {        "ref": inputRef,        "type": "file",        "class": bem("input"),        "accept": props.accept,        "capture": props.capture,        "multiple": props.multiple,        "disabled": props.disabled,        "onChange": onChange      }, null);      if (slots.default) {        return _createVNode("div", {          "class": bem("input-wrapper"),          "onClick": onClickUpload        }, [slots.default(), Input]);      }      return _createVNode("div", {        "class": bem("upload", {          readonly: props.readonly        }),        "style": getSizeStyle(props.previewSize),        "onClick": onClickUpload      }, [_createVNode(Icon, {        "name": props.uploadIcon,        "class": bem("upload-icon")      }, null), props.uploadText && _createVNode("span", {        "class": bem("upload-text")      }, [props.uploadText]), Input]);    };    const chooseFile = () => {      if (inputRef.value && !props.disabled) {        inputRef.value.click();      }    };    onBeforeUnmount(() => {      urls.forEach((url) => URL.revokeObjectURL(url));    });    useExpose({      chooseFile,      closeImagePreview    });    useCustomFieldValue(() => props.modelValue);    return () => _createVNode("div", {      "class": bem()    }, [_createVNode("div", {      "class": bem("wrapper", {        disabled: props.disabled      })    }, [renderPreviewList(), renderUpload()])]);  }});export {  stdin_default as default};
 |