Vue3中使用图片查看组件 支持vue3的图片组件

2022-01-05  本文已影响0人  zhoulh_cn

安装/Installation

npm i vue3-image-viewer
或者/or
yarn add vue3-image-viewer

引入/Import

import { Image } from 'vue3-image-viewer';
import 'vue3-image-viewer/dist/style.css';

使用示例/Example

<template>
  <div class="vue3-image-viewer">
    <section class="image">
      <div class="image-wrap" v-for="(item, index) in images" :key="item.url">
        <Image
          :base="base"
          :src="item.url"
          :token="token"
          :aspectRatio="3 / 4"
          fit="contain"
          lazy
          hideOnClickModal
          :initialIndex="index"
          preview
          :images="images"
          loop
          :preload="[-2, 2]"
          width="220px"
          alt="图片组件测试"
          bgColor="lightpink"
          @error="imageError"
          @load="imageLoad"
          @close="imageClose"
          @switch="ImageSwitch"
        >
          <template v-slot:footer>footer</template>
          <template v-slot:loading>LOADING</template>
          <template v-slot:error>ERROR</template>
        </Image>
      </div>
    </section>
    <section class="viewer">
      <div class="preview">
        <div class="item" v-for="(item, index) in current.marks" :key="index">
          <Viewer
            :base="base"
            :token="token"
            :image="current"
            :mark="item"
            focus
          >
            <template v-slot:loading>LOADING</template>
            <template v-slot:error>ERROR</template>
          </Viewer>
        </div>
      </div>
      <!-- 自定义 -->
      <div class="tools">
        <div @click="toolBtn('fit')">适应窗口</div>
        <div @click="toolBtn('prev')">上一个</div>
        <div @click="toolBtn('next')">下一个</div>
        <div @click="toolBtn('reset')">重置</div>
      </div>
      <div class="viewer-wrap">
        <!-- 如果传入了markList则不取images中的marks -->
        <Viewer
          ref="viewer"
          :base="base"
          :token="token"
          :scaleMax="20"
          :scaleMin="0.1"
          :scaleStep="1.2"
          :initialScale="1"
          :imageList="images"
          :markList="current.marks"
          :initialIndex="currentIndex"
          loop
          navigation
          toolbar
          drawable
          deleteable
          :keyboard="['A', 'D', 'Space', 'Esc']"
          @error="onError"
          @load="onLoad"
          @switch="onSwitch"
          @drawEnd="drawEnd"
          @resize="onResize"
          @delete="onDelete"
          @zoom="onZoom"
        >
          <template v-slot:loading>LOADING</template>
          <template v-slot:error>ERROR</template>
        </Viewer>
      </div>
    </section>
  </div>
</template>

<script setup lang="ts">
import { Image, Viewer } from 'vue3-image-viewer';
import { reactive, ref, computed } from 'vue';
const viewer = ref(null);
const currentIndex = ref(0);
const base = 'https://cube.elemecdn.com/';
const token = 'token';
const images = reactive([
  {
    title: '1',
    desc: 'A',
    url: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
    thumbnail: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
    marks: [
      {
        id: '1',
        left: 0,
        top: 0,
        width: 100,
        height: 100,
      },
      {
        id: '2',
        left: 200,
        top: 200,
        width: 50,
        height: 100,
      },
    ],
  },
  {
    title: '2',
    desc: 'B',
    url: 'd/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
    thumbnail: 'd/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
  },
  {
    title: '3',
    desc: 'C',
    url: '1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg1',
    thumbnail:
      '1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg1',
  },
  {
    title: '4',
    desc: 'B',
    url: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
    thumbnail: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
  },
  {
    title: '5',
    desc: 'B',
    url: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
    thumbnail: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
  },
  {
    title: '6',
    desc: 'B',
    url: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
    thumbnail: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
  },
  {
    title: '7',
    desc: 'B',
    url: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
    thumbnail: 'a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
  },
  {
    title: '8',
    desc: 'B',
    url: '6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg',
    thumbnail: '6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg',
  },
  {
    title: '9',
    desc: 'B',
    url: '9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
    thumbnail: '9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
  },
  {
    title: '10',
    desc: 'B',
    url: '3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
    thumbnail: '3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
  },
]);
const current = computed(() => {
  return images[currentIndex.value];
});

