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" style="max-width: 100%" /> </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指令的文章就介绍到这了,更多相关vue3 v-preview指令内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验
vee-validate 是为 Vue.js 量身打造的表单校验框架,允许您校验输入的内容并显示对应的错误提示信息。这篇文章给大家带来了Vue.js 使用 Vee-validate 实现表单校验的相关知识,感兴趣的朋友一起看看吧2019-04-04如何正确解决VuePress本地访问出现资源报错404的问题
这篇文章主要介绍了如何正确解决VuePress本地访问出现资源报错404的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-12-12在导入.vue文件的时候,ts报错提示:找不到模块“@/Layout/index.vue”或其相应的类型声明问题
这篇文章主要介绍了在导入.vue文件的时候,ts报错提示:找不到模块“@/Layout/index.vue”或其相应的类型声明问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-08-08
最新评论