!32 el-upload结合插件vue-picture-cropper Main Navigation来实现图片裁剪,可指定裁剪窗口大小。独立成单一组件
Merge pull request !32 from pu皮/master
This commit is contained in:
@@ -65,6 +65,7 @@
|
|||||||
"sortablejs": "^1.15.3",
|
"sortablejs": "^1.15.3",
|
||||||
"vue": "^3.5.12",
|
"vue": "^3.5.12",
|
||||||
"vue-i18n": "9.9.1",
|
"vue-i18n": "9.9.1",
|
||||||
|
"vue-picture-cropper": "^0.7.0",
|
||||||
"vue-router": "^4.4.5"
|
"vue-router": "^4.4.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
9762
pnpm-lock.yaml
generated
9762
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
92
src/components/ImgCorpper/compressUtil.js
Normal file
92
src/components/ImgCorpper/compressUtil.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* 图片压缩类
|
||||||
|
* @param minSize
|
||||||
|
* @param maxSize
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
export function PhotoCompress(minSize, maxSize) {
|
||||||
|
var nextQ = 0.5; // 压缩比例
|
||||||
|
var maxQ = 1;
|
||||||
|
var minQ = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将base64转换为文件
|
||||||
|
* @param base64Codes base64编码
|
||||||
|
* @param fileName 文件名称
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
PhotoCompress.prototype.dataUrlToFile = function (base64Codes, fileName = new Date().getTime()) {
|
||||||
|
var arr = base64Codes.split(","),
|
||||||
|
mime = arr[0].match(/:(.*?);/)[1],
|
||||||
|
bStr = atob(arr[1]),
|
||||||
|
n = bStr.length,
|
||||||
|
u8arr = new Uint8Array(n);
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bStr.charCodeAt(n);
|
||||||
|
}
|
||||||
|
return new File([u8arr], fileName, { type: mime });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片压缩
|
||||||
|
* @param file 文件
|
||||||
|
* @param callback 回调函数
|
||||||
|
*/
|
||||||
|
PhotoCompress.prototype.compress = function (file, callback) {
|
||||||
|
var self = this;
|
||||||
|
self.imgBase64(file, function (image, canvas) {
|
||||||
|
var base64Codes = canvas.toDataURL(file.type, nextQ); // y压缩
|
||||||
|
var compressFile = self.dataUrlToFile(base64Codes, file.name.split(".")[0]); // 转成file文件
|
||||||
|
var compressFileSize = compressFile.size; // 压缩后文件大小 k
|
||||||
|
// console.log("图片质量:" + nextQ);
|
||||||
|
// console.log("压缩后文件大小:" + compressFileSize / 1024);
|
||||||
|
if (compressFileSize > maxSize) {
|
||||||
|
// 压缩后文件大于最大值
|
||||||
|
maxQ = nextQ;
|
||||||
|
nextQ = (nextQ + minQ) / 2; // 质量降低
|
||||||
|
self.compress(file, callback);
|
||||||
|
} else if (compressFileSize < minSize) {
|
||||||
|
// 压缩以后文件小于最小值
|
||||||
|
minQ = nextQ;
|
||||||
|
nextQ = (nextQ + maxQ) / 2; // 质量提高
|
||||||
|
self.compress(file, callback);
|
||||||
|
} else {
|
||||||
|
callback(compressFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将图片转化为base64
|
||||||
|
* @param file 文件
|
||||||
|
* @param callback 回调函数
|
||||||
|
*/
|
||||||
|
PhotoCompress.prototype.imgBase64 = function (file, callback) {
|
||||||
|
// 看支持不支持FileReader
|
||||||
|
if (!file || !window.FileReader) return;
|
||||||
|
var image = new Image();
|
||||||
|
// 绑定 load 事件处理器,加载完成后执行
|
||||||
|
image.onload = function () {
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
canvas.width = image.width * nextQ;
|
||||||
|
canvas.height = image.height * nextQ;
|
||||||
|
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
||||||
|
callback(image, canvas);
|
||||||
|
};
|
||||||
|
if (/^image/.test(file.type)) {
|
||||||
|
// 创建一个reader
|
||||||
|
var reader = new FileReader();
|
||||||
|
// 将图片将转成 base64 格式
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
// 读取成功后的回调
|
||||||
|
reader.onload = function () {
|
||||||
|
// self.imgUrls.push(this.result);
|
||||||
|
// 设置src属性,浏览器会自动加载。
|
||||||
|
// 记住必须先绑定事件,才能设置src属性,否则会出同步问题。
|
||||||
|
image.src = this.result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
205
src/components/ImgCorpper/corpperDialog.vue
Normal file
205
src/components/ImgCorpper/corpperDialog.vue
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="isShowModal"
|
||||||
|
title="裁剪图片"
|
||||||
|
width="50%"
|
||||||
|
:close-on-press-escape="false"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
align-center
|
||||||
|
@close="cancel"
|
||||||
|
>
|
||||||
|
<div class="modal-content">
|
||||||
|
<VuePictureCropper
|
||||||
|
:img="pic"
|
||||||
|
:boxStyle="corpBoxStyle"
|
||||||
|
:options="corpOptions"
|
||||||
|
:presetMode="corpPresetMode"
|
||||||
|
@ready="ready"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="m-t-10 btns">
|
||||||
|
<el-button class="default-btn" @click="cancel">取消</el-button>
|
||||||
|
<el-button v-if="showClear" class="default-btn" @click="clear">关闭</el-button>
|
||||||
|
<el-button v-if="showReset" class="default-btn" @click="reset">重置</el-button>
|
||||||
|
<el-button class="default-btn primary" @click="getResult">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 组件文档:https://cropper.chengpeiquan.com/zh/quick-start.html
|
||||||
|
import VuePictureCropper, { cropper } from "vue-picture-cropper";
|
||||||
|
import { PhotoCompress } from "./compressUtil.js";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
type: [String, File],
|
||||||
|
},
|
||||||
|
presetMode: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
boxStyle: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
showClear: {
|
||||||
|
// 是否显示 Clear 按钮
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
showReset: {
|
||||||
|
// 是否显示 Reset 按钮
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
isCompress: {
|
||||||
|
// 是否压缩裁剪后的图片大小
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
compressSize: {
|
||||||
|
// 压缩图片大小限制
|
||||||
|
type: Object,
|
||||||
|
default: {
|
||||||
|
maxSize: 0.3 * 1024 * 1024, // 300k
|
||||||
|
minSize: 0.03 * 1024 * 1024, // 30k
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 裁剪组件属性配置 */
|
||||||
|
const corpOptions = computed(() => {
|
||||||
|
return {
|
||||||
|
viewMode: 1, // 裁剪框范围 1-只能在图片区域内活动
|
||||||
|
dragMode: "move", // 可选值 crop(可绘制裁剪框) | move(仅移动)
|
||||||
|
// aspectRatio: 1 / 1,// 裁剪框的宽高比
|
||||||
|
cropBoxResizable: false, // 是否可以调整裁剪区的大小
|
||||||
|
...props.options,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
/** 裁剪区域的样式 */
|
||||||
|
const corpBoxStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
width: "auto",
|
||||||
|
height: "400px",
|
||||||
|
backgroundColor: "#f8f8f8",
|
||||||
|
margin: "auto",
|
||||||
|
...props.boxStyle,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 预设模式配置 */
|
||||||
|
const corpPresetMode = computed(() => {
|
||||||
|
return {
|
||||||
|
mode: "fixedSize",
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
...props.presetMode,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["close"]);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(val) => {
|
||||||
|
isShowModal.value = val;
|
||||||
|
if (!val) {
|
||||||
|
pic.value = "";
|
||||||
|
result.dataURL = "";
|
||||||
|
result.blobURL = "";
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.image,
|
||||||
|
(val) => {
|
||||||
|
pic.value = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const isShowModal = ref(false);
|
||||||
|
const pic = ref("");
|
||||||
|
const result = reactive({
|
||||||
|
dataURL: "",
|
||||||
|
blobURL: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getResult() {
|
||||||
|
if (!cropper) return;
|
||||||
|
const base64 = cropper.getDataURL();
|
||||||
|
const blob = await cropper.getBlob();
|
||||||
|
if (!blob) return;
|
||||||
|
|
||||||
|
let file = await cropper.getFile({
|
||||||
|
fileName: "locales.fileName",
|
||||||
|
});
|
||||||
|
|
||||||
|
result.dataURL = base64;
|
||||||
|
result.blobURL = URL.createObjectURL(blob);
|
||||||
|
const { minSize, maxSize } = props.compressSize;
|
||||||
|
// console.log(file.size, maxSize)
|
||||||
|
// 是否限制文件大小
|
||||||
|
if (props.isCompress && file.size > maxSize) {
|
||||||
|
// console.log("compress")
|
||||||
|
const photoCompress = new PhotoCompress(minSize, maxSize);
|
||||||
|
photoCompress.compress(file, function (f) {
|
||||||
|
const r = new FileReader();
|
||||||
|
r.readAsDataURL(f);
|
||||||
|
r.onload = function (e) {
|
||||||
|
emits("close", { result, file: f });
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// console.log("crop")
|
||||||
|
emits("close", { result, file });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the crop box
|
||||||
|
*/
|
||||||
|
function clear() {
|
||||||
|
if (!cropper) return;
|
||||||
|
cropper.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the default cropping area
|
||||||
|
*/
|
||||||
|
function reset() {
|
||||||
|
if (!cropper) return;
|
||||||
|
cropper.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ready event passed to Cropper.js
|
||||||
|
*/
|
||||||
|
function ready() {
|
||||||
|
// console.log('Cropper is ready.')
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel() {
|
||||||
|
emits("close");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.modal-wrap {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btns {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
211
src/components/ImgCorpper/index.vue
Normal file
211
src/components/ImgCorpper/index.vue
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
<template>
|
||||||
|
<el-upload
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
list-type="picture-card"
|
||||||
|
:auto-upload="true"
|
||||||
|
:class="fileList.length >= 1 || !props.showUploadBtn ? 'hide' : 'show'"
|
||||||
|
:before-upload="handleBeforeUpload"
|
||||||
|
:data="props.data"
|
||||||
|
:name="props.name"
|
||||||
|
:accept="props.accept"
|
||||||
|
:limit="1"
|
||||||
|
>
|
||||||
|
<i-ep-plus />
|
||||||
|
{{ title }}
|
||||||
|
<template #file="{ file }">
|
||||||
|
<div style="width: 100%">
|
||||||
|
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
||||||
|
<span class="el-upload-list__item-actions">
|
||||||
|
<span class="el-upload-list__item-preview" @click="previewImg(file)">
|
||||||
|
<el-icon><zoom-in /></el-icon>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-if="props.showDelBtn"
|
||||||
|
class="el-upload-list__item-delete"
|
||||||
|
@click="handleRemove(file)"
|
||||||
|
>
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
<el-image-viewer
|
||||||
|
v-if="viewVisible"
|
||||||
|
:zoom-rate="1.2"
|
||||||
|
:initialIndex="initialIndex"
|
||||||
|
:url-list="[viewFile]"
|
||||||
|
@close="closePreview"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CorpperDialog
|
||||||
|
:visible="isShowCorpper"
|
||||||
|
:image="selectPic"
|
||||||
|
:isCompress="true"
|
||||||
|
:showReset="true"
|
||||||
|
:presetMode="presetMode"
|
||||||
|
@close="hideCorpper"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import CorpperDialog from "./corpperDialog.vue";
|
||||||
|
|
||||||
|
import { UploadRawFile, UploadUserFile, UploadFile, UploadProps } from "element-plus";
|
||||||
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
/**
|
||||||
|
* 文件路径
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "上传图片",
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件的参数名
|
||||||
|
*/
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: "file",
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 文件上传数量限制
|
||||||
|
*/
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 是否显示删除按钮
|
||||||
|
*/
|
||||||
|
showDelBtn: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 是否显示上传按钮
|
||||||
|
*/
|
||||||
|
showUploadBtn: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 单张图片最大大小
|
||||||
|
*/
|
||||||
|
uploadMaxSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 2 * 1024 * 1024,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 上传文件类型
|
||||||
|
*/
|
||||||
|
accept: {
|
||||||
|
type: String,
|
||||||
|
default: "image/*",
|
||||||
|
},
|
||||||
|
|
||||||
|
presetMode: {
|
||||||
|
type: Object,
|
||||||
|
default: "{ width: 200, height: 200 }",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectPic = ref("");
|
||||||
|
const isShowCorpper = ref(false);
|
||||||
|
|
||||||
|
const viewVisible = ref(false);
|
||||||
|
const initialIndex = ref(0);
|
||||||
|
|
||||||
|
const fileList = ref([] as UploadUserFile[]);
|
||||||
|
const viewFile = ref(props.modelValue as string);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newVal: string) => {
|
||||||
|
if (!newVal) {
|
||||||
|
fileList.value = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileList.value = [{ url: newVal } as UploadUserFile];
|
||||||
|
|
||||||
|
viewFile.value = newVal;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* 删除图片
|
||||||
|
*/
|
||||||
|
function handleRemove(removeFile: UploadFile) {
|
||||||
|
const filePath = removeFile.url;
|
||||||
|
if (filePath) {
|
||||||
|
emit("update:modelValue", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限制用户上传文件的格式和大小
|
||||||
|
*/
|
||||||
|
function handleBeforeUpload(file: UploadRawFile) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = () => {
|
||||||
|
selectPic.value = String(reader.result);
|
||||||
|
isShowCorpper.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (file.size > props.uploadMaxSize) {
|
||||||
|
ElMessage.warning("上传图片不能大于 " + Math.trunc(props.uploadMaxSize / 1024 / 1024) + "M");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预览图片
|
||||||
|
*/
|
||||||
|
const previewImg: UploadProps["onPreview"] = (uploadFile: UploadFile) => {
|
||||||
|
viewFile.value = uploadFile.url!;
|
||||||
|
initialIndex.value = 0;
|
||||||
|
viewVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭预览
|
||||||
|
*/
|
||||||
|
const closePreview = () => {
|
||||||
|
viewVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
function hideCorpper(data: any) {
|
||||||
|
isShowCorpper.value = false;
|
||||||
|
if (data) {
|
||||||
|
const {
|
||||||
|
result: { dataURL },
|
||||||
|
file,
|
||||||
|
} = data;
|
||||||
|
emit("update:modelValue", dataURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.hide {
|
||||||
|
:deep(.el-upload--picture-card) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.show {
|
||||||
|
:deep(.el-upload--picture-card) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1
src/types/components.d.ts
vendored
1
src/types/components.d.ts
vendored
@@ -91,6 +91,7 @@ declare module "vue" {
|
|||||||
ThemeColorPicker: (typeof import("./../layout/components/Settings/components/ThemeColorPicker.vue"))["default"];
|
ThemeColorPicker: (typeof import("./../layout/components/Settings/components/ThemeColorPicker.vue"))["default"];
|
||||||
SingleImageUpload: (typeof import("./../components/Upload/SingleImageUpload.vue"))["default"];
|
SingleImageUpload: (typeof import("./../components/Upload/SingleImageUpload.vue"))["default"];
|
||||||
WangEditor: (typeof import("./../components/WangEditor/index.vue"))["default"];
|
WangEditor: (typeof import("./../components/WangEditor/index.vue"))["default"];
|
||||||
|
ImgCorpper: (typeof import("./../components/ImgCorpper/index.vue"))["default"];
|
||||||
}
|
}
|
||||||
export interface ComponentCustomProperties {
|
export interface ComponentCustomProperties {
|
||||||
vLoading: (typeof import("element-plus/es"))["ElLoadingDirective"];
|
vLoading: (typeof import("element-plus/es"))["ElLoadingDirective"];
|
||||||
|
|||||||
@@ -23,6 +23,22 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="单图裁剪">
|
||||||
|
<ImgCorpper
|
||||||
|
v-model="cprpperValue"
|
||||||
|
:presetMode="{ width: 295, height: 413 }"
|
||||||
|
:title="'上传图片'"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="参数说明">
|
||||||
|
<el-table :data="imageCprpperUploadArgData" border>
|
||||||
|
<el-table-column prop="argsName" label="参数名称" width="300" />
|
||||||
|
<el-table-column prop="type" label="参数类型" width="200" />
|
||||||
|
<el-table-column prop="default" label="默认值" width="400" />
|
||||||
|
<el-table-column prop="desc" label="描述" width="300" />
|
||||||
|
</el-table>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="多图上传">
|
<el-form-item label="多图上传">
|
||||||
<MultiImageUpload v-model="picUrls" />
|
<MultiImageUpload v-model="picUrls" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -81,6 +97,29 @@ const singleImageUploadArgData = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const imageCprpperUploadArgData = [
|
||||||
|
{
|
||||||
|
argsName: "v-model",
|
||||||
|
type: "Object",
|
||||||
|
default: "",
|
||||||
|
desc: "裁剪后图片Base64编码",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
argsName: "presetMode",
|
||||||
|
type: "String",
|
||||||
|
default: "{ width: 295, height: 413 }",
|
||||||
|
desc: "裁剪窗口的长宽,及裁剪图片大小",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
argsName: "title",
|
||||||
|
type: "String",
|
||||||
|
default: "上传图片",
|
||||||
|
desc: "组件内容",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const cprpperValue = ref();
|
||||||
|
|
||||||
// 多图
|
// 多图
|
||||||
const picUrls = ref([
|
const picUrls = ref([
|
||||||
"https://s2.loli.net/2023/05/24/yNsxFC8rLHMZQcK.jpg",
|
"https://s2.loli.net/2023/05/24/yNsxFC8rLHMZQcK.jpg",
|
||||||
|
|||||||
Reference in New Issue
Block a user