图片上传一站式解决方案。
⚠ DEPRECATED
Warning
ImgPond 已推出 Element Plus (Vue 3) & Element UI (Vue 2.7/2.6) 一体通用版本
不仅能力得到增强,为了后续的漏洞修复和迭代优化,请迁移至原作者 cloydlau 的 faim
特性
- 数据双向绑定
v-model
,支持任意绑定值类型 - 数据源
- 用户选择本地文件 (File)
- 编程式提供数据源 (File/Blob/Base64/URL/object URL)
- 编辑图片
- 格式转换
- 尺寸指定
- 品质调节
- 自由裁剪 & 锁定比例裁剪
- 翻转、缩放、无级角度旋转
- 限制图片
- 格式筛选
- 尺寸或尺寸范围 (间接限制宽高比例)
- 大小上限、下限
- 数量上限、下限
- 自定义校验
- 多选
- 拖拉拽排序
- 预览图片 (pic-viewer 提供技术支持)
- 局部注册并传参,或全局注册并传参 (vue-global-config 提供技术支持)
安装
npm i imgpond
外置依赖
- vue@2
- element-ui
- pic-viewer
局部注册
<script>
import Vue from 'vue'
import PicViewer from 'pic-viewer'
import ImgPond from 'imgpond'
Vue.use(PicViewer, {
// 全局配置
})
export default {
components: { ImgPond },
}
</script>
<template>
<ImgPond
v-model="value"
v-bind="{/* 局部配置 */}"
/>
</template>
全局注册
import PicViewer from 'pic-viewer'
import ImgPond from 'imgpond'
Vue.use(PicViewer, {
})
Vue.use(ImgPond, {
})
CDN + ESM
⚠ 暂不支持 (ElementUI 未提供 ESM 导出)
CDN + IIFE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/element-ui/lib/theme-chalk/index.css"
>
</head>
<body>
<div id="app">
<img-pond v-model="value"></img-pond>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.jsdelivr.net/npm/element-ui/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pic-viewer@0.11"></script>
<script src="https://cdn.jsdelivr.net/npm/imgpond@0.14"></script>
<script>
Vue.use(PicViewer)
Vue.use(ImgPond)
new Vue({
data() {
return {
value: undefined,
}
},
}).$mount('#app')
</script>
</body>
</html>
属性
名称 | 说明 | 类型 | 默认值 |
---|
value / v-model | 绑定值 | any | |
arrayed | 绑定值是否为数组类型,默认自动 | boolean | |
srcAt | 图片链接的位置 | string / symbol / (value: any) => any | |
upload | 调用接口上传图片,返回图片链接 | (output: File | Blob) => Promise<string | object> | string | object | void | |
count | 数量限制 | number / [number?, number?] | |
size | 大小限制 (MB) | number / [number?, number?] | |
accept | 图片格式筛选 | string | 'image/*' |
outputType | 图片输出格式 (编辑后),默认原格式 | string | |
validator | 自定义数据源校验器 | (source: File | Blob | string) => boolean | |
disabled | 禁用状态 | boolean | false |
editable | 是否开启编辑功能 | boolean | true |
width | 宽度或宽度范围 (像素) | number / [number?, number?] | |
height | 高度或高度范围 (像素) | number / [number?, number?] | |
aspectRatioTolerance | 锁定裁剪比例的公差 | number | 0 |
arrayed
如果数量上限和图片数量均不超过 1,则处于单选状态,否则为多选
默认情况下,在单选时输出的绑定值形如:item,多选时输出的绑定值形如:[item,item]
item 具体是什么格式?
未配置 srcAt 时,会提取图片链接作为 item,配置了则不会
如果将 arrayed 设置为 true
则强制输出数组类型,无论单选还是多选
如果将 arrayed 设置为 false
则强制输出非数组类型,如果此时图片数量为多个,则会执行 JSON.stringify
srcAt
用于定位 value 和 upload 返回值中的图片链接,适用于绑定值非图片链接本身的情况
- 支持属性名,如
'url'
- 支持属性路径,如
'data[0].url'
- 支持 symbol 类型的属性名
- 支持 Function,如
value => value.url
upload
开启编辑功能时,会在编辑完成后调用,未开启编辑功能时,会在选择图片后调用
未配置或函数返回值为空时,绑定值将输出二进制文件
参数为编辑产物:
用户选择本地文件、编程式提供 File 类型的数据源时,编辑产物的类型为 File
编程式提供非 File 类型的数据源且编辑了图片时,编辑产物的类型为 Blob
未开启编辑功能或未编辑时,编辑产物即输入值
编程式提供 string 类型的数据源且未编辑时,不需要上传,该方法不会被调用
返回值类型为 Promise<object> 或 object 时需要配置 srcAt
count
10
:限制数量上限为 10 张[1]
:限制数量下限为 1 张[, 10]
:限制数量上限为 10 张[1, 10]
:限制数量下限为 1 张,且上限为 10 张
size
10
:限制大小上限为 10 MB[1]
:限制大小下限为 1 MB[, 10]
:限制大小上限为 10 MB[1, 10]
:限制大小下限为 1 MB,且上限为 10 MB
width
100
:限制宽度为 100 像素[100]
:限制宽度下限为 100 像素[, 200]
:限制宽度上限为 200 像素[100, 200]
:限制宽度下限 100 像素,且上限为 200 像素
height
100
:限制高度为 100 像素[100]
:限制高度下限为 100 像素[, 200]
:限制高度上限为 200 像素[100, 200]
:限制高度下限 100 像素,且上限为 200 像素
accept
通过文件对话框选择图片时,优先展示指定类型的文件,同原生 input 的 accept
⚠ 用户仍可以选择其它类型,文件类型校验应使用 validator
可选值:
- 文件扩展名,不区分大小写,如
'.jpg.jpeg.png'
- MIME type,如
'image/jpeg,image/png'
outputType
开启编辑模式时,可以指定输出的图片格式,可选值参考 MIME type
插槽
同 el-upload
事件
名称 | 说明 | 回调参数 |
---|
size-error | 未开启编辑模式,且图片大小不符合要求时触发 | 图片体积 (Byte) |
width-error | 未开启编辑模式,且图片宽度不符合要求时触发 | 图片宽度 (像素) |
height-error | 未开启编辑模式,且图片高度不符合要求时触发 | 图片高度 (像素) |
... | el-upload 的事件 (Function 类型的属性,去掉 on 前缀) | |
<ImgPond
@remove="onRemove"
@beforeUpload="onBeforeUpload"
/>
方法
名称 | 说明 | 参数 |
---|
openEditor | 打开图片编辑对话框 | (source: File | Blob | string | File[] | Blob[] | string[]) => void |
参数为输入的数据源,支持的数据类型有:
- File
- Blob
- Base64
- URL:需要跨域支持
- object URL:需要在当前
document
创建
如果没有编辑图片,则输出值类型不变 (与输入值一致)
如果编辑了图片,输入类型为 File 时,输出类型也为 File,其它情况均输出 Blob 类型
如果未开启编辑模式,且限制了图片大小或宽高,则需要 await openEditor(...)
编程式提供数据源
<!-- 示例: 输入图片链接进行编辑 -->
<!-- 如果需要附加图片名称,可以先转换为 File 类型再输入 -->
<script setup>
const imgPondRef = ref()
async function urlToFile(url, fileName) {
const blob = await (await fetch(url)).blob()
return new File([blob], fileName, { type: blob.type })
}
async function openEditor() {
const file = urlToFile('https://picsum.photos/100', '100x100.jpg')
await imgPondRef.value.openEditor(file)
}
function upload(file) {
return POST.upload(import.meta.env.VITE_APP_UPLOAD_API, {
file,
}).then(res => res.data.data)
}
</script>
<template>
<ImgPond
v-show="false"
ref="imgPondRef"
:upload="upload"
/>
<el-button @click="openEditor">
编辑图片
</el-button>
</template>
校验文件扩展名
<script setup>
const accept = '.jpg,.jpeg,.png'
const extension = accept.split(',')
function validator(source) {
let valid = true
if (source instanceof File) {
valid = extension.includes(source.name.replace(/.+\./, '.').toLowerCase())
if (!valid) {
alert(`"${source.name}" 的格式不在可支持范围: ${accept}`)
}
}
return valid
}
</script>
<template>
<ImgPond
:accept="accept"
:validator="validator"
/>
</template>
输出体积
图片经过编辑后,输出的体积与以下因素相关:
- 原图体积
- 配置或用户设置的图片宽度
- 配置或用户设置的图片高度
- 配置的图片格式
- 用户设置的品质系数
上传状态
<script setup>
const imgPondRef = ref()
console.log(imgPondRef.value.uploading)
</script>
<template>
<ImgPond ref="imgPondRef" />
</template>
自定义上传时机
- 不配置 upload,绑定值得到二进制文件
- 将 srcAt 配置为
'url'
,使图片能够正常预览 - 在适当时机自行上传
自定义 trigger
<template>
<ImgPond
class="custom-trigger"
list-type="text"
mb="8px"
>
<el-button>自定义 trigger</el-button>
</ImgPond>
</template>
<style lang="scss" scoped>
.custom-trigger {
:deep(.pic-viewer),
:deep(.el-upload-list),
:deep(.el-upload__tip),
:deep(.el-upload__text) {
display: none;
}
}
</style>
自定义 tip
<ImgPond
:width="200"
:height="100"
:size="10"
:count="1"
>
<template #tip="{ count, size, dimension, accept }">
<div>{{ count }}</div>
<div>{{ size }}</div>
<div>{{ dimension }}</div>
<div>{{ accept }}</div>
</template>
</ImgPond>
嵌套在表格中
以宽高 50px
为例,修改为如下样式:
:deep(.pic-viewer li) {
margin: 0 !important;
img {
height: 50px !important;
}
}
:deep(.el-upload-list__item) {
width: 50px;
height: 50px;
margin: 0;
&>.el-upload-list__item-status-label {
width: 34px;
height: 18px;
&>i {
margin-top: 0;
}
}
.el-upload-list__item-actions {
line-height: 50px;
font-size: 16px;
&>span+span {
margin-left: 4px;
}
}
}
:deep(.el-upload) {
width: 50px;
height: 50px;
line-height: 50px;
margin: 0;
&>.el-icon-plus {
font-size: initial;
}
&>.el-upload__text {
display: none;
}
}
更新日志
各版本详细改动请参考 release notes