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

v-viewer

用于图片浏览的Vue3组件,支持旋转、缩放、翻转等操作,基于viewer.js

有任何问题请到github项目页提交issue,博客的留言我可能无法及时看到,谢谢各位支持👍。

npm versionlanguage

npm versionlanguage

npm downloadlicense

v-viewer for vue2

在线演示

使用示例

安装

使用npm命令安装

bash
npm install v-viewer@next viewerjs

使用

引入v-viewer及必需的css样式,并使用app.use()注册插件,之后即可使用。

组件、指令和api会被一起安装到app全局。

ts
import { createApp } from 'vue'
import App from './App.vue'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'
const app = createApp(App)
app.use(VueViewer)
app.mount('#app')
vue
<template>
  <div>
    <!-- directive -->
    <div class="images" v-viewer>
      <img v-for="src in images" :key="src" :src="src">
    </div>
    <!-- component -->
    <viewer :images="images">
      <img v-for="src in images" :key="src" :src="src">
    </viewer>
    <!-- api -->
    <button type="button" @click="show">Click to show</button>
  </div>
</template>
<script lang="ts">
  import { defineComponent } from 'vue'
  export default defineComponent({
    data() {
      return {
        images: [
          "https://picsum.photos/200/200",
          "https://picsum.photos/300/200",
          "https://picsum.photos/250/200"
        ]
      };
    },
    methods: {
      show() {
        this.$viewerApi({
          images: this.images,
        })
      },
    },
  })
</script>

支持UMD方式引入

Browser

html
<link href="//unpkg.com/viewerjs/dist/viewer.css" rel="stylesheet">
<script src="//unpkg.com/vue@next"></script>
<script src="//unpkg.com/viewerjs/dist/viewer.js"></script>
<script src="//unpkg.com/v-viewer@next/dist/index.umd.js"></script>
<script>
  app.use(VueViewer.default)
</script>

CommonJS

javascript
var VueViewer = require('VueViewer')

AMD

javascript
require(['VueViewer'], function (VueViewer) {});

以指令形式使用

只需要将v-viewer指令添加到任意元素即可,该元素下的所有img元素都会被viewer自动处理。

你可以像这样传入配置项: v-viewer="{inline: true}"

如果有必要,可以先用选择器查找到目标元素,然后可以用el.$viewer来获取viewer实例。

vue
<template>
  <div>
    <div class="images" 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 } from 'vue'
  import { defineComponent } from 'vue'
  import 'viewerjs/dist/viewer.css'
  import { directive as viewer } from "v-viewer"
  export default defineComponent({
    directives: {
      viewer: viewer({
        debug: true,
      }),
    },
    data() {
      return {
        images: [
          "https://picsum.photos/200/200",
          "https://picsum.photos/300/200",
          "https://picsum.photos/250/200"
        ]
      };
    },
    methods: {
      show () {
        const viewer = this.$el.querySelector('.images').$viewer
        viewer.show()
      }
    }
  })
</script>

指令修饰器

static

添加修饰器后,viewer的创建只会在元素绑定指令时执行一次。

如果你确定元素内的图片不会再发生变化,使用它可以避免不必要的重建动作。

vue
<div class="images" v-viewer.static="{inline: true}">
  <img v-for="src in images" :src="src" :key="src">
</div>
rebuild

默认情况下当图片发生变更时(添加、删除或排序),viewer实例会使用update方法更新内容。

如果你遇到任何显示问题,尝试使用重建来代替更新。

vue
<div class="images" v-viewer.rebuild="{inline: true}">
  <img v-for="src in images" :src="src" :key="src">
</div>

以组件形式使用

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

vue
<template>
  <div>
    <viewer :options="options" :images="images"
            @inited="inited"
            class="viewer" ref="viewer"
            >
      <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 } from 'vue'
  import 'viewerjs/dist/viewer.css'
  import { component as Viewer } from "v-viewer"
  export default defineComponent({
    components: {
      Viewer,
    },
    data() {
      return {
        images: [
          "https://picsum.photos/200/200",
          "https://picsum.photos/300/200",
          "https://picsum.photos/250/200"
        ]
      };
    },
    methods: {
      inited (viewer) {
        this.$viewer = viewer
      },
      show () {
        this.$viewer.show()
      }
    }
  })
