使用vue3指令封装一个图片预览功能

 更新时间:2024年01月18日 15:36:35   作者:前端Ah  
这篇文章主要为大家详细介绍了如何使用 vue3 指令封装一个后台管理系统图片预览功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

最近公司搭建了一个新的 vue3 项目,因为项目中有很多模块用到了图片预览功能,项目的 ui 框架用的是element-plus,框架自带 el-image 组件里面带了图片预览功能,但是当时我不想用这个组件,所以就借鉴了它里面预览图片组件的代码。

复习vue3指令的写法

官方指令文档

简单的例子

<div v-color="red"> 我是红色的文字</div>
app.directive('color', (el, binding) => {
  // 这会在 `mounted` 和 `updated` 时都调用
  el.style.color = binding.value
})

这时候 div 里面的文字都变成红色, v-color="yellow" 就变成了黄色

相关参数介绍

  • el:指令绑定到的元素。这可以用于直接操作 DOM。
  • binding:一个对象,包含以下属性。
  • value:传递给指令的值。例如在 v-my-directive="1 + 1" 中,值是 2
  • oldValue:之前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否更改,它都可用。
  • arg:传递给指令的参数 (如果有的话)。例如在 v-my-directive:foo 中,参数是 "foo"
  • modifiers:一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }
  • instance:使用该指令的组件实例。
  • dir:指令的定义对象。
  • vnode:代表绑定元素的底层 VNode。
  • prevNode:代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。

新建 previewImageDirective.ts 文件

导入相关函数及类型,编写基本的指令代码

import { DirectiveBinding, h, render } from 'vue';
import { ElImageViewer } from 'element-plus';

export default function (app) {
	app.directive('previewImage', {
		mounted(el: HTMLElement, binding: DirectiveBinding) {
			// 逻辑操作
		},
	});
}
  • DirectiveBinding el的类型
  • h 将组件代码转成 vnode
  • render 将 vnode 渲染成 html

下面开始编写相关指令代码

首先我们需要创建一个 div 用来包裹我们的预览组件,我们来控制这个 div 的显示隐藏来实现预览组件的弹出和隐藏。

为什么这几个变量为啥要定义成全局的,如果写在指令内部 v-previewImage="" 多次 就出现多个变量,和多个组件,造成了资源浪费,然后ElImageViewer组件一个页面要写多次还会出现一个错误

我给 element 提了issues,现在已经修复,但还是推荐我这种写法

const previewBox = document.createElement('div'); // 创建节点
previewBox.classList.add('preview-box'); // 给 div 增加类名
let vnode; // 存放 vnode 的变量

编写指令内部代码

第一步给图片绑定点击事件并给图片添加样式,当鼠标滑过添加小手的样式

export default function (app) {
	app.directive('previewImage', {
		mounted(el: HTMLElement, binding: DirectiveBinding) {
			el.addEventListener('click', () => {
                            el.style.cursor = 'pointer';
                        })
		},
	});
}

第二步 使用 h 函数 渲染组件 将组件代码转成 vnode

export default function (app) {
	app.directive('previewImage', {
		mounted(el: HTMLElement, binding: DirectiveBinding) {
			el.addEventListener('click', () => {
                            el.style.cursor = 'pointer';
                        })
                        vnode = h(ElImageViewer, {
				urlList: [binding.value], // 图片地址
				hideOnClickModal: true, // 允许点击遮罩层关闭
			});
		},
	});
}

第三步 使用 render 函数将 vnode 渲染到我们创建的div 里面,并且将我们创建的 div 插入到 body 里面

export default function (app) {
	app.directive('previewImage', {
		mounted(el: HTMLElement, binding: DirectiveBinding) {
			el.addEventListener('click', () => {
                            el.style.cursor = 'pointer';
                        })
                        vnode = h(ElImageViewer, {
				urlList: [binding.value], // 图片地址
				hideOnClickModal: true, // 允许点击遮罩层关闭
			});
                        render(vnode, previewBox); // 将 vnode 渲染成 html
                        document.body.appendChild(previewBox); // 将 html 插入到 body 标签里面
		},
	});
}

