vue2图片预览插件

article/2025/8/24 9:01:52

文章目录

    • 学习链接
    • 准备工作
      • 准备图片与基础的样式
      • PrevImg.vue
      • App.vue
      • 静态效果
    • 封装插件
      • 修改PrevImg.vue
      • 定义插件逻辑
      • main.js中应用此插件
      • App.vue中使用此插件
    • 图片预览列表
      • 修改App.vue
      • 修改插件逻辑
      • 修改PrevImg.vue

学习链接

vue插件开发实例-图片预览插件
vue2-pre-img-plugin的gitee代码

准备工作

准备图片与基础的样式

  • 将iconfont下载的字体图标资源放在src/assets/iconfont目录下
  • 将准备预览的图片放到src/static/images目录下

PrevImg.vue

在plugins/PrevImg目录下,创建PrevImg.vue。

直接引入静态图片资源,然后作为vue组件实例的data

<template><div class="prev-container"><div class="mask"></div><div class="indicator"><i class="iconfont icon-jiahao1"></i><i class="iconfont icon-jian"></i><i class="iconfont icon-reset"></i><i class="iconfont icon-close"></i></div><div class="img-wrapper"><img :src="imgPath"></div></div>
</template><script>
import img1 from '@/static/images/1.jpg'
import img2 from '@/static/images/2.jpg'
import img3 from '@/static/images/3.jpg'
import img4 from '@/static/images/4.png'
import img5 from '@/static/images/5.png'console.log('PrevImg->img1',img1); // PrevImg->img1 /img/1.1a1b49d1.jpgexport default {name: 'PrevImg2',data() {return {imgPath: img1}},
}
</script><style lang="scss">.prev-container {position: fixed;top:0;left: 0;width: 100%;height: 100%;.mask {position: absolute;background-color: rgba(0,0,0,.3);width: 100%;height: 100%;z-index: -1;}.indicator {display: flex;justify-content: flex-end;padding: 20px;z-index: 100;i {padding: 10px;background-color: rgba(255,255,255,.3);border-radius: 50%;margin: 0 5px;cursor: pointer;}}.img-wrapper {position: absolute;top: 0;width: 100%;height: 100%;z-index: -1;display: flex;align-items: center;justify-content: center;img {max-height: 100%;max-width: 80%;transition: all 0.5s;}}}
</style>

App.vue

App.vue中使用改组件

<template><div id="app"><prev-img/></div>
</template><script>import PrevImg from '@/plugins/prevImg/PrevImg'export default {name: 'App',components: {PrevImg}
}
</script><style>
* {margin: 0;
}body {display: flex;flex-direction: column;
}.btn-box {text-align: center;margin-top: 20px;
}
</style>

静态效果

在这里插入图片描述

封装插件

修改PrevImg.vue

为按钮绑定相关的方法,图片的路径,将由外部传递过来

<template><div class="prev-container" v-show="isShow"><div class="mask"></div><div class="indicator"><i @click="operate('zoomIn')" class="iconfont icon-jiahao1"></i><i @click="operate('zoomOut')" class="iconfont icon-jian"></i><i @click="operate('rotate')" class="iconfont icon-reset"></i><i @click="close" class="iconfont icon-close"></i></div><div class="img-wrapper"><img :src="imgPath" :style="imgStyle" alt=""></div></div>
</template><script>export default {name: 'PrevImg',components: {},data() {return {isShow: false,imgPath: '',transform: {rotate: 0,scale: 1}}},computed:{imgStyle() {let {rotate, scale} = this.transformreturn {transform: `scale(${scale}) rotate(${rotate}deg)`}}},methods: {open({url}) {this.isShow = truethis.imgPath = url},close() {console.log('object');this.isShow = false},operate(command) {if(command == 'zoomIn') {this.transform.scale += 0.04} else if(command == 'zoomOut') {this.transform.scale -= 0.04} else if(command == 'rotate') {this.transform.rotate += 90} }}
}
</script><style lang="scss">.prev-container {position: fixed;top:0;left: 0;width: 100%;height: 100%;.mask {position: absolute;background-color: rgba(0,0,0,.3);width: 100%;height: 100%;z-index: -1;}.indicator {display: flex;justify-content: flex-end;padding: 20px;z-index: 100;i {padding: 10px;background-color: rgba(255,255,255,.3);border-radius: 50%;margin: 0 5px;cursor: pointer;}}.img-wrapper {position: absolute;top: 0;width: 100%;height: 100%;z-index: -1;display: flex;align-items: center;justify-content: center;img {max-height: 100%;max-width: 80%;transition: all 0.5s;}}}
</style>

定义插件逻辑

