Vue3图片浏览组件v-viewer,支持旋转、缩放、翻转等操作

文章目录

  • 1. v-viewer组件简介
  • 2. 在vue项目使用
    • 2.1 指令形式调用
    • 2.2 组件形式调用
    • 2.3 api形式调用
  • Viewer的配置项 & 方法
  • bug


1. v-viewer组件简介

一款基于 viewer.js 封装的Vue版插件,可用于图像查看,以及图片的旋转、缩放等功能预览

官网:v-viewer

  1. 文档说明:Vue3图片浏览组件v-viewer,支持旋转、缩放、翻转等操作
  2. 安装
    npm install v-viewer@next viewerjs
    
  3. 特点
  • 支持移动设备触摸事件
  • 支持响应式
  • 支持放大/缩小
  • 支持旋转(类似微博的图片旋转)
  • 支持水平/垂直翻转
  • 支持图片移动
  • 支持键盘
  • 支持全屏幻灯片模式(可做屏保)
  • 支持缩略图
  • 支持标题显示
  • 支持多种自定义事件

2. 在vue项目使用

2.1 指令形式调用

只需要将v-viewer指令添加到任意元素即可,该元素下的所有img元素都会被viewer自动处理。
可以传入配置项:v-viewer=“{inline: true}”
如果有必要,可以先用选择器查找到目标元素,然后可以用el.$viewer来获取viewer实例。

  1. 指令修饰符static

    添加修饰器后,viewer的创建只会在元素绑定指令时执行一次。
    如果你确定元素内的图片不会再发生变化,使用它可以避免不必要的重建动作。

    <div class="images" v-viewer.static="{inline: true}">
      <img v-for="src in images" :src="src" :key="src">
    </div>
    
  2. 指令修饰符rebuild

    默认情况下当图片发生变更时(添加、删除或排序),viewer实例会使用update方法更新内容。
    如果你遇到任何显示问题,尝试使用重建来代替更新。

    <div class="images" v-viewer.rebuild="{inline: true}">
      <img v-for="src in images" :src="src" :key="src">
    </div>
    
  3. 组件中以指令形式使用,代码如下
    <template>
      <div>
        <div ref="imagesDiv" class="images" v-show="false" v-viewer="{movable: false}">
          <img v-for="src in images" :src="src" :key="src">
        </div>
        <button type="button" @click="show">Show</button>
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from 'vue'
    import 'viewerjs/dist/viewer.css'
    import Viewer from 'viewerjs'
    export default defineComponent({
      setup () {
        const imagesDiv = ref<any>(null)
        const images = ref<string[]>([
          'https://picsum.photos/200/200',
          'https://picsum.photos/300/200',
          'https://picsum.photos/250/200'
        ])
        function show () {
          const viewer = imagesDiv.value.viewer
          viewer.show()
        }
        return {
          imagesDiv,
          images,
          show
        }
      },
      directives: {
      // mounted钩子函数负责初始化Viewer实例,而beforeUnmount钩子函数负责在组件销毁前清理Viewer实例。你可以通过传递一个对象作为指令的参数来配置Viewer.js的选项。
        viewer: {
          mounted (el, binding) {
            // 确保只初始化一次
            if (!el.viewer) {
              el.viewer = new Viewer(el, binding.value || {})
            }
          },
          beforeUnmount (el) {
            // 组件销毁前销毁viewer实例
            if (el.viewer) {
              el.viewer.destroy()
            }
          }
        }
      }
    })
    </script>
    <style scoped>
    </style>
    

以上代码执行效果

  1. 全局以指令形式使用,代码如下
    // main.ts
    import VueViewer from 'v-viewer';
    import 'viewerjs/dist/viewer.css';
    const app = createApp(App1)
    app.use(store)
    app.use(router)
    app.use(() => VueViewer)
    app.mount('#app')
    // 组件中的引用
    <template>
      <div>
        <div ref="imagesDiv" class="images" v-show="false" v-viewer="{movable: false}">
          <img v-for="src in images" :src="src" :key="src">
        </div>
        <button type="button" @click="show">Show</button>
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from 'vue'
    export default defineComponent({
      setup () {
        const imagesDiv = ref<any>(null)
        const images = ref<string[]>([
          'https://picsum.photos/200/200',
          'https://picsum.photos/300/200',
          'https://picsum.photos/250/200'
        ])
        function show () {
          const viewer = imagesDiv.value.$viewer
          viewer.show()
        }
        return {
          imagesDiv,
          images,
          show
        }
      }
    })
    </script>
    <style scoped>
    </style>
    