到现在为止我们点击图片组件已经可以正常的显示了

第四步当点击遮罩层关闭的时候将我们创建的 div 移除掉就 ok 了

export default function (app) {
	app.directive('previewImage', {
		mounted(el: HTMLElement, binding: DirectiveBinding) {
			el.addEventListener('click', () => {
                            el.style.cursor = 'pointer';
                        })
                        vnode = h(ElImageViewer, {
				urlList: [binding.value], // 图片地址
				hideOnClickModal: true, // 允许点击遮罩层关闭
                                onClose: () => {
                                         el.removeEventListener('click', () => {}); // 移除
                                         document.body.removeChild(previewBox);
					},
			});
                        render(vnode, previewBox); // 将 vnode 渲染成 html
                        document.body.appendChild(previewBox); // 将 html 插入到 body 标签里面
		},
	});
}

将文件导入到 main.ts中

将文件导入 main.ts中然后调用我们导入的方法传入 app 就可以在页面中使用了

import imageDirective from 'xxxx/previewImageDirective';
const app = createApp(App);
imageDirective(app)

ok 上面就是完整代码,这样一个图片预览指令就完成了

以上就是使用vue3指令封装一个图片预览功能的详细内容,更多关于vue3图片预览的资料请关注脚本之家其它相关文章!

相关文章

  • Vue中computed与methods的区别详解

    Vue中computed与methods的区别详解

    这篇文章主要介绍了Vue中computed与methods的区别详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • Vite代理如何解决跨域问题详解

    Vite代理如何解决跨域问题详解

    跨域是指浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制,下面这篇文章主要给大家介绍了关于Vite代理如何解决跨域问题的相关资料,需要的朋友可以参考下
    2023-03-03
  • 详解基于Vue,Nginx的前后端不分离部署教程

    详解基于Vue,Nginx的前后端不分离部署教程

    这篇文章主要介绍了详解基于Vue,Nginx的前后端不分离部署教程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • 使用vscode 开发uniapp的方法

    使用vscode 开发uniapp的方法

    本文给大家分享我使用vscode开发的一些配置。其中包括uniapp组件语法提示,uniapp代码提示,代码自动格式化问题,对vscode 开发uniapp的相关知识感兴趣的朋友一起看看吧
    2021-08-08
  • vue webpack重写cookie路径的方法

    vue webpack重写cookie路径的方法

    webpack提供的反向代理服务器在开发阶段非常方便,几行简单的代码配置就可以使用反向代理功能,包括路径重写、cookie处理等。这篇文章主要介绍了vue webpack重写cookie路径,需要的朋友可以参考下
    2019-07-07
  • 详解Vue内部怎样处理props选项的多种写法

    详解Vue内部怎样处理props选项的多种写法

    这篇文章主要介绍了详解Vue内部怎样处理props选项的多种写法,详细的介绍了props的使用的写法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • elementui简易介绍(推荐)

    elementui简易介绍(推荐)

    ElementUI是一套基于VUE2.0的桌面端组件库,ElementUI提供了丰富的组件帮助开发人员快速构建功能强大、风格统一的页面,本文给大家分享elementui简易介绍,感兴趣的朋友一起看看吧
    2024-01-01
  • vue.js动态数据绑定学习笔记

    vue.js动态数据绑定学习笔记

    这篇文章主要为大家详细介绍了vue.js动态数据绑定学习笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • vue+elementUI实现分页效果

    vue+elementUI实现分页效果

    这篇文章主要为大家详细介绍了vue+elementUI实现分页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • element-ui中的clickoutside点击空白隐藏元素

    element-ui中的clickoutside点击空白隐藏元素

    这篇文章主要为大家介绍了element-ui中的clickoutside点击空白隐藏元素示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03

最新评论