import PrevImg from '@/plugins/prevImg/PrevImg'export default {install(Vue, options) {let PrevImgConstructor = Vue.extend(PrevImg)let instance = new PrevImgConstructor()/* 这里会打印dom */console.log('instance', instance.$mount().$el);// instance <div class="prev-container" style="display: none;">...</div>/* 把组件转换成了dom,插入到了body中  */document.body.appendChild(instance.$mount().$el) let opts = {open(url) {// 调用组件实例上定义的方法instance.open({url})},close() {instance.close()}}// 挂载到vue组件实例上Vue.prototype.$prevImg = opts}
}

main.js中应用此插件

import Vue from 'vue'
import App from './App.vue'import '@/assets/iconfont/iconfont.css'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';import prevImg from './plugins/prevImg';Vue.config.productionTip = falseVue.use(ElementUI)
Vue.use(prevImg)new Vue({render: h => h(App),
}).$mount('#app')

App.vue中使用此插件

<template><div id="app"><div class="btn-box"><el-button @click="preview">打开预览</el-button></div></div>
</template><script>
import img1 from '@/static/images/1.jpg'
import img2 from '@/static/images/2.jpg'
import img3 from '@/static/images/3.jpg'
import img4 from '@/static/images/4.png'
import img5 from '@/static/images/5.png'export default {name: 'App',components: {},methods: {preview() {// 原本测试的是把PrevImg.vue组件给引进来, 直接调用子组件的方法使用, 但// 是没想到插件还能这么玩的, 感觉那种方式会更好// this.$refs.prevImgRef.open()this.$prevImg.open(img4)}}
}
</script><style>
* {margin: 0;
}body {display: flex;flex-direction: column;
}.btn-box {text-align: center;margin-top: 20px;
}
</style>

在这里插入图片描述

图片预览列表

在这里插入图片描述

修改App.vue

<template><div id="app"><div class="btn-box"><el-button @click="preview">打开预览</el-button></div></div>
</template><script>
import img1 from '@/static/images/1.jpg'
import img2 from '@/static/images/2.jpg'
import img3 from '@/static/images/3.jpg'
import img4 from '@/static/images/4.png'export default {name: 'App',components: {},methods: {preview() {// this.$refs.prevImgRef.open()this.$prevImg.open(0,[img1,img2,img3,img4])}}
}
</script><style>
* {margin: 0;
}body {display: flex;flex-direction: column;
}.btn-box {text-align: center;margin-top: 20px;
}
</style>

修改插件逻辑

import PrevImg from '@/plugins/prevImg/PrevImg'
export default {install(Vue, options) {let PrevImgConstructor = Vue.extend(PrevImg)let instance = new PrevImgConstructor()/* 这里会打印dom */console.log('instance', instance.$mount().$el);// instance <div class="prev-container" style="display: none;">...</div>/* 把组件转换成了dom,插入到了body中  */document.body.appendChild(instance.$mount().$el) let opts = {open(imgIdx,imgPaths) {instance.open({imgIdx,imgPaths})},close() {instance.close()}}Vue.prototype.$prevImg = opts}
}

修改PrevImg.vue

<template><div class="prev-container" v-show="isShow"><div class="mask"></div><div class="indicator"><i @click="operate('zoomIn')" class="iconfont icon-jiahao1"></i><i @click="operate('zoomOut')" class="iconfont icon-jian"></i><i @click="operate('rotate')" class="iconfont icon-reset"></i><i @click="close" class="iconfont icon-close"></i></div><div :class="['prev-next', 'left', { 'pointer-allowd': isPrev }]" @click="operate('left')"><i class="iconfont icon-houtuishangyige"></i></div><div :class="['prev-next', 'right', { 'pointer-allowd': isNext }]" @click="operate('right')"><i class="iconfont icon-qianjinxiayige"></i></div><div ref="imgWrapper" :class="['img-wrapper']"><img :src="imgPaths[imgIdx]" :style="imgStyle" alt=""></div></div>
</template><script>export default {name: 'PrevImg',components: {},data() {return {isShow: false,imgIdx: 0,imgPaths: [],transform: {rotate: 0,scale: 1},enterAniClass: '',}},computed: {imgStyle() {let { rotate, scale } = this.transformreturn {transform: `scale(${scale}) rotate(${rotate}deg)`}},isNext() {return this.imgIdx != this.imgPaths.length - 1},isPrev() {return this.imgIdx != 0},},mounted() {this.$refs['imgWrapper'].addEventListener('webkitAnimationEnd', (e) => {console.log('动画停止了');this.enterAniClass = ''})},methods: {open({ imgIdx, imgPaths }) {this.isShow = truethis.imgIdx = imgIdxthis.imgPaths = imgPaths},close() {console.log('object');this.isShow = falsethis.transform = {rotate: 0,scale: 1}},operate(command) {if (command == 'zoomIn') {this.transform.scale += 0.04} else if (command == 'zoomOut') {this.transform.scale -= 0.04} else if (command == 'rotate') {this.transform.rotate += 90} else {this.transform = {rotate: 0,scale: 1}if (command == 'left') {if (this.imgIdx == 0) {return}this.imgIdx = this.imgIdx - 1} else if (command == 'right') {if (this.imgIdx == this.imgPaths.length - 1) {return}this.imgIdx = this.imgIdx + 1}}}}
}
</script><style lang="scss">
.prev-container {position: fixed;top: 0;left: 0;width: 100%;height: 100%;.mask {position: absolute;background-color: rgba(0, 0, 0, .3);width: 100%;height: 100%;z-index: -1;}.pointer-allowd {cursor: pointer !important;}.prev-next {width: 36px;height: 36px;border-radius: 50%;background-color: rgba(255, 255, 255, .3);text-align: center;line-height: 36px;cursor: not-allowed;position: absolute;top: 0;bottom: 0;margin: auto;z-index: 2000;}.left {left: 30px;}.right {right: 30px;}.indicator {display: flex;justify-content: flex-end;padding: 20px;z-index: 100;i {padding: 10px;background-color: rgba(255, 255, 255, .3);border-radius: 50%;margin: 0 5px;cursor: pointer;}}.img-wrapper {position: absolute;top: 0;width: 100%;height: 100%;z-index: -1;display: flex;align-items: center;justify-content: center;img {max-height: 100%;max-width: 80%;transition: all 0.5s;}}
}</style>

http://chatgpt.dhexx.cn/article/cqebnX5L.shtml

相关文章

vue 图片预览插件

vue 图片预览插件 步骤 1、先安装依赖 npm install v-viewer --save2、main.js内引用并注册调用 //main.js import Viewer from v-viewer import viewerjs/dist/viewer.cssVue.use(Viewer); Viewer.setDefaults({Options: { "inline": true, "button": …

Vue3图片预览(Image)

本图片预览组件主要包括以下功能&#xff1a; 展示图片时&#xff0c;可设置鼠标悬浮时的预览文本&#xff1b;图像无法加载时要显示的描述&#xff1b;自定义图像高度和宽度&#xff1b;设置图像如何适应容器高度和宽度&#xff08; fill(填充) | contain(等比缩放包含) | cov…

Vue实现图片预览和缩放功能

使用v-viewer插件即可实现图片预览和缩放功能。&#xff08;v-viewer是一款支持vue项目中的图片浏览组件&#xff0c;它支持图片旋转、缩放、翻转等操作&#xff0c;支持配置化.非常强大&#xff09; 安装依赖 执行命令&#xff1a; npm install v-viewer --save 引入并使用…

图片上传预览功能

大多时候我们上传图片&#xff0c;都是直接上传到服务器上&#xff0c;然后返回图片资源所在服务器的路径&#xff0c;然后页面根据这个路径&#xff0c;给图片一个src 属性就能看到图片了。 但是&#xff0c;这样会有一个弊端&#xff1a;如果客户对自己上传的图片不满意&am…

uniapp 图片预览实现

uniapp 图片预览实现 提示&#xff1a;下面案例可供参考 一、app端 使用 uni.previewImage 进行图片预览 可去 uniapp官网 查看具体使用:(https://uniapp.dcloud.net.cn/api/media/image.html#unipreviewimageobject) 二、具体使用如下&#xff08;示例&#xff09;&#xf…

Android中点击图片进行图片预览功能的实现(ImagePreview图片预览工具库)

因为需求&#xff0c;对于轮播图进行一个点击预览的功能&#xff0c;看了好多的文章&#xff0c;都没有弄出来&#xff0c;还是多亏了昊昊猿博主 点击查看原文 终于把它搞定啦。 这里的话是使用ImagePreview&#xff0c;一个非常好用的图片预览工具库&#xff08;还可以实现双…

Vue实现图片预览(Viewer.js)

Viewer.js viewer.js是一款开源的图片预览插件&#xff0c;功能十分强大: 支持移动设备触摸事件 支持响应式 支持放大/缩小 支持旋转&#xff08;类似微博的图片旋转&#xff09; 支持水平/垂直翻转 支持图片移动 支持键盘 支持全屏幻灯片模式&#xff08;可做屏保&#xff0…

前端图片预览怎么做?Vue

选择的图片文件&#xff0c;要给到img标签上纯前端的预览 让用户更近一步看到自己选择的头像 因为img的标签的src的值只能是以下两个 1、只能是图片的“链接地址”&#xff08;外链http://开头&#xff0c;图片文件相对路径&#xff09;(不能发给后台)因为第一种转成http是存…

点击图片实现大图预览

实现点击图片预览 这次主要是在table表格里能够实现&#xff0c;点击里面的图片实现大图预览的效果&#xff0c;直接找的现成的轮子&#xff0c;用在项目里。这里主要是讲讲用viewer组件实现点击图片预览&#xff0c;用的组件&#xff0c;只需在本地安装或者引入。 先看一下&…

ImagePreview 图片预览 的使用​

一、ImagePreview 图片预览 的使用 ImagePreview 是一个函数&#xff08;必须使用按需到处&#xff09;&#xff0c;调用函数后会直接在页面中展示图片预览界面。 // 实现图片预览 import { ImagePreview } from vant 二、处理图片点击预览 思路&#xff1a; 1、从文章内容中…

图片预览(原生js实现)

功能描述 很多网站都是使用浏览器自带图片浏览功能&#xff0c;但看起来很low&#xff0c;想手动实现图片预览功能&#xff0c;点击图片弹出大图预览框在屏幕中间显示&#xff0c;根据图片宽高自适应屏幕大小 效果图 具体代码实现 页面preview.html <!DOCTYPE html> …

图片预览的两种实现方式

做用户头像上传等类似功能的时候&#xff0c;经常会有预览选中图片的需求。在这里介绍两种实现预览的方式。 1.转化为base64格式 通过一种异步文件读取机制FileReader实现。具体步骤是&#xff1a; 创建FileReader对象调用readAsDataURL函数读取文件内容监听FileReader创建的…

CVTE 面试的两道算法题

下了班立马赶往深圳北站&#xff0c;下着大雨又坐过了站&#xff0c;着急地跑向对面的站牌&#xff0c;匆忙间搞得满头大汗。好不容易坐上了高铁&#xff0c;休息片刻&#xff0c;终于有时间整理一下前两天面试CVTE 时遇到的两道算法题。 1. 在数组中寻找和为固定值的两个数字…

CVTE实习求职经历

今天&#xff0c;听到有好多同学最近要去面试CVTE这家企业&#xff0c;于是呢&#xff0c;准备将自己的经历写上来&#xff0c;给大家一个参考&#xff0c;希望能够大家一次帮助。 一、整体感觉 首先呢&#xff0c;先讲一下我个人对这家企业的整体感觉吧。 1. 第一次 对于CVTE这…

CVTE 2016 春季实习校招一面(C++后台)

文章目录 前言问题小结参考文献 前言 2016-03-15 日&#xff0c;参加了 CVTE 的技术一面&#xff0c;很不幸&#xff0c;我和我的两位小伙伴均跪在了一面。先将当日的面试内容汇总如下&#xff0c;供后来者参考。我们三人各自也都总结了失败的原因&#xff0c;大致如下&#x…

CVTE2019校招笔试

在vector中删除元素时&#xff0c;指向被删除元素和它后面元素的迭代器都失效了&#xff1b;如果添加一个元素&#xff0c;可能导致所有内容重新分配&#xff0c;所有迭代器均失效。因此在循环中使用erase操作时&#xff0c;要特别注意。不过erase删除元素后会返回一个迭代器指…

CVTE C++软开全程面试(一面、二面、群面、HR面)

一面&#xff0c;面了一个钟&#xff0c;问了很多问题&#xff0c;大部分是计算机的基础知识&#xff0c;我也只能记录下一部分。 C的继承问题&#xff0c;protected成员被public、protected和private继承的情况。 下面是关于protected成员在不同类型继承中的访问权限&#xff…

2015 CVTE校招网测部分试题(技术类)

CVTE的网测题分为技术题与行测题&#xff0c;都非常基础非常简单&#xff0c;但也有较难的题目&#xff0c;下面这些题都是我当时觉得稍有些难或容易答错或值得进一步推敲的题&#xff0c;现在分享出来&#xff0c;大家可以对着知识点做下&#xff0c;不会的Google&#xff0c;…

剑指Offer——CVTE校招笔试题+知识点总结(Java岗)

剑指Offer(Java岗)——CVTE校招笔试题知识点总结 2016.9.3 19:00参加CVTE笔试&#xff0c;笔试内容如下: 需要掌握的知识:Linux基本命令、网络协议、数据库、数据结构。 选择题 1.36进制转换(0~9&#xff0c; A~Z)&#xff1a;28045707425转换结果为...P 2.已知二叉树的节点数…

2016CVTE校招在线笔试题

2016CVTE校招在线笔试题 https://www.nowcoder.com/test/458195/summary 以下说法正确的有() A. 多个进程操作同一个文件时&#xff0c;应该要考虑到文件的一致性问题 B. 可通过文件在不同进程间进行数据传递和共享 C. 可以通过全局变量在不同进程间传递数据 D. 一个进程可以…