diff --git a/packages/devui-vue/devui/image-preview/src/image-preview-directive.ts b/packages/devui-vue/devui/image-preview/src/image-preview-directive.ts index 5317dff6d37f419071351c395870ed25f4420ade..471fee809ce815d67e0914f7b79637ee8914d2bf 100644 --- a/packages/devui-vue/devui/image-preview/src/image-preview-directive.ts +++ b/packages/devui-vue/devui/image-preview/src/image-preview-directive.ts @@ -1,8 +1,18 @@ -import { BindingTypes } from './image-preview-types' +import { BindingTypes, ImagePreviewProps } from './image-preview-types' import ImagePreviewService from './image-preview-service' -function mountedPreviewImages(url: string, urlList: Array): void { - ImagePreviewService.open({ url, previewUrlList: urlList }) +interface PreviewHTMLElement extends HTMLElement { + zIndex?: number + backDropZIndex?: number +} + +function mountedPreviewImages(props: ImagePreviewProps): void { + ImagePreviewService.open({ + url: props.url, + previewUrlList: props.previewUrlList, + zIndex: props.zIndex, + backDropZIndex: props.backDropZIndex + }) } function unmountedPreviewImages() { ImagePreviewService.close() @@ -15,20 +25,25 @@ function getImgByEl(el: HTMLElement): Array { return urlList } -function handleImgByEl(el: HTMLElement) { +function handleImgByEl(el: PreviewHTMLElement) { el.addEventListener('click', (e: MouseEvent) => { e.stopPropagation() - const target = e.target as HTMLElement + const target = e.target as PreviewHTMLElement if (target?.nodeName?.toLowerCase() === 'img') { const urlList = getImgByEl(el) const url = target.getAttribute('src') - mountedPreviewImages(url, urlList) + mountedPreviewImages({ + url, + previewUrlList: urlList, + zIndex: el?.zIndex, + backDropZIndex: el?.backDropZIndex + }) } }) } export default { - mounted(el: HTMLElement, binding: BindingTypes | undefined) { + mounted(el: PreviewHTMLElement, binding: BindingTypes | undefined) { if (!binding.value) { return handleImgByEl(el) } @@ -37,7 +52,12 @@ export default { if (custom instanceof Object) { custom.open = () => { const urlList = getImgByEl(el) - mountedPreviewImages(urlList?.[0], urlList) + mountedPreviewImages({ + url: urlList?.[0], + previewUrlList: urlList, + zIndex: el?.zIndex, + backDropZIndex: el?.backDropZIndex + }) } custom.close = () => unmountedPreviewImages() } @@ -48,5 +68,9 @@ export default { }, unmounted() { unmountedPreviewImages() + }, + updated(el: PreviewHTMLElement, binding) { + el.zIndex = binding.value?.zIndex + el.backDropZIndex = binding.value?.backDropZIndex } } diff --git a/packages/devui-vue/devui/image-preview/src/image-preview-types.ts b/packages/devui-vue/devui/image-preview/src/image-preview-types.ts index 1f4053cb665ef1edabc0a59b2d25bb748cc7c945..c98bc03c210db016fdfd7c63cc8dbd84861af1cf 100644 --- a/packages/devui-vue/devui/image-preview/src/image-preview-types.ts +++ b/packages/devui-vue/devui/image-preview/src/image-preview-types.ts @@ -3,11 +3,21 @@ import type { PropType, ExtractPropTypes } from 'vue' export const imagePreviewProps = { url: { type: String, - default: '' + default: '', + required: true }, previewUrlList: { type: Array as PropType, - default: () => [] + default: () => [], + required: true + }, + zIndex: { + type: Number, + required: false + }, + backDropZIndex: { + type: Number, + required: false } } as const diff --git a/packages/devui-vue/devui/image-preview/src/image-preview.scss b/packages/devui-vue/devui/image-preview/src/image-preview.scss index 28a4f786dd980e419912750b48f772bc6009ef34..49c07261e291d6ba90e10ae8bf1e7b12875f2f66 100644 --- a/packages/devui-vue/devui/image-preview/src/image-preview.scss +++ b/packages/devui-vue/devui/image-preview/src/image-preview.scss @@ -9,10 +9,7 @@ top: 0; right: 0; bottom: 0; - z-index: calc(#{$devui-z-index-modal} - 1); - background: $devui-shadow; - border-radius: $devui-border-radius; - box-shadow: $devui-shadow-length-fullscreen-overlay $devui-shadow; + z-index: calc(#{$devui-z-index-modal}); display: flex; align-items: center; justify-content: center; @@ -113,3 +110,14 @@ } } } +.devui-image-preview-bg { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + z-index: calc(#{$devui-z-index-modal} - 1); + background: $devui-shadow; + border-radius: $devui-border-radius; + box-shadow: $devui-shadow-length-fullscreen-overlay $devui-shadow; +} diff --git a/packages/devui-vue/devui/image-preview/src/image-preview.tsx b/packages/devui-vue/devui/image-preview/src/image-preview.tsx index 3076a4e2cd584834a394340c44b9679700c2d76c..052e73dbbcfe52777406f248bd0886983943b6b0 100644 --- a/packages/devui-vue/devui/image-preview/src/image-preview.tsx +++ b/packages/devui-vue/devui/image-preview/src/image-preview.tsx @@ -1,5 +1,5 @@ import './image-preview.scss' -import { defineComponent, ref, computed, onMounted, onUnmounted } from 'vue' +import { defineComponent, Fragment, ref, computed, onMounted, onUnmounted } from 'vue' import { imagePreviewProps, ImagePreviewProps } from './image-preview-types' import ImagePreviewService from './image-preview-service' import Transform from './transform' @@ -13,6 +13,9 @@ export default defineComponent({ const index = ref(0) const url = computed(() => props.previewUrlList[index.value]) + const imageStyle = props.zIndex ? { zIndex: props.zIndex } : {} + const bgStyle = props.backDropZIndex ? { zIndex: props.backDropZIndex } : {} + function initTransform() { const imageElement: HTMLImageElement = document.querySelector( '.devui-image-preview-main-image' @@ -20,7 +23,7 @@ export default defineComponent({ transform = new Transform(imageElement) } function initIndex() { - index.value = props.previewUrlList.findIndex(curUrl => curUrl === props.url) + index.value = props.previewUrlList.findIndex((curUrl) => curUrl === props.url) } function onPrev() { index.value = index.value <= 0 ? props.previewUrlList.length - 1 : index.value - 1 @@ -47,15 +50,15 @@ export default defineComponent({ transform.setZoomOriginal() } - function onKeyDown(event:KeyboardEvent) { - if(event.defaultPrevented) return; + function onKeyDown(event: KeyboardEvent) { + if (event.defaultPrevented) return - if(event.code == 'Escape') { - onClose(); - }else if(event.code == 'ArrowLeft') { - onPrev(); - }else if(event.code == 'ArrowRight') { - onNext(); + if (event.code == 'Escape') { + onClose() + } else if (event.code == 'ArrowLeft') { + onPrev() + } else if (event.code == 'ArrowRight') { + onNext() } } function initKeyboard() { @@ -70,122 +73,125 @@ export default defineComponent({ initTransform() initKeyboard() }) - onUnmounted(()=>{ - unKeyBoard(); - }) + onUnmounted(() => { + unKeyBoard() + }) return () => { return ( -
- {/* 预览图 */} - - {/* 按钮区 */} - - - - {/* 底部固定区 */} -
- - - - - - {index.value + 1}:{props.previewUrlList.length} - - + {/* 底部固定区 */} +
+ + + + + + {index.value + 1}:{props.previewUrlList.length} + + + + +
-
+
+ ) } } diff --git a/packages/devui-vue/docs/components/image-preview/index.md b/packages/devui-vue/docs/components/image-preview/index.md index 25ebc6a27049af2a5185fe823a83e3f6cb675e4f..c16c4fc094556d0c18a10c249de50794bedb8a80 100644 --- a/packages/devui-vue/docs/components/image-preview/index.md +++ b/packages/devui-vue/docs/components/image-preview/index.md @@ -9,6 +9,7 @@ ### 基本用法 :::demo 使用 v-d-image-preview 指令,对容器内图片进行预览。 + ```vue - - +}) + ``` + ::: ### 自定义开启预览窗口 :::demo 传入 custom 参数,指令会自动注入 open 方法,通过 custom.open 开启预览窗口 + ```vue - - +}) + ``` + ::: ### 设置 zIndex -通过设置 zIndex 控制弹出效果的层级,设置 backDropZIndex 控制弹出层背景的层级。 -可以看到当设置 zIndex 小于 backDropZIndex 时,imagePreview 会显示在背景下方。 -可以通过 Esc 关闭 imagePreview。 +:::demo 通过设置 zIndex 控制弹出效果的层级,设置 backDropZIndex 控制弹出层背景的层级。可以看到当设置 zIndex 小于 backDropZIndex 时,imagePreview 会显示在背景下方。可以通过 Esc 关闭 imagePreview。 -``` -// 待嵌入 modal 组件即可 +```vue + + ``` +::: ### API @@ -120,4 +139,23 @@ | zIndex | `Number` | 1050 | 可选,可选,设置预览时图片的 z-index 值 | | backDropZIndex | `Number` | 1040 | 可选,设置预览时图片背景的 z-index 值 | - +