vue-easy-lightbox

基于Vue.js 3.0 与 TypeScript 构建的图片阅览插件, 提供了旋转、放大、拖拽功能。可自定义各种功能。

vue-easy-lightbox@1.x 只支持Vue.js 3, 如果你需要使用Vue.js 2版本,请点击这里open in new window查看.

安装

使用 npm or yarn 安装

$ npm install --save vue-easy-lightbox@next
$ yarn add vue-easy-lightbox@next

浏览器引入

在浏览器中使用 script 直接引入,使用全局变量 VueEasyLightbox.

<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-easy-lightbox@next/dist/vue-easy-lightbox.umd.min.js"></script>
<script>
  const app = Vue.createApp({
    // ... 根组件选项
  })
  app.use(VueEasyLightbox) // 全局变量
  app.mount('#app')
</script>

不同构建版本的区别

由于 Vue 3.x 使用 ES2015 (docs faqopen in new window), 不再需要构建ES5版本,1.6.0版本开始不再提供ES5构建包.

ModuleFilename
UMD(for browsers)vue-easy-lightbox.umd.min.js
CommonJSvue-easy-lightbox.common.min.js (pkg.main)
ES Module(for bundlers)vue-easy-lightbox.esm.min.js (pkg.module)

单独导入CSS文件

Added in: 1.2.3

默认情况下, CSS被包含在了 dist/*.min.js. 在一些特殊情况,你可能需要单独引入CSS文件来避免一些问题 (CSP Violationopen in new window). 你可以从dist/external-css/导入不包含CSS的构建文件和单独的样式文件.

import VueEasyLightbox from 'vue-easy-lightbox/external-css'
// or
import VueEasyLightbox from 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js'

// 单独引入组件样式
import 'vue-easy-lightbox/external-css/vue-easy-lightbox.css'
// or
import 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.css'

TypeScript Checking error:

如果你使用TypeScript,并遇到了以下报错:

Could not find the declaration file for module 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js'

这里有两种办法解决这个问题

方法 1: 项目本地添加 d.ts,补充模块信息:

declare module 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js' {
  import VueEasyLightbox from 'vue-easy-lightbox'
  export * from 'vue-easy-lightbox'
  export default VueEasyLightbox
}

方法 2: 如果你使用的是Webpack工程,参考以下方法: webpack alias docsopen in new window

// wepback.config.js
module.exports = {
  //...
  resolve: {
    alias: {
      'vue-easy-lightbox$': 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js',
    },
  },
};

// in your component
import VueEasyLightbox from 'vue-easy-lightbox' // work

或者使用 vitejs: vitejs aliasopen in new window

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  resolve: {
    alias: {
      'vue-easy-lightbox$': 'vue-easy-lightbox/dist/external-css/vue-easy-lightbox.esm.min.js'
    }
  }
})

使用方式

HTML中使用 UMD 包导入

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-easy-lightbox@next/dist/vue-easy-lightbox.umd.min.js"></script>
  </head>
  <body>
    <div id="app">
      <div class="">
        <div v-for="(src, index) in imgs" :key="index" class="pic" @click="() => showImg(index)">
          <img :src="src" />
        </div>
      </div>
      <vue-easy-lightbox :visible="visibleRef" :imgs="imgs" :index="indexRef" @hide="onHide"></vue-easy-lightbox>
    </div>
    <script>
      const { ref } = Vue
      const app = Vue.createApp({
        setup() {
          const visibleRef = ref(false)
          const indexRef = ref(0)
          const imgs = [
            'https://via.placeholder.com/450.png/',
            'https://via.placeholder.com/300.png/',
            'https://via.placeholder.com/150.png/',
            { src: 'https://via.placeholder.com/450.png/', title: 'this is title' }
          ]
          const showImg = (index) => {
            indexRef.value = index
            visibleRef.value = true
          }
          const onHide = () => visibleRef.value = false
          return {
            visibleRef,
            indexRef,
            imgs,
            showImg,
            onHide
          }
        }
      })
      // Registering VueEasyLightbox for your VueApp.
      app.use(VueEasyLightbox)
      app.mount('#app')
    </script>
  </body>
</html>

单文件组件用法

1. 注册VueApp组件

import Vue from 'vue'
import VueEasyLightbox from 'vue-easy-lightbox'

const app = Vue.createApp({
  // ... 根组件选项
})
// app中以插件方式全局注册
app.use(VueEasyLightbox)
app.mount('#app')

2. 基础用法

<template>
  <div>
    <button @click="showSingle">Show single picture.</button>
    <button @click="showMultiple">Show a group of pictures.</button>

    <vue-easy-lightbox
      :visible="visibleRef"
      :imgs="imgsRef"
      :index="indexRef"
      @hide="onHide"
    ></vue-easy-lightbox>
  </div>
</template>

<script>
// 如果VueApp已经注册组件,则这里不需要单独引入
import VueEasyLightbox from 'vue-easy-lightbox'
import { ref, defineComponent } from 'vue'

export default defineComponent({
  components: {
    VueEasyLightbox
  },
  setup() {
    const visibleRef = ref(false)
    const indexRef = ref(0) // default 0
    const imgsRef = ref([])
    // Img Url , string or Array of string
    // ImgObj { src: '', title: '', alt: '' }
    // 'src' 是必须值
    // 允许混合

    const onShow = () => {
      visibleRef.value = true
    }
    const showSingle = () => {
      imgsRef.value = 'http://via.placeholder.com/350x150'
      // or
      // imgsRef.value  = {
      //   title: 'this is a placeholder',
      //   src: 'http://via.placeholder.com/350x150'
      // }
      onShow()
    }
    const showMultiple = () => {
      imgsRef.value = [
        'http://via.placeholder.com/350x150',
        'http://via.placeholder.com/350x150'
      ]
      // or
      // imgsRef.value = [
      //   { title: 'test img', src: 'http://via.placeholder.com/350x150' },
      //   'http://via.placeholder.com/350x150'
      // ]
      indexRef.value = 0 // 图片顺序索引
      onShow()
    }
    const onHide = () => (visibleRef.value = false)

    return {
      visibleRef,
      indexRef,
      imgsRef,
      showSingle,
      showMultiple,
      onHide
    }
  }
})
</script>

使用slot定制你的按钮或者工具栏

<vue-easy-lightbox
  ...
>
  <template v-slot:prev-btn="{ prev }">
    <button @click="prev">上一张</button>
  </template>

  <template v-slot:next-btn="{ next }">
    <button @click="next">下一张</button>
  </template>

  <template v-slot:close-btn="{ close }">
    <button @click="close">关闭</button>
  </template>

  <template v-slot:toolbar="{ toolbarMethods }">
    <button @click="toolbarMethods.zoomIn">放大图片</button>
    <button @click="toolbarMethods.zoomOut">缩小图片</button>
    <button @click="toolbarMethods.rotateLeft">逆时针旋转</button>
    <button @click="toolbarMethods.rotateRight">顺时针旋转</button>
  </template>
</vue-easy-lightbox>

参考:插槽 - Vue.jsopen in new window

组合式函数 Composables

Added in v1.7.0

useEasyLightbox 提供了一些简单的方法和state,方便你使用setup()。 这个composable是可选的。你可以自定义自己的状态和方法。

Usage:

<template>
  <div>
    <button @click="show">show</button>
    <vue-easy-lightbox
      :visible="visibleRef"
      :imgs="imgsRef"
      :index="indexRef"
      @hide="onHide"
    />
  </div>
</template>

<script>
import { defineComponent } from 'vue'
import VueEasyLightbox, { useEasyLightbox } from 'vue-easy-lightbox'

export default defineComponent({
  components: {
    VueEasyLightbox
  },
  setup() {
    const {
      // methods
      show, onHide, changeIndex,
      // refs
      visibleRef, indexRef, imgsRef
    } = useEasyLightbox({
      // src / src[]
      imgs: [
        'http://via.placeholder.com/250x150',
        'http://via.placeholder.com/300x150',
        'http://via.placeholder.com/350x150'
      ],
      // initial index
      initIndex: 0
    })

    return {
      visibleRef,
      indexRef,
      imgsRef,
      show,
      onHide
    }
  }
})
</script>

Type declaration

export interface Img {
  src?: string
  title?: string
  alt?: string
}
export interface UseEasyLightboxOptions {
  /**
   * image src/Img or list of images src/Img
   * @default ''
   */
  imgs: Img | string | (Img | string)[];
  /**
   * initial index of imgList
   * @default 0
   */
  initIndex?: number;
}
export declare const useEasyLightbox: (options: UseEasyLightboxOptions) => {
  imgsRef: Ref<Img | string | (Img | string)[]>;
  indexRef: Ref<number | undefined>;
  visibleRef: Ref<boolean>;
  show: (index?: Ref<number> | number | Event) => void;
  onHide: () => void;
  changeIndex: (index?: number) => void;
};