</script>

组件属性

images
  • Type: Array
trigger
  • Type: Object

你可以使用trigger来代替images, 从而传入任何类型的数据。

trigger绑定的数据发生变更,组件就会自动更新。

vue
<viewer :trigger="externallyGeneratedHtmlWithImages">
  <div v-html="externallyGeneratedHtmlWithImages"/>
</viewer>
rebuild
  • Type: Boolean
  • Default: false

默认情况下当图片发生变更时(添加、删除或排序),viewer实例会使用update方法更新内容。

如果你遇到任何显示问题,尝试使用重建来代替更新。

vue
<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>

组件事件

inited
  • viewer: Viewer

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

以api形式使用

api形式只能使用modal模式。

你可以直接执行函数: this.$viewerApi({options: {}, images: []}) 来展现画廊, 而不需要自己来渲染这些img元素.

函数会返回对应的viewer实例.

vue
<template>
  <div>
    <button type="button" class="button" @click="previewURL">URL Array</button>
    <button type="button" class="button" @click="previewImgObject">Img-Object Array</button>
  </div>
</template>
<script lang="ts">
  import { defineComponent } from 'vue'
  import 'viewerjs/dist/viewer.css'
  import { api as viewerApi } from "v-viewer"
  export default defineComponent({
    data() {
      sourceImageURLs: [
        'https://picsum.photos/200/200?random=1',
        'https://picsum.photos/200/200?random=2',
      ],
      sourceImageObjects: [
        {
          'src':'https://picsum.photos/200/200?random=3',
          'data-source':'https://picsum.photos/800/800?random=3'
        },
        {
          'src':'https://picsum.photos/200/200?random=4',
          'data-source':'https://picsum.photos/800/800?random=4'
        }
      ]
    },
    methods: {
      previewURL () {
        // If you use the `app.use` full installation, you can use `this.$viewerApi` directly like this
        const $viewer = this.$viewerApi({
          images: this.sourceImageURLs
        })
      },
      previewImgObject () {
        // Or you can just import the api method and call it.
        const $viewer = viewerApi({
          options: {
            toolbar: true,
            url: 'data-source',
            initialViewIndex: 1
          },
          images: this.sourceImageObjects
        })
      }
    }
  })
</script>

Viewer的配置项 & 方法

请参考viewer.js.

插件配置项

name

  • Type: String
  • Default: viewer

如果你需要避免重名冲突,可以像这样引入:

ts
import { createApp } from 'vue'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'
import App from './App.vue'

export const app = createApp(App)
app.use(VueViewer, {
  name: 'vuer',
  debug: true,
})
app.mount('#app')
vue
<template>
<div>
  <!-- directive name -->
  <div class="images" v-vuer="{movable: false}">
    <img v-for="src in images" :src="src" :key="src">
  </div>
  <button type="button" @click="show">Show</button>
  <!-- component name -->
  <vuer :images="images">
    <img v-for="src in images" :src="src" :key="src">
  </vuer>
  </div>
</template>
<script lang="ts">
  import { defineComponent } from 'vue'
  export default defineComponent({
    data() {
      return {
        images: [
          "https://picsum.photos/200/200",
          "https://picsum.photos/300/200",
          "https://picsum.photos/250/200"
        ]
      };
    },
    methods: {
      show () {
        // viewerjs instance name
        const vuer = this.$el.querySelector('.images').$vuer
        vuer.show()
        // api name
        this.$vuerApi({
          images: this.images
        })
      }
    }
  })
</script>

defaultOptions

  • Type: Object
  • Default: undefined

如果你需要修改viewer.js的全局默认配置项,可以像这样引入:

ts
import { createApp } from 'vue'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'
import App from './App.vue'

export const app = createApp(App)
app.use(VueViewer, {
  defaultOptions: {
    zIndex: 9999
  }
})
app.mount('#app')

你还可以在任何时候像这样修改全局默认配置项:

javascript
import VueViewer from 'v-viewer'

VueViewer.setDefaults({
  zIndexInline: 2021,
})
Husky6配置正确但无法触发githook的问题
如何在一段URL中插入参数