2.2 组件形式调用

可以单独引入全屏组件并局部注册它。

<template>
  <div>
    <Viewer class="images" v-show="false" ref="imagesDiv" :images="images" :options="viewOptions"  @inited="inited">
      <template #default="scope">
        <img v-for="src in scope.images" :src="src" :key="src">
        {{scope.options}}
      </template>
    </Viewer>
    <button type="button" @click="show">Show</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, reactive } from 'vue'
import 'viewerjs/dist/viewer.css'
import { component as Viewer } from 'v-viewer'
export default defineComponent({
  components: {
    Viewer
  },
  setup () {
    const imagesDiv = ref<any>(null)
    let viewerOne = ref<any>(null)
    const viewOptions = reactive({
      fullscreen: true,
      keyboard: false,
      loop: false

    })
    const images = ref<string[]>([
      'https://picsum.photos/200/200',
      'https://picsum.photos/300/200',
      'https://picsum.photos/250/200'
    ])
    function show () {
      viewerOne.value.show()
    }
    function inited (viewer: any) {
      viewerOne.value = viewer
    }
    return {
      imagesDiv,
      images,
      show,
      viewOptions,
      inited
    }
  }
})
</script>
<style scoped>
</style>
  1. images#
    Type: Array
  2. trigger
    Type: Object
    使用trigger来代替images, 从而传入任何类型的数据。
    当trigger绑定的数据发生变更,组件就会自动更新。
    <viewer :trigger="externallyGeneratedHtmlWithImages">
      <div v-html="externallyGeneratedHtmlWithImages"/>
    </viewer>
    
  3. rebuild
    Type: Boolean
    Default: false
    默认情况下当图片发生变更时(添加、删除或排序),viewer实例会使用update方法更新内容。
    如果你遇到任何显示问题,尝试使用重建来代替更新。
    <viewer
      ref="viewer"
      :options="options"
      :images="images"
      rebuild
      class="viewer"
      @inited="inited"
    >
      <template #default="scope">
        <img v-for="src in scope.images" :src="src" :key="src">
        {{scope.options}}
      </template>
    </viewer>
    
  4. 组件事件
    • inited

    viewer: Viewer
    监听inited事件来获取viewer实例,或者也可以用this.refs.xxx.$viewer这种方法。

2.3 api形式调用

api形式只能使用modal模式。
可以直接执行函数: this.$viewerApi({options: {}, images: []}) 来展现画廊, 而不需要自己来渲染这些img元素.
函数会返回对应的viewer实例.

<template>
	<div>
		<button v-if="images?.length" @click="showImagesInViewer(images)">查看</button>
	<div>
<template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue'
import 'viewerjs/dist/viewer.css'
import { api as viewerApi } from "v-viewer";
export default defineComponent({
 setup () {
 	const images = ref<string[]>([
      'https://picsum.photos/200/200',
      'https://picsum.photos/300/200',
      'https://picsum.photos/250/200'
    ])
	 const showImagesInViewer = (urls)=> {
 		const $viewer = viewerApi({
          options: {
            toolbar: true,
            url: 'data-source',
            initialViewIndex: 1
          },
          images: images.value
        })
	}
	return {
		images,
		showImagesInViewer 
	}
  }
})
</script>

Viewer的配置项 & 方法

如果要更改全局默认选项,可以使用view . setdefaults(选项)

  • 配置参数
