本文主要介绍了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指令内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
本文标题为:vue3+ts+elementPLus实现v-preview指令
基础教程推荐
- 第7天:CSS入门 2022-11-04
- ExtJS 3.x DateField menuListeners 显示/隐藏 2022-09-15
- vue的 Mixins (混入) 2023-10-08
- 关于 css:WebKit (iPad) CSS3: 背景过渡闪烁 2022-09-21
- 解决ajax的delete、put方法接收不到参数的问题方法 2023-02-23
- 深入浅析Jsonp解决ajax跨域问题 2022-12-28
- Vue+WebSocket实现在线聊天 2023-10-08
- 基于bootstrap的上传插件fileinput实现ajax异步上传功能(支持多文件上传预览拖拽) 2023-02-01
- 分页技术原理与实现之无刷新的Ajax分页技术(三) 2023-01-20
- ECSHOP中实现ajax弹窗登录功能 2023-01-31