vue3 的插件开发和vue2思路类似但是写法却迥异。主要变化在vue3没有了extend构造器。

这次我们通过一个图片预览插件,贯通整个vue3插件开发的过程。

1 在src下新建lplugins文件夹,在此文件夹下新建两个文件prevImg.vue和index.js

<template><div class="viewer" v-if="isShow"><divclass="mask"@click="close"></div><div class="actions"><iclass="el-icon-zoom-in fs24"@click="operate('zoomIn')">-</i><i  @click="operate('zoomOut')" class="fs24">+</i>        <i class="el-icon-c-scale-to-original fs14"@click="toggleMode">[]</i><i class="el-icon-refresh-left fs24"@click="operate('rotateDY')">☽</i><iclass="el-icon-refresh-right fs14"@click="operate('rotateY')"></i><iclass="el-icon-circle-close fs14"@click="operate('close')"></i></div><div class="img-wrap"><imgref="img":style="imgStyle"class="viewer__img":src="imgUrl"/></div></div>
</template><script setup>
import { computed, ref ,nextTick, getCurrentInstance, watch, reactive, onMounted,toRefs} from 'vue'const Mode = {CONTAIN: {name: 'contain',icon: 'el-icon-full-screen'},ORIGINAL: {name: 'original',icon: 'el-icon-c-scale-to-original'}};//stateconst loading=ref(false)const isShow=ref(false)const transform=reactive({scale: 1,deg: 0,offsetX: 0,offsetY: 0,enableTransition: false})const mode=ref(Mode.CONTAIN)const instance=getCurrentInstance()const imgUrl=ref("")const emits=defineEmits(["close","open"])const imgStyle=computed(()=> {const { scale, deg, offsetX, offsetY, enableTransition } = transform;const style = {transform: `scale(${scale}) rotate(${deg}deg)`,transition: enableTransition ? 'transform .3s' : '','margin-left': `${offsetX}px`,'margin-top': `${offsetY}px`,};if (mode.value === Mode.CONTAIN) {style.maxWidth = style.maxHeight = '100%';}return style;})const  handleImgLoad=(e)=>{loading.value = false;}const handleImgError=(e)=>{loading.value = false;console.log("e.target",e.target)e.target.alt = '加载失败';}const open=(data)=>{console.log("组件内---data",data)debuggerisShow.value=true;imgUrl.value=data.url}const close=()=>{console.log("close")isShow.value=falseemits("close")}const operate=(action,options={})=>{ if (loading.value) return;const { zoomRate, rotateDeg, enableTransition } = {zoomRate: 0.2,rotateDeg: 90,enableTransition: true,...options};transform.enableTransition=true;switch (action) {case 'zoomOut':if (transform.scale > 0.2) {transform.scale = parseFloat((transform.scale - zoomRate).toFixed(3));}break;case 'zoomIn':transform.scale = parseFloat((transform.scale + zoomRate).toFixed(3));break;case 'rotateY':transform.deg += rotateDeg;break;case 'rotateDY':transform.deg -= rotateDeg;break;case "close":$emit("close");break;}transform.enableTransition = enableTransition;  }defineExpose({open,close,operate})</script>
<style  scoped>
.mask {position: absolute;width: 100%;height: 100%;top: 0;left: 0;opacity: 0.5;background: #000;
}
.viewer {position: fixed;top: 0;right: 0;bottom: 0;left: 0;
}.img-wrap {width: 100%;height: 100%;/* position:absolute;top:0;left:0;z-index: 100; */display: -webkit-box;display: -ms-flexbox;display: flex;-webkit-box-pack: center;-ms-flex-pack: center;justify-content: center;-webkit-box-align: center;-ms-flex-align: center;align-items: center;
}
.loading {color: #fff;
}
.actions {position: fixed;top: 16px;right: 30px;width: 220px;z-index: 9999;color: #fff;display: flex;justify-content: flex-end;}
.actions i {display: inline-block;margin-left: 10px;
}.viewer__img{max-height: 100%;
}
.fs24{font-size: 24px;
}
</style>

在这个文件中我们定义了几个比较重要的函数

open、close、operate分别用于打开图层。关闭图层和对图层进行放大。缩小。旋转等操作。这些函数我们通过defineExpose()对外暴露出去。这样在父组件我们就可以直接调用这些方法。达到穿透的效果。

2 接下里是lib下的index.js文件,它是整个插件的核心

import {  createVNode, render, } from 'vue';
import preview from './preview.vue'export default {install(app,options) {console.log("options;",options={})//createVNode vue提供的底层方法 可以给我们组件创建一个虚拟DOM 也就是Vnodeconst vnode = createVNode(preview)//render 把我们的Vnode 生成真实DOM 并且挂载到指定节点render(vnode, document.body)// Vue 提供的全局配置 可以自定义app.config.globalProperties.$preview = {open: (opts) => vnode.component?.exposed?.open(opts),close: () => vnode.component?.exposed?.close()}app.component("preview", preview)}
}

注意这里,由于vue3中没有了原型的概念。vue3给了我们一个新的api, app.config.globalProperties,我们把方法或者属性挂载到globalProperties上,就相当于在vue2中我们挂载到了vue的原型对象上。而open方法里我们传入的参数就是我们在点击预览时要传递的参数。我们这个例子把图片的url作为核心参数传递过去

3 看看在页面中如何调用

<script setup>
import {getCurrentInstance, ref} from "vue"
import Test from './components/test.vue'const {proxy}=getCurrentInstance()const imgSrc=ref("https://baj-dabanjiz-conf.oss-cn-hangzhou.aliyuncs.com/intelligent-design/image/20210730/middle/9bbeb6570f7b416b1bcbcc59a1b38635.jpg") //横图const testPlugin=()=>{console.log("proxy",proxy)let obj={url:imgSrc.value}proxy.$preview.open(obj)}</script><template><el-button @click="testPlugin"> 测试插件</el-button></template><style scoped></style>

4 这里要注意的就是我们在页面中如何获取到vue的实例。当我们点击按钮的时候,

const testPlugin=()=>{console.log("proxy",proxy)let obj={url:imgSrc.value}proxy.$preview.open(obj)
}

实际上这里我们依然可以通过这样的写法来获取我们 的open方法.如下

 const instance=getCurrentInstance()const imgSrc=ref("https://baj-dabanjiz-conf.oss-cn-hangzhou.aliyuncs.com/intelligent-design/image/20210730/middle/9bbeb6570f7b416b1bcbcc59a1b38635.jpg") //横图const testPlugin=()=>{console.log("proxy",proxy)let obj={url:imgSrc.value}instance.config.globalProperties.$preview.open(obj)}

但是每次这样会又长又臭。还好vue3在实例里有个prxoy对象。它就相当于当前组件实例的副本。在它上面我们就能获取到我们注册的$preview.

5 main.js注册插件

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// import Loading from "./libs/testLoading/loading"
import preview from "./libs/preview/preview"
createApp(App).use(ElementPlus).use(preview).mount('#app')

到这里我们就基本上实现了图片预览的基本操作

vue3 开发一个图片预览插件相关推荐

  1. 移动开发photoswipe图片预览插件使用

    页面代码如下: <div class="card-content" style="margin-left: 15px;margin-right: 15px;&quo ...

  2. dw按钮图片滚动js_使用 React Hooks 实现仿石墨的图片预览插件(巨详细)

    点击上方"前端教程",选择"星标" 每天前端开发干货第一时间送达! 作者:DARRELL https://juejin.im/post/5e9bf299f265 ...

  3. pc 图片预览放大 端vue_安利一款简单好用的Vue图片预览插件

    在项目中因为要经常用到图片预览效果,自己写的话麻烦死啦(懒) vue-photo-preview 一个基于 photoswipe 的 vue 图片预览插件,支持移动端和PC端,支持各种手势操作,放大缩 ...

  4. 移动端图片预览插件-fly-zomm-img.min.js

    移动端图片预览插件,一个JQ的插件,支持手势放大缩小:有点小bug,不过感觉是可以接受的: 插件的地址:http://www.jq22.com/jquery-info15466 那里有具体的说明,但是 ...

  5. VSCode图片预览插件 Image preview

    VSCode前端开发图片预览插件 Image preview(支持css预览 支持svg格式) 一款提高前端开发效率的插件 ,代码中hover直接预览图片 先上效果图 不仅html中可以预览 js代码 ...

  6. html页面点击图片名称查看图片------图片预览插件viewer.js使用

    前言 在做项目时,会遇到在前台展示附件详情,比如图片,word,pdf等.viewer.js 图片查看器,用来查看页面中的图片. 基本效果: Viewer.js的使用 这是一个github工程,功能很 ...

  7. React 图片预览插件 rc-viewer @hanyk/rc-viewer

    最近一个需求是图片要实现预览并且可以上下切换,react接触不是很久,查了好多资料,最终对@hanyk/rc-viewer下手,jquery用多了伙伴都知道viewer.js,一个很强大的图片预览插件 ...

  8. 实现一个vue的图片预览插件

    vue-image-swipe 基于photoswipe实现的vue图片预览组件 安装 1 第一步 npm install vue-image-swipe -D 2 第二步 vue 入口文件引入 im ...

  9. Windows系统SVG图片预览插件

    由于工作中经常需要对组图查看和管理,而Windows系统不支持在文件夹下直接预览svg图片, HBuilderX 插件市场没有找到相应的svg插件,比较麻烦.经过查找,发现svg扩展插件(SVG Vi ...

最新文章

  1. Python 爬虫之 Beautiful Soup 模块使用指南
  2. 配置两个不同kerberos认证中心的集群间的互信
  3. 初始化方法-使用参数设置属性初始值
  4. php基础教程(三):变量
  5. java弹出提示窗口_Java实现弹窗效果的基本操作(2)
  6. IDEA这样配置注释模板,让你高出一个逼格!!
  7. XOR and Favorite Number(CF-617E)
  8. Swing basic
  9. 拒绝平庸——浅谈WEB登录页面设计
  10. 在 Angular 8 中,我们可以期待些什么
  11. linux学习笔记-文件属性基本知识
  12. Linux自学之旅-安装篇(一)
  13. php被挂马,PHP网站被挂马防御战
  14. Linux下系统函数
  15. 数字媒体技术基础之三:分辨率
  16. 为什么INT_MIN不是直接写成-2147483648
  17. 2048小游戏 java版(代码+注释)
  18. java毕业设计——基于java+Socket+sqlserver的网络通信系统设计与实现(毕业论文+程序源码)——网络通信系统
  19. matlab画一维波动方程,一维波动方程的数值解
  20. 《Head First 设计模式》读书笔记——工厂模式

热门文章

  1. PMP证书含金量有多高?
  2. pytorch + AMD卡 (docker快速构建A卡pytorch环境, 5分钟不折腾版)
  3. Zabbix外部邮件告警配置mailx
  4. 一起来看看:IT热门行业那一种最适合你
  5. 公众号开发之-node响应微信token验证
  6. c语言中叹号 几个字节,排列组合里的惊叹号和A和C、P等符号都是什 – 手机爱问...
  7. 使用自定义键盘切换大小写功能失效,一直显示大写字母
  8. 小米自打脸,1亿像素无意义
  9. css6图层 解锁,javascript - 如何在Openlayers上更改WMS图层的样式(来自Javascript) - 堆栈内存溢出...
  10. LeetCode 171 Excel表列序号[进制转换] HERODING的LeetCode之路