专栏名称: 程序员大咖
程序员大咖,努力成就期待着的自己。分享程序员技术文章、程序员工具资源、程序员精选课程、程序员视频教程、程序员热点资讯、程序员学习资料等。
目录
相关文章推荐
你的Sneaker  ·  全国多地发售!Nike Kobe 6 ... ·  11 小时前  
你的Sneaker  ·  全国多地发售!Nike Kobe 6 ... ·  11 小时前  
正观新闻  ·  喜茶:拒绝门店规模内卷,将暂停加盟 ·  2 天前  
江西公安  ·  最高补贴15000元! ·  2 天前  
江西公安  ·  最高补贴15000元! ·  2 天前  
上海经信委  ·  “开发者,找找找” | ... ·  3 天前  
上海经信委  ·  “开发者,找找找” | ... ·  3 天前  
北京青年报  ·  DeepSeek横空出世,因为中国做对了这件事 ·  3 天前  
北京青年报  ·  DeepSeek横空出世,因为中国做对了这件事 ·  3 天前  
51好读  ›  专栏  ›  程序员大咖

使用 Vue3 指令封装一个后台管理系统图片预览功能

程序员大咖  · 公众号  · 科技自媒体 互联网短视频  · 2024-11-07 10:24

主要观点总结

本文介绍了一个Vue3项目中自定义图片预览指令的实现过程。文章首先概述了项目背景和使用的UI框架Element-plus。接着详细描述了如何借鉴el-image组件的代码,通过复习Vue3指令的写法来创建自定义指令。文章包括创建指令的步骤,如导入相关函数和类型、编写基本指令代码、创建div包裹预览组件、控制div的显示隐藏等。最后,文章展示了如何编写指令内部代码,包括绑定点击事件、渲染组件、将vnode渲染到创建的div中,以及移除创建的div等步骤。整体而言,文章介绍了一种自定义图片预览指令的完整实现过程。

关键观点总结

关键观点1: 项目背景

Vue3项目中使用Element-plus框架,需要实现图片预览功能。

关键观点2: 自定义指令的创建

通过复习Vue3指令的写法,借鉴el-image组件的代码,创建自定义的图片预览指令。

关键观点3: 创建div包裹预览组件

为了控制预览组件的显示和隐藏,创建一个div并给它添加类名。

关键观点4: 编写指令内部代码

包括绑定点击事件、渲染组件、将vnode渲染到创建的div中,以及移除创建的div等步骤。

关键观点5: 导入和使用自定义指令

将自定义指令的文件导入到main.ts中,并在项目中调用使用。


正文

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

复习vue3指令的写法

官方指令文档:https://cn.vuejs.org/guide/reusability/custom-directives.html#custom-directives

简单的例子

<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], // 图片地址
    hideOnClickModaltrue// 允许点击遮罩层关闭
   });
  },
 });
}
  • 第三步 使用 render 函数将 vnode 渲染到我们创建的div 里面,并且将我们创建的 div 插入到 body 里面
export






请到「今天看啥」查看全文