vue3+ts+elementPLus实现v-preview指令的方法

本篇文章和大家了解一下vue3+ts+elementPLus实现v-preview指令的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

引文

最近在用 vue3+ts 开发公司的后台系统,因为后台多处需要图片放大预览的功能,就想着封装一个v-preview指令,这样在需要预览的图片上加个 v-preview就可以预览啦。

目录

在这里就不列我的项目目录啦,想尝试的朋友可以这样创建目录

-- preview
---- previewImage.vue
---- preview.ts

文件内容

previewImage.vue

普普通通vue3组件,记得全局注册

<template>
    <div class="previewImg" @click="dialogVisible = true">
        <slot>
            <img :src="props.src" alt="图片加载失败" />
        </slot>
    </div>
    <el-dialog v-model="dialogVisible" title="查看图片" @close="close">
        <img :src="imgSrc" alt="Preview Image"  />
    </el-dialog>
</template>
<script setup lang="ts">
    import { ref, getCurrentInstance, ComponentInternalInstance, onMounted } from 'vue'
    import { ElDialog } from 'element-plus'
    const props = defineProps({
        src: String
    })
    const dialogVisible = ref(false)
    const imgSrc = ref('')
    // 插槽形式
    onMounted(() => {
        const { proxy } = getCurrentInstance() as ComponentInternalInstance
        let slot = proxy?.$slots?.default?.()
        if(slot){
            // 获取插槽内容设置imgSrc地址
            imgSrc.value = slot?.[0]?.props?.src
        }
    })
    const setSrc = (v: string) => {
        imgSrc.value = v
    }
    // 组件触发
    if (props.src) {
        setSrc(props.src)
    }
    // 指令触发
    const show = () => {
        dialogVisible.value = true
    }
    const close = () => { 
        // 弹窗关闭移除dom
        if (document.getElementById('previewDom')) {
            document.body.removeChild(document.getElementById('previewDom') as HTMLElement)
        }
    }
    defineExpose({
        show,
        setSrc
    })
</script>

preview.ts

对previewImage组件进行拓展,全局注册preview指令(这个注册代码就不放了呦)
需要注意的是vue3拓展组件和vue2有所不同,vue2用Vue.extend就可以拿到组件构造器,vue3这边则是使用createApp

import { Component, createApp } from 'vue'
import PreviewImageVue from '@/components/PreviewImage.vue'
function mountComponent(RootComponent: Component) {
    const app = createApp(RootComponent)
    const root = document.createElement('div')
    root.setAttribute('id', 'previewDom')
    document.body.appendChild(root)
    return {
        instance: app.mount(root),
        unmount() { // 这里unmout没用到,因为组件中dialog的close事件这里监听不到,我就在组件内进行卸载了
            console.log('unmount')
            document.body.removeChild(root)
        }
    }
}
const preview = {
    mounted(el: any) {
        el.style.cursor = 'zoom-in'
        el.addEventListener('click', () => {
            let imgSrc = el.getAttribute('src')
            let { instance, unmount } = mountComponent(PreviewImageVue)
            ;(instance as any).setSrc(imgSrc)
            ;(instance as any).show()
        })
    }
}
export default preview

使用

本地资源测试

<div class="imgs">
    <!-- 普通图片 -->
    <img src="~@/assets/images/logo.png" alt="">
    <!-- 组件形式使用预览组件、需要注意路径(使用绝对路径) -->
    <PreviewImage src="/src/assets/images/logo.png"></PreviewImage>
    <!-- 组件插槽形式预览组件、需要注意路径(使用绝对路径) -->
    <PreviewImage>
        <img src="/src/assets/images/logo.png" alt="">
    </PreviewImage>
    <!-- 指令使用预览组件 -->
    <img src="~@/assets/images/logo.png" alt="" v-preview>
</div>

开发中可能遇到的问题

  • 获取proxy时使用getCurrentInstance时编辑器会报错,断言成ComponentInternalInstance就不报错了。

  • 获取插槽内容时需要 proxy?.$slots?.default?.() 这样判断取值,不然编辑器也会报错。

  • 暴露给外部使用的方法/属性需通过defineExpose暴露出去

  • 注意拓展组件方式。vue2用Vue.extend,vue3用createApp

  • 使用的时候注意路径问题

总结

之前都是用vue2开发项目,此次项目是vue3的第一次实践,使用下来感觉ts写起来比较冗余,很多编辑器报错都需要时间去解决,可能不是开发组件库都是业务需求,对类型接口的定义使用很少。个人不是很喜欢ts,还是js来的简单粗暴。

以上就是vue3+ts+elementPLus实现v-preview指令的方法的简略介绍,当然详细使用上面的不同还得要大家自己使用过才领会。如果想了解更多,欢迎关注编程之家行业资讯频道哦!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在PHP中进行字符串拼接时,应注意以下几点: 使用 .“运算符进行字符串拼接:在PHP中,可以使用”. 运算符来连接两个字符串。 使用双引号或单引号来包裹字符...
在Python中,全局变量可以在程序的任何地方进行定义,通常在函数外部进行定义。全局变量可以在整个程序中访问,而不仅仅是在函数内部。要定义一个全局变量,只
今天小编给大家分享一下电脑显示器上auto指的是什么意思的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考
本文小编为大家详细介绍“ai建立剪切蒙版后如何移动里面的图片”,内容详细,步骤清晰,细节处理妥当,希望这篇“ai建立剪切蒙版后如何移动里面的图片”文章能帮...
这篇文章主要讲解了“windows中格式化d盘的后果是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“wind...
这篇“otf文件有哪些特点”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章...
这篇文章主要介绍“wpsystem文件夹有什么作用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“wpsystem文件夹有什
这篇文章主要介绍了ps单位指的是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ps单位指的是什么文章都会有所收获,下面我...
这篇文章主要介绍“ipv6对网速有没有提升”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“ipv6对网速有没有提升”文...
本文小编为大家详细介绍“islide是什么及有什么作用”,内容详细,步骤清晰,细节处理妥当,希望这篇“islide是什么及有什么作用”文章能帮助大家解决疑惑,下面...
本篇内容主要讲解“UAC被禁用有哪些影响”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“UAC被禁用有哪些影响”...
今天小编给大家分享一下svchost.exe可不可以关掉的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,
这篇文章主要介绍“win10有没有32位版本”,在日常操作中,相信很多人在win10有没有32位版本问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,
这篇文章主要介绍了vlookup如何引用别的表格数据的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vlookup如何引用别的表格数据文...
本文小编为大家详细介绍“.json文件有什么作用”,内容详细,步骤清晰,细节处理妥当,希望这篇“.json文件有什么作用”文章能帮助大家解决疑惑,下面跟着小编的...
这篇文章主要介绍了vlookup函数的参数是什么意思的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vlookup函数的参数是什么意思文...
本篇内容介绍了“wmiprvse.exe程序有什么作用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情...
这篇“Windows wifi的ip地址指的是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅...
今天小编给大家分享一下video接口指的是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大...
本篇内容介绍了“路由器wps有哪些优缺点”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...