antd design vue 图片预览二次封装-组件调用到函数调用

921 阅读1分钟

antd design vue是通过template模板的html代码实现预览图片的,非常不灵活。可以通过js的api调用方式实现图片展示。使用单例设计模式,专门给图片展示添加一个函数调用。因此从组件调用改造成函数调用

1: 使用方法:

import usePreviewImg from './usePreviewImage'
  
const previewImage = usePreviewImg()

2: 调用:

previewImage.show({
   list: ['https://gw.alipayobjects.com/zos/antfincdn/cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp'],
   current: 0
})

WXWorkCapture_17303646573462.png

WXWorkCapture_17303647011699.png

实现代码:

<template>
  <div>
    <a-button type="primary" @click="() => setVisible()">show image preview</a-button>
  </div>
</template>
<script setup>
import { ref } from "vue";
import usePreviewImg from "./usePreviewImage";

const previewImage = usePreviewImg();

const fileList = ref([
  {
    visible: true,
    thumbUrl:
      "https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png",
  },
  {
    thumbUrl: "https://aliyuncdn.antdv.com/vue.png",
  },
]);
const setVisible = (value) => {
  previewImage.show({
    list: fileList.value.map((item) => item.thumbUrl),
  });
};
</script>

/*
 * @Author: Poet WangZhenhao
 * @Date: 2024-10-31 14:36:47
 * @LastEditors: Poet WangZhenhao
 * @LastEditTime: 2025-01-02 16:26:50
 * @Description: 图片预览api调用

1: 使用方法:

import usePreviewImg from './usePreviewImage'
  
const previewImage = usePreviewImg()

2: 调用:

previewImage.show({
   list: ['https://gw.alipayobjects.com/zos/antfincdn/cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp'],
   current: 0
})

show方法接收参数一个对象
list        图片url的数组        如:['xxx', 'xxx]        
current     预览第几张图片       默认:0

*/
import { ImagePreviewGroup, Image } from 'ant-design-vue';
import { createVNode, render as vueRender, cloneVNode, ref } from 'vue';
let instance = '';

function usePreviewImg() {
    if (instance) {
      return instance;
    }
    const container = document.createDocumentFragment();
    function show(config) {
        const visible = ref(true);
        config.visible = visible
        const newVm = cloneVNode(instance.vnode, config)
        vueRender(newVm, container)
    }
    const Wrapper = (attr = {}) => {
        let visible = attr.visible
        
        let current = attr.current
        const list = attr.list || []
        const onVisibleChangeHandle = () => {
            visible.value = false
        }
        return (<div style="display: none;" data-mark="image-preview">
            <ImagePreviewGroup
             preview={{
                visible: visible?.value,
                onVisibleChange: onVisibleChangeHandle,
                current: current
             }}
            >
                {
                    list.map(item => {
                        return <Image width="200" src={item} />
                    })
                }
            </ImagePreviewGroup>
          </div>)
    }
 
    function render() {
        const vm = createVNode(Wrapper);
        vueRender(vm, container)
        // document.body.appendChild(vm.el)
        // console.log(container)
        // debugger
        return vm
    }
    const vnode = render()
    
    instance = {
        show,
        vnode: vnode
    }
    return instance

}

export default usePreviewImg