Преглед изворни кода

feat: Add ImageViewer component and add ImageViewer demo

陈凯龙 пре 3 година
родитељ
комит
af9fc0a4ad

+ 1 - 0
src/components/Dialog/src/Dialog.vue

@@ -63,6 +63,7 @@ const dialogStyle = computed(() => {
     :fullscreen="isFullscreen"
     destroy-on-close
     lock-scroll
+    draggable
     :close-on-click-modal="false"
   >
     <template #title>

+ 33 - 0
src/components/ImageViewer/index.ts

@@ -0,0 +1,33 @@
+import ImageViewer from './src/ImageViewer.vue'
+import { isClient } from '@/utils/is'
+import { createVNode, render, VNode } from 'vue'
+import { ImageViewerProps } from './src/types'
+
+let instance: Nullable<VNode> = null
+
+export function createImageViewer(options: ImageViewerProps) {
+  if (!isClient) return
+  const {
+    urlList,
+    initialIndex = 0,
+    infinite = true,
+    hideOnClickModal = false,
+    appendToBody = false,
+    zIndex = 2000,
+    show = true
+  } = options
+
+  const propsData: Partial<ImageViewerProps> = {}
+  const container = document.createElement('div')
+  propsData.urlList = urlList
+  propsData.initialIndex = initialIndex
+  propsData.infinite = infinite
+  propsData.hideOnClickModal = hideOnClickModal
+  propsData.appendToBody = appendToBody
+  propsData.zIndex = zIndex
+  propsData.show = show
+
+  document.body.appendChild(container)
+  instance = createVNode(ImageViewer, propsData)
+  render(instance, container)
+}

+ 23 - 0
src/components/ImageViewer/src/ImageViewer.vue

@@ -0,0 +1,23 @@
+<script setup lang="ts">
+import { ElImageViewer } from 'element-plus'
+import { computed, ref } from 'vue'
+import { imageViewerProps } from './props'
+
+const props = defineProps(imageViewerProps)
+
+const getBindValue = computed(() => {
+  const propsData: Recordable = { ...props }
+  delete propsData.show
+  return propsData
+})
+
+const show = ref(props.show)
+
+const close = () => {
+  show.value = false
+}
+</script>
+
+<template>
+  <ElImageViewer v-if="show" v-bind="getBindValue" @close="close" />
+</template>

+ 32 - 0
src/components/ImageViewer/src/props.ts

@@ -0,0 +1,32 @@
+import { PropType } from 'vue'
+
+export const imageViewerProps = {
+  urlList: {
+    type: Array as PropType<string[]>,
+    default: (): string[] => []
+  },
+  zIndex: {
+    type: Number as PropType<number>,
+    default: 2000
+  },
+  initialIndex: {
+    type: Number as PropType<number>,
+    default: 0
+  },
+  infinite: {
+    type: Boolean as PropType<boolean>,
+    default: true
+  },
+  hideOnClickModal: {
+    type: Boolean as PropType<boolean>,
+    default: false
+  },
+  appendToBody: {
+    type: Boolean as PropType<boolean>,
+    default: false
+  },
+  show: {
+    type: Boolean as PropType<boolean>,
+    default: false
+  }
+}

+ 9 - 0
src/components/ImageViewer/src/types.ts

@@ -0,0 +1,9 @@
+export interface ImageViewerProps {
+  urlList?: string[]
+  zIndex?: number
+  initialIndex?: number
+  infinite?: boolean
+  hideOnClickModal?: boolean
+  appendToBody?: boolean
+  show?: boolean
+}

+ 7 - 1
src/locales/en.ts

@@ -105,7 +105,8 @@ export default {
     defaultTable: 'Basic example',
     editor: 'Editor',
     richText: 'Rich text',
-    dialog: 'Dialog'
+    dialog: 'Dialog',
+    imageViewer: 'Image viewer'
   },
   analysis: {
     newUser: 'New user',
@@ -343,5 +344,10 @@ export default {
     dialogDes: 'Secondary packaging of Dialog components based on ElementPlus',
     open: 'Open',
     close: 'Close'
+  },
+  imageViewerDemo: {
+    open: 'Open',
+    imageViewer: 'Image viewer',
+    imageViewerDes: 'Secondary packaging of ImageViewer components based on ElementPlus'
   }
 }

+ 7 - 1
src/locales/zh-CN.ts

@@ -105,7 +105,8 @@ export default {
     defaultTable: '基础示例',
     editor: '编辑器',
     richText: '富文本',
-    dialog: '弹窗'
+    dialog: '弹窗',
+    imageViewer: '图片预览'
   },
   analysis: {
     newUser: '新增用户',
@@ -340,5 +341,10 @@ export default {
     dialogDes: '基于 ElementPlus 的 Dialog 组件二次封装',
     open: '打开',
     close: '关闭'
+  },
+  imageViewerDemo: {
+    open: '打开',
+    imageViewer: '图片预览',
+    imageViewerDes: '基于 ElementPlus 的 ImageViewer 组件二次封装'
   }
 }

+ 8 - 0
src/router/index.ts

@@ -193,6 +193,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
           title: t('router.search')
         }
       },
+      {
+        path: 'image-viewer',
+        component: () => import('@/views/Components/ImageViewer.vue'),
+        name: 'ImageViewer',
+        meta: {
+          title: t('router.imageViewer')
+        }
+      },
       {
         path: 'dialog',
         component: () => import('@/views/Components/Dialog.vue'),

+ 30 - 0
src/views/Components/ImageViewer.vue

@@ -0,0 +1,30 @@
+<script setup lang="ts">
+import { ContentWrap } from '@/components/ContentWrap'
+import { createImageViewer } from '@/components/ImageViewer'
+import { ElButton } from 'element-plus'
+import { useI18n } from '@/hooks/web/useI18n'
+
+const { t } = useI18n()
+
+const open = () => {
+  createImageViewer({
+    urlList: [
+      'https://img1.baidu.com/it/u=657828739,1486746195&fm=26&fmt=auto&gp=0.jpg',
+      'https://img0.baidu.com/it/u=3114228356,677481409&fm=26&fmt=auto&gp=0.jpg',
+      'https://img1.baidu.com/it/u=508846955,3814747122&fm=26&fmt=auto&gp=0.jpg',
+      'https://img1.baidu.com/it/u=3536647690,3616605490&fm=26&fmt=auto&gp=0.jpg',
+      'https://img1.baidu.com/it/u=4087287201,1148061266&fm=26&fmt=auto&gp=0.jpg',
+      'https://img2.baidu.com/it/u=3429163260,2974496379&fm=26&fmt=auto&gp=0.jpg'
+    ]
+  })
+}
+</script>
+
+<template>
+  <ContentWrap
+    :title="t('imageViewerDemo.imageViewer')"
+    :message="t('imageViewerDemo.imageViewerDes')"
+  >
+    <ElButton type="primary" @click="open">{{ t('imageViewerDemo.open') }}</ElButton>
+  </ContentWrap>
+</template>