参数名称参数类型默认值说明
initialViewIndexNumber0定义用于查看的图像的初始索引
inlineBooleanfalse支持 inline mode
buttonBooleantrue是否显示查看图片时右上角的关闭按钮
navbarBoolean / Numbertrue是否显示底部导航栏0 或者 false :不显示1 或者 true :显示2 :当屏幕宽度大于768px时显示3 :当屏幕宽度大于992px时显示4 :当屏幕宽度大于1200px时显示
titleBoolean / Number /Function / Arraytrue0 或者 false 时不显示1或者true或者function或者array时显示2 :当屏幕宽度大于768px时显示3 :当屏幕宽度大于992px时显示4 :当屏幕宽度大于1200px时显示function 在函数体内返回标题array 第一个参数表示可见性(0-4) 第二个参数就是标题
toolbarBoolean / Number / Objecttrue标题栏是否显示和布局0 或者 false 时不显示1或者true或者时显示2 :当屏幕宽度大于768px时显示3 :当屏幕宽度大于992px时显示4 :当屏幕宽度大于1200px时显示
tooltipBooleantrue放大或缩小时显示的百分比的文字提示true : 显示false : 不显示
movableBooleantrue是否可以拖动图片
zoomableBooleantrue是否可以缩放图片
rotatableBooleantrue是否可以旋转图片
scalableBooleantrue是否可以缩放图片
transitionBooleantrue为一些特殊元素启用CSS3转换。
fullscreenBooleantrue允许全屏播放
keyboardBooleantrue启用键盘支持
backdropBoolean / Stringtrue启用 modal 为false的时候不支持点击背景关闭
loadingBooleantrue加载图片的时候的loading图标
loopBooleantrue是否可以循环查看图片
intervalNumber5000定义图片查看器的最小的宽度
minWidthNumber200定义图片查看器的最小的高度
minHeightNumber100播放图片时 距离下一张图片的间隔时间
zoomRatioNumber0.1利用鼠标滚轮缩放图片时的比例
minZoomRatioNumber0.01缩小图片的最小比例
maxZoomRatioNumber100放大图片的放大比例
zIndexNumber2015定义查看器的CSS z-index值 modal 模式下
zIndexInlineNumber0定义查看器的CSS z-index值 inline 模式下
urlString / Functionsrc原始图像URL如果是一个字符串,应该图像元素的属性之一如果是一个函数,应该返回一个有效的图像URL
containerElement / Stringbody将查看器置于modal模式的容器只有在 inline为 false的时候才可以使用
filterFunctionnull过滤图像以便查看(如果图像是可见的,应该返回true)
toggleOnDblclickBooleantrue当你放大或者缩小图片时 双击还原
readyFunctionnull当查看图片时被触发的函数 只会触发一次
showFunctionnull当查看图片时被触发的函数 每次查看都会触发
shownFunctionnull当查看图片时被触发的函数 每次查看都会触发 在show之后
hideFunctionnull当关闭图片查看器时被触发的函数 每次关闭都会触发
hiddenFunctionnull当关闭图片查看器时被触发的函数 每次关闭都会触发 在hide之后
viewFunctionnull当查看图片时被触发的函数 每次查看都会触发 在shown之后
viewedFunctionnull当查看图片时被触发的函数 每次查看都会触发 在view之后
zoomFunctionnull在图片缩放时触发
zoomedFunctionnull在图片缩放时触发 在 zoom之后
  • toolbar Object详解
    key值列表: “zoomIn”, “zoomOut”, “oneToOne”, “reset”, “prev”, “play”, “next”, “rotateLeft”, “rotateRight”, “flipHorizontal”, “flipVertical”
key值名称说明
zoomIn放大图片的按钮
zoomOut缩小图片的按钮
reset重置图片大小的按钮
prev查看上一张图片的按钮
next查看上一张图片的按钮
play播放图片的按钮
rotateLeft向左旋转图片的按钮
rotateRight向右旋转图片的按钮
flipHorizontal图片左右翻转的按钮
flipVertical图片上下翻转的按钮