配置项

Props

属性类型默认值说明
visibleBooleanrequired控制组件的显示
imgsString/String[]/ImgObject:{ src: string, title?: string, alt?: string }/ImgObject[]required图片的src字符串或图片对象(地址和标题) { src, title?, alt? },传入数组则可以轮播显示
indexNumber0打开图片组时,展示索引位置的图片
loopBooleanfalse允许循环切换图片
scrollDisabled (scroll-disabled)Booleantrue传true时,禁用背景滚动
escDisabled (esc-disabled)Booleanfalse默认情况下,展示时按下esc键关闭Modal
moveDisabled (move-disabled)Booleanfalse传true时,禁用拖动图片功能,并启用手势swipe功能
rotateDisabled (rotate-disabled)Booleanfalse传true时,禁用图片旋转功能
zoomDisabled (zoom-disabled)Booleanfalse传true时,禁用图片缩放功能
pinchDisabled (pinch-disabled)Booleanfalse传true时,禁用双指触摸缩放功能
maskClosable (mask-closable)Booleantrue控制点击蒙板关闭预览.
dblclickDisabled (dblclick-closable)Booleanfalse控制双击缩放功能.
teleportstring | Element-指定挂载的节点
swipeTolerance (swipe-tolerance)Number50指定swipe距离,单位为px
zoomScaleNumber0.12指定缩放步进的比例
maxZoomNumber3指定图片最大缩放比例
minZoomNumber0.1指定图片最小缩放比例.
rtlBooleanfalse指定RTL布局

参考: Teleportopen in new window

Event

事件名说明返回值
hide当点击遮罩或者关闭按钮时,会触发该事件-
on-error图片加载错误,触发error事件event (event.target 不是实际展示的图片)
on-prev /
on-prev-click
切换上一张图片时触发(oldIndex, newIndex)
on-next /
on-next-click
切换下一张图片时触发(oldIndex, newIndex)
on-index-change当图片索引被改变时触发,比如点击或更改传给组件index(oldIndex, newIndex)
on-rotate当图片旋转时触发事件deg: number (顺时针角度)

Slot 插槽

名称slot propsslot props 类型说明
prev-btnprevFunction当点击时显示上一页
next-btnnextFunction当点击时显示下一页
close-btncloseFunction当点击时关闭弹窗
toolbar toolbarMethods: { zoomIn, zoomOut, rotate(rotateLeft), rotateLeft, rotateRight } { Function }放大、缩小、逆时针/顺时针旋转
loading--加载图标
onerror--图片加载错误占位图