[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-8760":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":32,"trendingCount":16,"starSnapshotCount":16,"syncStatus":33,"lastSyncTime":34,"discoverSource":35},8760,"v-viewer","mirari\u002Fv-viewer","mirari","Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js","https:\u002F\u002Fmirari.cc\u002Fv-viewer\u002F",null,"Vue",2636,300,16,34,0,4,59.84,"MIT License",false,"master",true,[24,25,26,27,28,29],"gallery","image","img","picture","viewer","vue","2026-06-12 04:00:41","# v-viewer\n\nImage viewer component for vue, supports rotation, scale, zoom and so on, based on [viewer.js](https:\u002F\u002Fgithub.com\u002Ffengyuanchen\u002Fviewerjs)\n\n[![npm version](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Fv-viewer.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fv-viewer)\n[![language](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flanguage-Vue3-brightgreen.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fv-viewer)\n\n[![npm version](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Fv-viewer\u002Flegacy.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fv-viewer)\n[![language](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flanguage-Vue2-brightgreen.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fv-viewer)\n\n[![npm download](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdw\u002Fv-viewer.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fv-viewer)\n[![license](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-brightgreen.svg)](https:\u002F\u002Fmit-license.org\u002F) \n\n## [v-viewer for vue2](https:\u002F\u002Fgithub.com\u002Fmirari\u002Fv-viewer\u002Ftree\u002Fv2)\n\n## [Live demo](https:\u002F\u002Fmirari.github.io\u002Fvue3-viewer\u002F)\n\n## Quick Example\n\n- [directive](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FyLMPPWy)\n- [component](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FZEeaaWZ)\n- [api](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FqBrVpNV)\n- [thumbnail & source](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FVwpryax)\n- [viewer callback](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FeYveypz)\n- [custom toolbar](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FZEXqyPq)\n- [filter images](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FmdWqpwa)\n- [change images](https:\u002F\u002Fcodepen.io\u002Fmirari\u002Fpen\u002FExWbovw)\n\n## [中文文档](https:\u002F\u002Fmirari.cc\u002Fposts\u002Fvue3-viewer)\n\n## Installation\n\nInstall from NPM\n\n```bash\nnpm install v-viewer viewerjs\n```\n\n## Usage\n\nTo use `v-viewer`, simply import it and the `css` file, and call `app.use()` to install.\n\nThe component, directive and api will be installed together in the global.\n\nTwo different API styles are both supported: **Options API** and **Composition API**.\n\n```ts\nimport { createApp } from 'vue'\nimport App from '.\u002FApp.vue'\nimport 'viewerjs\u002Fdist\u002Fviewer.css'\nimport VueViewer from 'v-viewer'\nconst app = createApp(App)\napp.use(VueViewer)\napp.mount('#app')\n```\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003C!-- directive -->\n    \u003Cdiv class=\"images\" v-viewer>\n      \u003Cimg v-for=\"src in images\" :key=\"src\" :src=\"src\">\n    \u003C\u002Fdiv>\n    \u003C!-- component -->\n    \u003Cviewer :images=\"images\">\n      \u003Cimg v-for=\"src in images\" :key=\"src\" :src=\"src\">\n    \u003C\u002Fviewer>\n    \u003C!-- api -->\n    \u003Cbutton type=\"button\" @click=\"show\">Click to show\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003C!-- Options API -->\n\u003Cscript lang=\"ts\">\n  import { defineComponent } from 'vue'\n  export default defineComponent({\n    data() {\n      return {\n        images: [\n          \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n        ]\n      }\n    },\n    methods: {\n      show() {\n        this.$viewerApi({\n          images: this.images\n        })\n      }\n    }\n  })\n\u003C\u002Fscript>\n\u003C!-- Composition API -->\n\u003C!-- \u003Cscript lang=\"ts\" setup>\n  import { api as viewerApi } from 'v-viewer'\n  const images = [\n    \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n  ]\n  const show = () => {\n    viewerApi({\n      images\n    })\n  }\n\u003C\u002Fscript> -->\n```\n\n### Support UMD\n\n#### Browser\n\n```html\n\u003Clink href=\"\u002F\u002Funpkg.com\u002Fviewerjs\u002Fdist\u002Fviewer.css\" rel=\"stylesheet\">\n\u003Cscript src=\"\u002F\u002Funpkg.com\u002Fvue\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002F\u002Funpkg.com\u002Fviewerjs\u002Fdist\u002Fviewer.js\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002F\u002Funpkg.com\u002Fv-viewer\u002Fdist\u002Findex.umd.js\">\u003C\u002Fscript>\n\u003Cscript>\n  app.use(VueViewer.default)\n\u003C\u002Fscript>\n```\n\n#### CommonJS\n\n```javascript\nvar VueViewer = require('VueViewer')\n```\n\n#### AMD\n\n```javascript\nrequire(['VueViewer'], function (VueViewer) {});\n```\n\n### Usage of directive\n\nJust add the directive `v-viewer` to any element, then all `img` elements in it will be handled by `viewer`.\n\nYou can set the options like this: `v-viewer=\"{inline: true}\"`\n\nGet the element by selector and then use `el.$viewer` to get the `viewer` instance if you need.\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv class=\"images\" v-viewer=\"{movable: false}\">\n      \u003Cimg v-for=\"src in images\" :src=\"src\" :key=\"src\">\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" @click=\"show\">Show\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003C!-- Options API -->\n\u003Cscript lang=\"ts\">\n  import { defineComponent } from 'vue'\n  import 'viewerjs\u002Fdist\u002Fviewer.css'\n  import { directive as viewer } from \"v-viewer\"\n  export default defineComponent({\n    directives: {\n      viewer: viewer({\n        debug: true\n      })\n    },\n    data() {\n      return {\n        images: [\n          \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n        ]\n      }\n    },\n    methods: {\n      show () {\n        const viewer = this.$el.querySelector('.images').$viewer\n        viewer.show()\n      }\n    }\n  })\n\u003C\u002Fscript>\n\u003C!-- Composition API -->\n\u003C!-- \u003Cscript lang=\"ts\" setup>\n  import 'viewerjs\u002Fdist\u002Fviewer.css'\n  import { directive as viewer } from \"v-viewer\"\n  const vViewer = viewer({\n    debug: true\n  })\n  const images = [\n    \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n  ]\n  const show = () => {\n    const viewer = document.querySelector('.images').$viewer\n    viewer.show()\n  }\n\u003C\u002Fscript> -->\n```\n\n#### Directive modifiers\n\n##### static\n\nThe `viewer` instance will be created only once after the directive binded.\n\nIf you're sure the images inside this element won't change again, use it to avoid unnecessary re-render.\n\n```vue\n\u003Cdiv class=\"images\" v-viewer.static=\"{inline: true}\">\n  \u003Cimg v-for=\"src in images\" :src=\"src\" :key=\"src\">\n\u003C\u002Fdiv>\n```\n\n##### rebuild\n\nThe `viewer` instance will be updated by `update` method when the source images changed (added, removed or sorted) by default.\n\nIf you encounter any display problems, try rebuilding instead of updating.\n\n```vue\n\u003Cdiv class=\"images\" v-viewer.rebuild=\"{inline: true}\">\n  \u003Cimg v-for=\"src in images\" :src=\"src\" :key=\"src\">\n\u003C\u002Fdiv>\n```\n\n### Usage of component\n\nYou can simply import the component and register it locally too.\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cviewer :images=\"images\"\n            @inited=\"inited\"\n            class=\"viewer\"\n            ref=\"viewer\"\n            >\n      \u003Ctemplate #default=\"scope\">\n        \u003Cimg v-for=\"src in scope.images\" :src=\"src\" :key=\"src\">\n        {{scope.options}}\n      \u003C\u002Ftemplate>\n    \u003C\u002Fviewer>\n    \u003Cbutton type=\"button\" @click=\"show\">Show\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003C!-- Options API -->\n\u003Cscript lang=\"ts\">\n  import { defineComponent } from 'vue'\n  import 'viewerjs\u002Fdist\u002Fviewer.css'\n  import { component as Viewer } from \"v-viewer\"\n  export default defineComponent({\n    components: {\n      Viewer,\n    },\n    data() {\n      return {\n        images: [\n          \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n        ]\n      }\n    },\n    methods: {\n      inited (viewer) {\n        this.$viewer = viewer\n      },\n      show () {\n        this.$viewer.show()\n      }\n    }\n  })\n\u003C\u002Fscript>\n\u003C!-- Composition API -->\n\u003C!-- \u003Cscript lang=\"ts\" setup>\n  import 'viewerjs\u002Fdist\u002Fviewer.css'\n  import { component as Viewer } from \"v-viewer\"\n  const images = [\n    \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n  ]\n  let $viewer:any = null\n  const inited = (viewer) => {\n    $viewer = viewer\n  }\n  const show = () => {\n    $viewer.show()\n  }\n\u003C\u002Fscript> -->\n```\n\n#### Component props\n\n##### images\n\n- Type: `Array`\n\n##### trigger\n\n- Type: `Object`\n\nYou can replace `images` with `trigger`, to accept any type of prop.\nwhen the `trigger` changes, the component will re-render the viewer.\n\n```vue\n\u003Cviewer :trigger=\"externallyGeneratedHtmlWithImages\">\n  \u003Cdiv v-html=\"externallyGeneratedHtmlWithImages\"\u002F>\n\u003C\u002Fviewer>\n```\n\n##### rebuild\n\n- Type: `Boolean`\n- Default: `false`\n\nThe viewer instance will be updated by `update` method when the source images changed (added, removed or sorted) by default.\n\nIf you encounter any display problems, try rebuilding instead of updating.\n\n```vue\n\u003Cviewer\n  ref=\"viewer\"\n  :options=\"options\"\n  :images=\"images\"\n  rebuild\n  class=\"viewer\"\n  @inited=\"inited\"\n>\n  \u003Ctemplate #default=\"scope\">\n    \u003Cimg v-for=\"src in scope.images\" :src=\"src\" :key=\"src\">\n    {{scope.options}}\n  \u003C\u002Ftemplate>\n\u003C\u002Fviewer>\n```\n\n#### Component events\n\n##### inited\n\n- viewer: `Viewer`\n\nListen for the `inited` event to get the `viewer` instance, or use `this.refs.xxx.$viewer`.\n\n### Usage of api\n\n> Only available in modal mode.\n\nYou can call the function: `this.$viewerApi({options: {}, images: []})` to show gallery without rendering the `img` elements yourself.\n\nThe function returns the current viewer instance.\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton type=\"button\" class=\"button\" @click=\"previewURL\">URL Array\u003C\u002Fbutton>\n    \u003Cbutton type=\"button\" class=\"button\" @click=\"previewImgObject\">Img-Object Array\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003C!-- Options API -->\n\u003Cscript lang=\"ts\">\n  import { defineComponent } from 'vue'\n  import 'viewerjs\u002Fdist\u002Fviewer.css'\n  import { api as viewerApi } from \"v-viewer\"\n  export default defineComponent({\n    data() {\n      return {\n        sourceImageURLs: [\n          'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=1',\n          'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=2'\n        ],\n        sourceImageObjects: [\n          {\n            'src': 'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=3',\n            'data-source': 'https:\u002F\u002Fpicsum.photos\u002F800\u002F800?random=3'\n          },\n          {\n            'src': 'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=4',\n            'data-source': 'https:\u002F\u002Fpicsum.photos\u002F800\u002F800?random=4'\n          }\n        ]\n      }\n    },\n    methods: {\n      previewURL () {\n        \u002F\u002F If you use the `app.use` full installation, you can use `this.$viewerApi` directly like this\n        const $viewer = this.$viewerApi({\n          images: this.sourceImageURLs\n        })\n      },\n      previewImgObject () {\n        \u002F\u002F Or you can just import the api method and call it.\n        const $viewer = viewerApi({\n          options: {\n            toolbar: true,\n            url: 'data-source',\n            initialViewIndex: 1\n          },\n          images: this.sourceImageObjects\n        })\n      }\n    }\n  })\n\u003C\u002Fscript>\n\u003C!-- Composition API -->\n\u003C!-- \u003Cscript lang=\"ts\" setup>\nimport 'viewerjs\u002Fdist\u002Fviewer.css'\nimport { api as viewerApi } from 'v-viewer'\nconst sourceImageURLs = [\n  'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=1',\n  'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=2'\n]\nconst sourceImageObjects = [\n  {\n    src: 'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=3',\n    'data-source': 'https:\u002F\u002Fpicsum.photos\u002F800\u002F800?random=3'\n  },\n  {\n    src: 'https:\u002F\u002Fpicsum.photos\u002F200\u002F200?random=4',\n    'data-source': 'https:\u002F\u002Fpicsum.photos\u002F800\u002F800?random=4'\n  }\n]\nconst previewURL = () => {\n  \u002F\u002F If you use the `app.use` full installation, you can use `this.$viewerApi` directly like this\n  const $viewer = this.$viewerApi({\n    images: sourceImageURLs\n  })\n}\nconst previewImgObject = () => {\n  \u002F\u002F Or you can just import the api method and call it.\n  const $viewer = viewerApi({\n    options: {\n      toolbar: true,\n      url: 'data-source',\n      initialViewIndex: 1\n    },\n    images: sourceImageObjects\n  })\n}\n\u003C\u002Fscript> -->\n```\n\n## Options & Methods of Viewer\n\nRefer to [viewer.js](https:\u002F\u002Fgithub.com\u002Ffengyuanchen\u002Fviewerjs).\n\n## Plugin options\n\n### name\n\n- Type: `String`\n- Default: `viewer`\n\nIf you need to avoid name conflict, you can import it like this:\n```ts\nimport { createApp } from 'vue'\nimport 'viewerjs\u002Fdist\u002Fviewer.css'\nimport VueViewer from 'v-viewer'\nimport App from '.\u002FApp.vue'\n\nexport const app = createApp(App)\napp.use(VueViewer, {\n  name: 'vuer',\n  debug: true,\n})\napp.mount('#app')\n\n```\n\n```vue\n\u003Ctemplate>\n\u003Cdiv>\n  \u003C!-- directive name -->\n  \u003Cdiv class=\"images\" v-vuer=\"{movable: false}\">\n    \u003Cimg v-for=\"src in images\" :src=\"src\" :key=\"src\">\n  \u003C\u002Fdiv>\n  \u003Cbutton type=\"button\" @click=\"show\">Show\u003C\u002Fbutton>\n  \u003C!-- component name -->\n  \u003Cvuer :images=\"images\">\n    \u003Cimg v-for=\"src in images\" :src=\"src\" :key=\"src\">\n  \u003C\u002Fvuer>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003C!-- Options API -->\n\u003Cscript lang=\"ts\">\n  import { defineComponent } from 'vue'\n  export default defineComponent({\n    data() {\n      return {\n        images: [\n          \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n          \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n        ]\n      };\n    },\n    methods: {\n      show () {\n        \u002F\u002F viewerjs instance name\n        const vuer = this.$el.querySelector('.images').$vuer\n        vuer.show()\n        \u002F\u002F api name\n        this.$vuerApi({\n          images: this.images\n        })\n      }\n    }\n  })\n\u003C\u002Fscript>\n\u003C!-- Composition API -->\n\u003Cscript lang=\"ts\" setup>\n  import { api as vuerApi } from 'v-viewer'\n  const images = [\n    \"https:\u002F\u002Fpicsum.photos\u002F200\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F300\u002F200\",\n    \"https:\u002F\u002Fpicsum.photos\u002F250\u002F200\"\n  ]\n  const show = () => {\n    \u002F\u002F viewerjs instance name\n    const vuer = document.querySelector('.images').$vuer\n    vuer.show()\n    \u002F\u002F api name\n    vuerApi({\n      images\n    })\n  }\n\u003C\u002Fscript>\n```\n\n### defaultOptions\n\n- Type: `Object`\n- Default: `undefined`\n\nIf you need to set the viewer default options, you can import it like this:\n\n```ts\nimport { createApp } from 'vue'\nimport 'viewerjs\u002Fdist\u002Fviewer.css'\nimport VueViewer from 'v-viewer'\nimport App from '.\u002FApp.vue'\n\nexport const app = createApp(App)\napp.use(VueViewer, {\n  defaultOptions: {\n    zIndex: 9999\n  }\n})\napp.mount('#app')\n```\n\nAnd you can reset the default options at any other time:\n\n```javascript\nimport VueViewer from 'v-viewer'\n\nVueViewer.setDefaults({\n  zIndexInline: 2021,\n})\n```\n","v-viewer 是一个基于 Vue 的图片查看器组件，支持旋转、缩放、放大等功能，底层依赖于 viewer.js。该项目提供了丰富的功能，包括但不限于通过指令或组件形式展示图片、自定义工具栏、过滤图片等，并且兼容 Vue 2 和 Vue 3 版本。适用于需要在网页中实现交互式图片浏览的场景，如在线相册、产品展示页面等。其简洁易用的 API 设计使得开发者能够快速集成到现有项目中。",2,"2026-06-11 03:19:39","top_language"]