function onError(err) {
  // console.log(err);
}
function onLoad(ev) {
  // console.log(ev);
}
function onSwitch(index) {
  // console.log(index);
  currentIndex.value = index;
}
function drawEnd(item) {
  const { left, top, width, height } = item;
  if (!current.value.marks) {
    current.value.marks = [];
  }
  current.value.marks.push({
    id: current.value.marks.length + 1 + '',
    left,
    top,
    width,
    height,
  });
}
function onResize({ target, detail }) {
  const { left, top, width, height } = detail;
  console.log(left, top, width, height);
  const mark = { ...target };
  mark.left = left;
  mark.top = top;
  mark.width = width;
  mark.height = height;
  const idx = current.value.marks.indexOf(target);
  if (idx > -1) {
    current.value.marks.splice(idx, 1, mark);
  }
}
function onDelete({ target }) {
  const idx = current.value.marks.indexOf(target);
  if (idx > -1) {
    current.value.marks.splice(idx, 1);
  }
}
function onZoom(zoom) {
  // console.log(zoom);
}

function imageError(err) {
  // console.log(err);
}
function imageLoad(ev) {
  // console.log(ev);
}
function imageClose() {
  // console.log('close');
}
function ImageSwitch(idx) {
  // console.log(idx);
}

function toolBtn(type) {
  if (!viewer.value) {
    return;
  }
  if (type === 'fit') {
    viewer.value.toggleFit();
  }
  if (type === 'next') {
    viewer.value.next();
  }
  if (type === 'prev') {
    viewer.value.prev();
  }
  if (type === 'reset') {
    viewer.value.reset();
  }
}
</script>

<style lang="less" scoped>
.vue3-image-viewer {
  .image {
    width: 750px;
    margin: 20px auto;
    padding: 0 10px;
    max-height: 200px;
    overflow-y: auto;
    .image-wrap {
      float: left;
      margin: 10px;
    }
  }
  .viewer {
    margin-bottom: 50px;
    .preview {
      display: flex;
      // flex-wrap: wrap;
      .item {
        width: 200px;
        margin: 10px;
      }
    }
    .tools {
      width: 400px;
      margin: 20px auto;
      display: flex;
      justify-content: space-around;
      div {
        cursor: pointer;
        height: 22px;
        line-height: 22px;
        padding: 0 10px;
        border-radius: 2px;
        background-color: #333;
        color: #fff;
      }
    }
    padding: 0 20px;
    .viewer-wrap {
      width: 100%;
      height: 500px;
    }
  }
}
</style>

Image 组件说明

传参/Props

参数 说明 类型 默认值
base 地址前缀 string ""
src 图片地址 string ""
token token 参数 string ""
aspectRatio 固定宽高比 number 0
fit object-fit string "fill"
lazy 懒加载 boolean false
hideOnClickModal 点击遮罩关闭预览 boolean false
initialIndex 在预览数组中的位置 number 0
preview 是否开启预览 boolean false
images 预览列表 array []
loop 开启循环 boolean false
preload 预览预加载 array or boolean [0,2]
width 盒子宽度 string ""
height 盒子高度 string ""
alt alt string ""
referrerPolicy referrerPolicy string ""
bgColor 背景颜色 string "black"

参数说明/Props Explanation

组件事件/Event

支持插槽/Slot


Viewer 组件说明

传参/Props

参数 说明 类型 默认值
base 地址前缀 string ""
token token 参数 string ""
scaleMax 最大缩放倍数 number 15
scaleMin 最小缩放倍数 number 1
scaleStep 缩放步进 number 1.1
initialScale 初始缩放倍数 number 1
imageList 图片列表 array []
markList 标记框列表 array []
initialIndex 初始展示图片下标 number 0
loop 开启循环 boolean 0
navigation 底部预览条 boolean false
toolbar 工具栏 boolean false
keyboard 开启快捷键 array ['A', 'D']
fit object-fit string "contain"
preload 图片预加载 array or boolean [0,2]
fixed 禁止缩放 boolean false
focus 锁定标记框的展示模式 boolean false
drawable 是否开启标记功能 boolean false
deleteable 是否显示移除标记框的按钮 boolean false
image 单张图片 object null
mark 单个标记框 object null

参数说明/Props Explanation

组件事件/Event

组件方法/Methods

支持插槽/Slot

预览效果/Preview

图片列表
图片预览
绘图
调整大小

补充说明

联系我/Contact me

上一篇 下一篇

猜你喜欢

热点阅读