{key:number|Boolean} 显示或者隐藏对应key的按钮 为Number的时候为可见性
{key: String } 自定义按钮的大小
{ key: Function } 自定义按钮点击的处理
{ key: { show: Boolean | Number, size: String, click: Function } 自定义按钮的每个属性

size的取值范围: small medium default large

bug

1:在main.ts配置中有时候会报错
在这里插入图片描述

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import Viewer from 'viewerjs';
import 'viewerjs/dist/viewer.css';
Viewer.setDefaults({
  navbar: true,
  title: true,
  toolbar: {
    prev: true,
    next: true,
  },
});
const Vue = createApp(App);
Vue.use(router);
Vue.use(() => Viewer); //这样引入是为了兼容ts规定的类型,不用箭头函数方式会报错Argument of type 'typeof Viewer' is not assignable to parameter of type 'Plugin_2'.Property 'install' is missing in type 'typeof Viewer' but required in type '{ install: PluginInstallFunction; }'
Vue.mount('#app');

然而引入不报错了,却不能使用,这里如果那位大神解决了,烦劳告诉我一下解决办法;
索性我们还是局部引入吧,毕竟也不是每个组件都能用到,于是放弃了在main.ts中使用;
在2个项目中同时使用,一个正常的全局注入能够成功,一个不成功,目前还没找到原因。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/647607.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CVE-2020-7982 OpenWrt 远程命令执行漏洞学习(更新中)

OpenWrt是一款应用于嵌入式设备如路由器等的Linux操作系统。类似于kali等linux系统中的apt-get等&#xff0c;该系统中下载应用使用的是opgk工具&#xff0c;其通过非加密的HTTP连接来下载应用。但是其下载的应用使用了SHA256sum哈希值来进行检验&#xff0c;所以将下载到的数据…

python探索转义字符的奥秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、转义字符的定义与功能 案例解析&#xff1a;换行符与双引号 二、转义字符的应用场景 …

【笔记】Pytorch安装配置

参考视频 安装前建议预留至少10个G的空间&#xff0c;会省下很多麻烦 查看安装是否成功&#xff0c;可以在Anaconda Prompt里输入conda list查看conda环境是否配置了pytorch/torchvision 1.安装anaconda 2.安装 CUDA CUDA在官网直接安装即可&#xff0c;需要先查看自己电脑…

HQL面试题练习 —— 互相关注

目录 1 题目2 建表语句3 题解 1 题目 现有用户关注者列表记录表 t_user_follower&#xff0c;有两个字段&#xff0c;用户ID&#xff08;user_id&#xff09;&#xff0c;关注者列表&#xff08;follower_ids)&#xff0c;关注者列表中是关注用户的用户ID&#xff0c;数据样例如…

python冰雹序列的探索与编程实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、冰雹序列的奥秘 二、编程实现冰雹序列 三、测试与验证 四、总结与展望 一、冰雹序列的…

【NOIP2013普及组复赛】题4:车站分级

题4&#xff1a;车站分级 【题目描述】 一条单向的铁路线上&#xff0c;依次有编号为 1 , 2 , … , n 1,2,…,n 1,2,…,n 的 n n n 个火车站。每个火车站都有一个级别&#xff0c;最低为 1 1 1 级。现有若干趟车次在这条线路上行驶&#xff0c;每一趟都满足如下要求&#…

力扣刷题---LCS 02. 完成一半题目【简单】

题目描述 有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例 1&…

基于yolov5和desnet的猫咪识别模型

前言 前段时间给学校的猫咪小程序搭建了识猫模型&#xff0c;可以通过猫咪的照片辨别出是那只猫猫&#xff0c;这里分享下具体的方案&#xff0c;先看效果图&#xff1a; 源代码在文末 模型训练 在训练服务器&#xff08;或你的个人PC&#xff09;上拉取本仓库代码。 图片数据…

方正畅享全媒体新闻采编系统 binary.do SQL注入漏洞复现

0x01 产品简介 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、发…

nss做题

[NCTF 2018]签到题 1.f12在index.php中找到flag [NSSCTF 2022 Spring Recruit]ezgame 1.在js源码中就有flag [UUCTF 2022 新生赛]websign 1.打开环境后发现ctrlu和右键&#xff0c;f12都被禁用了。两种方法&#xff0c;第一种&#xff1a;禁用js&#xff1b;第二中提前打开…

解决MacBook无法访问github问题

第一步&#xff1a;点击右上角Wi-Fi图标&#xff0c;在弹出的下拉框中选择“网络偏好设置” 第二步&#xff1a;在弹出框中选择WI-FI后&#xff0c;点击右下角的高级选项 第三步&#xff1a;在弹出框中选择DNS页签&#xff0c;点击左下角的加“”号&#xff0c;输入8.8.8.8后&a…

如何编辑 PDF 中的文本?4个有效的编辑PDF方法

PDF 文件可以轻松打开和查看&#xff0c;但修改要复杂得多 - 尤其是在 PDF 中的文本编辑方面。 知道如何离线编辑 PDF 中的文本对于任何需要快速更改而无需在线加载文档或担心安全问题的人来说都非常有益。它使用户能够更好地控制他们的文档&#xff0c;并有更广泛的字体和图形…

美军配备人工智能武器的机器狗引发伦理争议

近日&#xff0c;美国海军陆战队特种作战司令部&#xff08;MARSOC&#xff09;的一项测试引发了全球关注&#xff1a;他们正在评估一种由“幽灵机器人”公司研发的最新型机器狗&#xff0c;并考虑为其配备“玛瑙工业”公司提供的武器系统。这一消息犹如在平静的湖面投下一颗石…

怎么在Qt Designer设计的界面上显示Matplotlib的绘图?

首先&#xff0c;利用Qt Designer设计界面。 设计好后保存为ui文件。 接着&#xff0c;将ui文件转为py文件。 我喜欢在python中进行转换&#xff0c;因此把转换命令封装为函数&#xff0c;运行一下即可。 import os # pyuic5 -o output_file.py input_file.ui #通过命令把.ui…

半年不在csdn写博客,总结一下这半年的学习经历,coderfun的一些碎碎念.

前言 自从自己建站一来&#xff0c;就不在csdn写博客了&#xff0c;但是后来自己的网站因为资金问题不能继续维护下去&#xff0c;所以便放弃了自建博客网站来写博客&#xff0c;等到以后找到稳定&#xff0c;打算满意的工作再来做自己的博客网站。此篇博客用来记录自己在csdn…

初学Echart

创建一个html文件 1.引入 点击链接----快速上手网址&#xff1a;快速上手 - 使用手册 - Apache ECharts 复制这一串【这个是引入echart路径】 引入到这里 2.使用 我们在上一步---点击返回--往下翻---找到完整代码--复制黏贴 复制粘贴后--总体长这样 <!DOCTYPE html> &…

vulnhub靶场之FunBox-8

一.环境搭建 1.靶场描述 Its a box for beginners and can be pwned in the lunch break. This works better with VirtualBox rather than VMware 2.靶场下载 Funbox: Lunchbreaker ~ VulnHub 3.靶场启动 二.信息收集 1.寻找靶场真实IP地址 nmap -sP 192.168.2.0/24 arp-…

驱动开发之字符设备开发

1.概念 字符设备是 Linux 驱动中最基本的一类设备驱动&#xff0c;字符设备就是一个一个字节&#xff0c;按照字节 流进行读写操作的设备&#xff0c;读写数据是分先后顺序的。比如我们最常见的点灯、按键、IIC、SPI&#xff0c; LCD 等等都是字符设备&#xff0c;这些设备的驱…

算法在计算中的作用

前言 算法在基因工程&#xff0c;互联网&#xff0c;电子商务和制造业中都有广泛的应用。最近的智能驾驶和人工智能也处处有着算法的影子。 数据结构 数据结构是数据元素存在的一种形式&#xff0c;有线性和非线性的区别。常见的线性的有链表&#xff0c;数组&#xff0c;栈和…

Modal.method() 不显示头部的问题

ant-design中的Modal组件有两种用法&#xff1a; 第一种是用标签&#xff1a;<a-modal></a-modal> 第二种是用Api&#xff1a;Modal.info、Modal.warning、Modal.confirm...... 一开始项目中这两种用法是混用的&#xff0c;后面UI改造&#xff0c;需要统一样式&…