taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
175 lines (174 loc) • 5.42 kB
JavaScript
import {h, defineComponent, computed, mergeProps} from "vue";
import Taro from "@tarojs/taro";
import {uuid} from "../utils/common";
import {Image, View} from "@tarojs/components";
import AtLoading from "../loading/index";
const generateMatrix = (files, col, showAddBtn) => {
const matrix = [];
const length = showAddBtn ? files.length + 1 : files.length;
const row = Math.ceil(length / col);
for (let i = 0; i < row; i++) {
if (i === row - 1) {
const lastArr = files.slice(i * col);
if (lastArr.length < col) {
if (showAddBtn) {
lastArr.push({type: "btn", uuid: uuid()});
}
for (let j = lastArr.length; j < col; j++) {
lastArr.push({type: "blank", uuid: uuid()});
}
}
matrix.push(lastArr);
} else {
matrix.push(files.slice(i * col, (i + 1) * col));
}
}
return matrix;
};
const ENV = Taro.getEnv();
const AtImagePicker = defineComponent({
name: "AtImagePicker",
props: {
files: {
type: Array,
default: () => []
},
mode: {
type: String,
default: "aspectFill"
},
showAddBtn: {
type: Boolean,
default: true
},
multiple: Boolean,
length: {
type: Number,
default: 4
},
count: Number,
sizeType: {
type: Array,
default: () => ["original", "compressed"]
},
sourceType: {
type: Array,
default: () => ["album", "camera"]
},
onChange: {
type: Function,
default: () => () => {
}
},
onImageClick: Function,
onFail: Function
},
setup(props, {attrs}) {
const rowLength = computed(() => props.length <= 0 ? 1 : props.length);
const matrix = computed(() => generateMatrix(props.files, rowLength.value, props.showAddBtn));
function chooseFile() {
const params = {};
const filePathName = ENV === Taro.ENV_TYPE.ALIPAY ? "apFilePaths" : "tempFiles";
if (props.multiple) {
params.count = 99;
}
if (props.count) {
params.count = props.count;
}
if (props.sizeType) {
params.sizeType = props.sizeType;
}
if (props.sourceType) {
params.sourceType = props.sourceType;
}
Taro.chooseImage(params).then((res) => {
const targetFiles = res.tempFilePaths.map((path, i) => ({
url: path,
file: res[filePathName][i]
}));
const newFiles = props.files.concat(targetFiles);
props.onChange({files: newFiles, operationType: "add"});
}).catch(props.onFail);
}
function handleImageClick(idx) {
props.onImageClick && props.onImageClick(idx, props.files[idx]);
}
function handleRemoveImg(idx) {
if (ENV === Taro.ENV_TYPE.WEB) {
window.URL.revokeObjectURL(props.files[idx].url);
}
const newFiles = props.files.filter((_, i) => i !== idx);
props.onChange({files: newFiles, operationType: "remove", index: idx});
}
function renderUploadStatus(item) {
return h(View, {
class: `at-image-picker__upload-status`
}, {
default: () => {
const isUploading = item.status === "uploading";
const r = [
isUploading ? h(AtLoading, {
color: "#fff"
}) : h(View, {
class: "at-image-picker__status-icon at-image-picker__status-icon--failed"
})
];
if (item.message) {
const messageBasicClass = "at-image-picker__status-message";
r.push(h(View, {
class: `${messageBasicClass} ${messageBasicClass}--${isUploading ? "uploading" : "failed"}`
}, {default: () => item.message}));
}
return r;
}
});
}
return () => h(View, mergeProps(attrs, {
class: "at-image-picker"
}), {
default: () => matrix.value.map((row, i) => h(View, {
class: "at-image-picker__flex-box",
key: i + 1
}, {
default: () => row.map((item, j) => h(View, {
class: "at-image-picker__flex-item",
key: item.url ? `preview-${i * props.length + j}` : `add-bar-${i * props.length + j}`
}, {
default: () => [
item.url ? h(View, {
class: "at-image-picker__item"
}, {
default: () => {
const r = [
h(View, {
class: "at-image-picker__remove-btn",
onTap: handleRemoveImg.bind(this, i * props.length + j)
}),
h(Image, {
class: "at-image-picker__preview-img",
mode: props.mode,
src: item.url,
onTap: handleImageClick.bind(this, i * props.length + j)
})
];
if (item.status && item.status !== "done") {
r.push(renderUploadStatus(item));
}
return r;
}
}) : item.type === "btn" && h(View, {
class: "at-image-picker__item at-image-picker__choose-btn",
onTap: chooseFile
}, {
default: () => Array.apply(null, {length: 2}).map(() => h(View, {class: "add-bar"}))
})
]
}))
}))
});
}
});
var image_picker_default = AtImagePicker;
export {
image_picker_default as default
};