mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-23 13:31:06 +08:00
refactor(upload): createThumbnailUrl
This commit is contained in:
parent
67d6bf3fd4
commit
9829b714fe
@ -127,7 +127,8 @@ export default defineComponent({
|
||||
const handleError = (e: Event): void => {
|
||||
if (!shouldStartLoadingRef.value) return
|
||||
hasLoadErrorRef.value = true
|
||||
const { onError } = props
|
||||
const { onError, imgProps } = props
|
||||
imgProps?.onError?.(e)
|
||||
if (onError) {
|
||||
onError(e)
|
||||
}
|
||||
@ -240,8 +241,9 @@ export default defineComponent({
|
||||
shouldStartLoading: shouldStartLoadingRef,
|
||||
loaded: loadedRef,
|
||||
mergedOnLoad: (e: Event) => {
|
||||
const { onLoad } = props
|
||||
const { onLoad, imgProps } = props
|
||||
onLoad?.(e)
|
||||
imgProps?.onLoad?.(e)
|
||||
loadedRef.value = true
|
||||
}
|
||||
}
|
||||
@ -287,8 +289,9 @@ export default defineComponent({
|
||||
</VResizeObserver>
|
||||
)
|
||||
} else if (src) {
|
||||
const { imgProps } = this
|
||||
return h('img', {
|
||||
...this.imgProps,
|
||||
...imgProps,
|
||||
loading: isImageSupportNativeLazy && lazy ? 'lazy' : 'eager',
|
||||
src: isImageSupportNativeLazy
|
||||
? src
|
||||
@ -299,6 +302,7 @@ export default defineComponent({
|
||||
'data-image-src': src,
|
||||
onError: this.handleError,
|
||||
style: [
|
||||
imgProps?.style,
|
||||
{ objectFit: this.objectFit },
|
||||
placeholderNode
|
||||
? {
|
||||
|
@ -547,7 +547,7 @@ const Button = defineComponent({
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { mergedClsPrefix, renderIcon, tag: Component, onRender } = this
|
||||
const { mergedClsPrefix, tag: Component, onRender } = this
|
||||
onRender?.()
|
||||
const children = resolveWrappedSlot(
|
||||
this.$slots.default,
|
||||
@ -591,7 +591,7 @@ const Button = defineComponent({
|
||||
resolveWrappedSlot(
|
||||
this.$slots.icon,
|
||||
(children) =>
|
||||
(this.loading || renderIcon || children) && (
|
||||
(this.loading || this.renderIcon || children) && (
|
||||
<span
|
||||
class={`${mergedClsPrefix}-button__icon`}
|
||||
style={{
|
||||
@ -614,7 +614,7 @@ const Button = defineComponent({
|
||||
class={`${mergedClsPrefix}-icon-slot`}
|
||||
role="none"
|
||||
>
|
||||
{renderIcon ? renderIcon() : children}
|
||||
{this.renderIcon ? this.renderIcon() : children}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Equation
|
||||
|
||||
No one will think of that a component library should have this component. however a friend of me need this.
|
||||
No one will think of that a component library should have this component. However a friend of me need this.
|
||||
|
||||
<n-alert title="Note" type="warning" style="margin-bottom: 16px;" :bordered="false">
|
||||
Due to package size, Naive UI doesn't include katex. If you want to use Equation, make sure you have setup katex before using it.
|
||||
|
@ -1,7 +1,7 @@
|
||||
<markdown>
|
||||
# 字素计数
|
||||
|
||||
浏览器默认的 `maxlength` 和 `minlength` 以及 naive-ui 自带的字数统计功能并不能准确的拆分所有的字符串,你可以使用 `count-graphemes` 属性来精确的测量文字长度。
|
||||
浏览器默认的 `maxlength` 和 `minlength` 以及 naive-ui 自带的字数统计功能并不能准确地拆分所有的字符串,你可以使用 `count-graphemes` 属性来精确的测量文字长度。
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
|
@ -74,7 +74,7 @@ export interface InternalDropInfo {
|
||||
dropPosition: DropPosition
|
||||
}
|
||||
|
||||
export type RenderSwitcherIcon = (options: {
|
||||
export type RenderSwitcherIcon = (props: {
|
||||
expanded: boolean
|
||||
selected: boolean
|
||||
}) => VNodeChild
|
||||
|
@ -50,7 +50,8 @@ export default defineComponent({
|
||||
])
|
||||
return {
|
||||
fileList: fileListRef,
|
||||
createThumbnailUrl (file: File): Promise<string> {
|
||||
createThumbnailUrl (file: File | null): Promise<string> | undefined {
|
||||
if (!file) return undefined
|
||||
message.info(() => [
|
||||
'`createThumbnailUrl` changes the thumbnail image of the uploaded file.',
|
||||
h('br'),
|
||||
|
@ -28,7 +28,7 @@ download.vue
|
||||
| abstract | `boolean` | `false` | Whether or not DOM wrapping does not exist. Not supported for `image-card` type. | |
|
||||
| accept | `string` | `undefined` | The accept type of upload. See <n-a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept" target="_blank">accept</n-a>. | |
|
||||
| action | `string` | `undefined` | The URL to submit data to. | |
|
||||
| create-thumbnail-url | `(file: File) => Promise<string>` | `undefined` | Customize file thumbnails. | |
|
||||
| create-thumbnail-url | `(file: File \| null, fileInfo: UploadSettledFileInfo) => (Promise<string> \| string \| undefined)` | `undefined` | Customize file thumbnails. If `undefined` is returned, the file would use default thumbnail display logic. | `fileInfo` NEXT_VERSION |
|
||||
| custom-request | `(options: UploadCustomRequestOptions) => void` | `undefined` | Customize upload request. For types, see <n-a href="#UploadCustomRequestOptions-Type">UploadCustomRequestOptions</n-a> | |
|
||||
| data | `Object \| ({ file: UploadFileInfo }) => Object` | `undefined` | The additional fileds data of HTTP request's form data. | |
|
||||
| default-file-list | `Array<UploadFileInfo>` | `[]` | The default file list in uncontrolled manner. | |
|
||||
@ -47,7 +47,9 @@ download.vue
|
||||
| method | `string` | `'POST'` | The HTTP request method. | |
|
||||
| multiple | `boolean` | `false` | Allow multiple files to be selected. | |
|
||||
| name | `string` | `'file'` | The field name for the file(s) in the HTTP request's form data. | |
|
||||
| render-icon | `(file: UploadSettledFileInfo) => VNodeChild` | `undefined` | Render function of file icon. It works when `list-type="image"`. | NEXT_VERSION |
|
||||
| response-type | `'' \| 'arraybuffer' \| 'blob' \| 'document' \| 'json' \| 'text'` | `''` | Response type of `XMLHttpRequest` used by `n-upload` | 2.33.3 |
|
||||
| should-use-thumbnail-url | `(file: UploadSettledFileInfo) => boolean` | A function that only returns `true` for image typed file. | A function that determines whether to show thumbnail for the file. It only works when `list-type="image"` or `list-type="image-card"`. | NEXT_VERSION |
|
||||
| show-cancel-button | `boolean` | `true` | Show a cancel button (while uploading). Use the `on-remove` callback for this event. | |
|
||||
| show-download-button | `boolean` | `false` | Show a download button (after upload is finished). | |
|
||||
| show-file-list | `boolean` | `true` | Show a file list. | |
|
||||
|
@ -50,7 +50,8 @@ export default defineComponent({
|
||||
])
|
||||
return {
|
||||
fileList: fileListRef,
|
||||
createThumbnailUrl (file: File): Promise<string> {
|
||||
createThumbnailUrl (file: File | null): Promise<string> | undefined {
|
||||
if (!file) return undefined
|
||||
message.info(
|
||||
'createThumbnailUrl 产生了图片的 URL,你传什么都会变成 07akioni'
|
||||
)
|
||||
|
@ -29,7 +29,7 @@ debug.vue
|
||||
| abstract | `boolean` | `false` | 是否不存在 DOM 包裹,不支持 `image-card` 类型的 Upload | |
|
||||
| accept | `string` | `undefined` | 接受的文件类型,参考 <n-a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept" target="_blank">accept</n-a> | |
|
||||
| action | `string` | `undefined` | 请求提交的地址 | |
|
||||
| create-thumbnail-url | `(file: File) => Promise<string>` | `undefined` | 自定义文件缩略图 | |
|
||||
| create-thumbnail-url | `(file: File \| null, fileInfo: UploadSettledFileInfo) => (Promise<string> \| string \| undefined)` | `undefined` | 自定义文件缩略图,如果返回了 `undefined`,会使用默认的缩略图展示逻辑 | `fileInfo` NEXT_VERSION |
|
||||
| custom-request | `(options: UploadCustomRequestOptions) => void` | `undefined` | 自定义上传方法,类型参考 <n-a href="#UploadCustomRequestOptions-Type">UploadCustomRequestOptions</n-a> | |
|
||||
| data | `Object \| ({ file: UploadFileInfo }) => Object` | `undefined` | 提交表单需要附加的数据 | |
|
||||
| default-file-list | `Array<UploadFileInfo>` | `[]` | 非受控状态下默认的文件列表 | |
|
||||
@ -48,7 +48,9 @@ debug.vue
|
||||
| method | `string` | `'POST'` | HTTP 请求的方法 | |
|
||||
| multiple | `boolean` | `false` | 是否支持多个文件 | |
|
||||
| name | `string` | `'file'` | 文件在提交表单中的字段名 | |
|
||||
| render-icon | `(file: UploadSettledFileInfo) => VNodeChild` | `undefined` | 文件图标的渲染函数,在 `list-type="image"` 时生效 | NEXT_VERSION |
|
||||
| response-type | `'' \| 'arraybuffer' \| 'blob' \| 'document' \| 'json' \| 'text'` | `''` | `n-upload` 使用的 `XMLHttpRequest` 的 `responseType` | 2.33.3 |
|
||||
| should-use-thumbnail-url | `(file: UploadSettledFileInfo) => boolean` | 只对图片类文件返回 `true` 的函数 | 是否要对文件使用预览图的判定函数,只在 `list-type="image"` 或 `list-type="image-card"` 时生效 | NEXT_VERSION |
|
||||
| show-cancel-button | `boolean` | `true` | 是否显示取消按钮(在 pending、uploading、error 的时候展示),点击取消按钮会触发 `on-remove` 回调 | |
|
||||
| show-download-button | `boolean` | `false` | 是否显示下载按钮(在 finished 后展示) | |
|
||||
| show-remove-button | `boolean` | `true` | 是否显示删除按钮(在 finished 后时候展示),点击删除按钮会触发 `on-remove` 回调 | |
|
||||
|
@ -347,7 +347,7 @@ export const uploadProps = {
|
||||
shouldUseThumbnailUrl: {
|
||||
type: Function as PropType<ShouldUseThumbnailUrl>,
|
||||
default: (file: SettledFileInfo) => {
|
||||
if (!environmentSupportFile || !(file.file instanceof File)) return false
|
||||
if (!environmentSupportFile) return false
|
||||
return isImageFile(file)
|
||||
}
|
||||
},
|
||||
@ -595,11 +595,20 @@ export default defineComponent({
|
||||
warn('upload', 'File has no corresponding id in current file list.')
|
||||
}
|
||||
}
|
||||
async function getFileThumbnailUrl (file: SettledFileInfo): Promise<string> {
|
||||
function getFileThumbnailUrlResolver (
|
||||
file: SettledFileInfo
|
||||
): Promise<string> | string {
|
||||
if (file.thumbnailUrl) return file.thumbnailUrl
|
||||
const { createThumbnailUrl } = props
|
||||
return createThumbnailUrl
|
||||
? await createThumbnailUrl(file.file, file)
|
||||
: await createImageDataUrl(file.file)
|
||||
if (createThumbnailUrl) {
|
||||
return createThumbnailUrl(file.file, file) ?? (file.url || '')
|
||||
}
|
||||
if (file.url) {
|
||||
return file.url
|
||||
} else if (file.file) {
|
||||
return createImageDataUrl(file.file)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
const cssVarsRef = computed(() => {
|
||||
const {
|
||||
@ -662,7 +671,7 @@ export default defineComponent({
|
||||
doChange,
|
||||
showPreviewButtonRef: toRef(props, 'showPreviewButton'),
|
||||
onPreviewRef: toRef(props, 'onPreview'),
|
||||
getFileThumbnailUrl,
|
||||
getFileThumbnailUrlResolver,
|
||||
listTypeRef: toRef(props, 'listType'),
|
||||
dragOverRef,
|
||||
openOpenFileDialog,
|
||||
|
@ -190,7 +190,9 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
if (NUpload.shouldUseThumbnailUrlRef.value(props.file)) {
|
||||
thumbnailUrlRef.value = await NUpload.getFileThumbnailUrl(props.file)
|
||||
thumbnailUrlRef.value = await NUpload.getFileThumbnailUrlResolver(
|
||||
props.file
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,9 @@ export interface UploadInjection {
|
||||
onRender: undefined | (() => void)
|
||||
submit: (fileId?: string) => void
|
||||
shouldUseThumbnailUrlRef: Ref<ShouldUseThumbnailUrl>
|
||||
getFileThumbnailUrl: (file: SettledFileInfo) => Promise<string>
|
||||
getFileThumbnailUrlResolver: (
|
||||
file: SettledFileInfo
|
||||
) => Promise<string> | string
|
||||
renderIconRef: Ref<RenderIcon | undefined>
|
||||
handleFileAddition: (files: FileAndEntry[] | null, e?: Event) => void
|
||||
openOpenFileDialog: () => void
|
||||
@ -137,7 +139,7 @@ export type OnPreview = (file: SettledFileInfo) => void
|
||||
export type CreateThumbnailUrl = (
|
||||
file: File | null,
|
||||
fileInfo: SettledFileInfo
|
||||
) => Promise<string>
|
||||
) => Promise<string> | string | undefined
|
||||
|
||||
export interface CustomRequestOptions {
|
||||
file: SettledFileInfo
|
||||
|
@ -16,6 +16,7 @@ const getExtname = (url: string = ''): string => {
|
||||
return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0]
|
||||
}
|
||||
|
||||
// Do not need File object
|
||||
export const isImageFile: ShouldUseThumbnailUrl = (file) => {
|
||||
if (file.type) {
|
||||
return isImageFileType(file.type)
|
||||
@ -34,18 +35,15 @@ export const isImageFile: ShouldUseThumbnailUrl = (file) => {
|
||||
if (extension) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
export async function createImageDataUrl (file: File | null): Promise<string> {
|
||||
if (!file) return ''
|
||||
export async function createImageDataUrl (file: File): Promise<string> {
|
||||
return await new Promise((resolve) => {
|
||||
if (!file.type || !isImageFileType(file.type)) {
|
||||
resolve('')
|
||||
return
|
||||
}
|
||||
|
||||
resolve(window.URL.createObjectURL(file))
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user