特性:
- 支持设置初始索引值
- 支持显示标题、日期、大小、当前图片位置
- 支持无限循环切换轮播
- 支持鼠标滑轮滚动、左右键、上下键、PageUp、PageDown、Home、End操作切换图片
- 支持Esc关闭窗口
sgPhotoPlayer源码
<template> <div :class="$options.name" v-if="visible"> <div class="swiper-container"> <el-carousel class="image-swiper" ref="carousel" :initial-index="currentIndex" :autoplay="false" :height="'100%'" :indicator-position="swiperItems.length <= 1 ? 'none' : ''" :arrow="swiperItems.length <= 1 ? 'never' : ''" @change="(idx) => (currentIndex = idx)" > <el-carousel-item v-for="(a, $i) in swiperItems" :key="$i"> <el-image draggable="false" style="width: 600px; height: 400px" :src="a.sm" :preview-src-list="swiperItems.map((v) => v.lg)" :initial-index="$i" :fit="'cover'" > </el-image> </el-carousel-item> </el-carousel> <div class="desc"> <label class="number" >当前位置:{{ currentIndex + 1 }}/{{ swiperItems.length }}</label > <label class="title" :title="`${swiperItems[currentIndex].title}(${swiperItems[currentIndex].size})`" >{{ swiperItems[currentIndex].title }}({{ swiperItems[currentIndex].size }}) </label> <label class="date">{{ swiperItems[currentIndex].date }}</label> </div> </div> <el-tooltip :content="`关闭`" :effect="`light`" :enterable="false" :placement="`top-start`" :popper-class="`sg-el-tooltip`" :transition="`none`" ><el-button class="sg-closeModalBtn" type="primary" icon="el-icon-close" @click="visible = false" circle /> </el-tooltip> <div class="bg" @click="visible = false"></div> </div> </template> <script> export default { name: "sgPhotoPlayer", data() { return { currentIndex: 0, showBigImg: false, loading: false, //是否加载中 visible: false, //是否显示 swiperItems: [ /* { title:`标题`, date:`时间`, size:`文件大小`, sm: "static/img/sm/1.jpg",//小图路径 lg: "static/img/lg/1.jpg",//大图路径 }, */ ], }; }, props: [ "data", "value", //是否显示 ], watch: { value: { handler(d) { this.visible = d; }, deep: true, immediate: true, }, visible(d) { this.$emit("input", d); if (d) { this.$nextTick(() => { this.addEvents(); }); } else { this.removeEvents(); } }, data: { handler(newValue, oldValue) { if (newValue && Object.keys(newValue).length) { this.currentIndex = newValue.currentIndex; //默认显示的图片索引 this.swiperItems = newValue.photos; } }, deep: true, //深度监听 immediate: true, //立即执行 }, }, mounted() {}, destroyed() { this.removeEvents(); }, methods: { addEvents(d) { this.removeEvents(); addEventListener("mousewheel", this.mousewheel); addEventListener("keydown", this.keydown); addEventListener("keyup", this.keyup); }, removeEvents(d) { removeEventListener("mousewheel", this.mousewheel); removeEventListener("keydown", this.keydown); removeEventListener("keyup", this.keyup); }, mousewheel(e) { this.showBigImg = Boolean(document.querySelector(`.el-image-viewer__mask`)); if (this.showBigImg) return; if (e.deltaY < 0) return this.$refs.carousel.prev(); if (e.deltaY > 0) return this.$refs.carousel.next(); }, keydown(e) { let key = e.key.toLocaleLowerCase(); if ( [ "escape", "home", "end", "pageup", "arrowup", "arrowleft", "pagedown", "arrowdown", "arrowright", ].includes(key) ) { e.preventDefault(); return false; } }, keyup(e) { this.showBigImg = Boolean(document.querySelector(`.el-image-viewer__mask`)); let key = e.key.toLocaleLowerCase(); if ( ["escape", "home", "end", "pageup", "arrowup", "pagedown", "arrowdown"].includes( key ) && this.showBigImg ) return; switch (key) { case "escape": this.visible = false; break; case "home": this.$refs.carousel.setActiveItem(0); break; case "end": this.$refs.carousel.setActiveItem(this.swiperItems.length - 1); break; case "pageup": case "arrowup": case "arrowleft": this.$refs.carousel.prev(); break; case "pagedown": case "arrowdown": case "arrowright": this.$refs.carousel.next(); break; } }, }, }; </script> <style lang="scss" scoped> .sgPhotoPlayer { position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 2000; display: flex; justify-content: center; align-items: center; .swiper-container { position: absolute; width: 600px; height: 450px; margin: auto; top: 0; left: 0; right: 0; bottom: 0; >>> .image-swiper { width: 100%; height: 100%; overflow: hidden; .el-carousel__indicators { bottom: revert; top: 400px; margin-top: 10px; display: flex; justify-content: center; flex-wrap: wrap; width: 100%; li { padding: 2px; } } .el-carousel__container { margin-top: -30px; .el-carousel__arrow, .el-carousel__item { transition: 0.382s !important; } .el-carousel__arrow { // transform: translateY(-40px); } .el-carousel__item { display: flex; justify-content: center; flex-direction: column; } } } .desc { width: 100%; display: flex; justify-content: space-between; align-items: center; flex-wrap: nowrap; box-sizing: border-box; margin: auto; /*文本阴影*/ color: white; text-shadow: 1px 1px 1px black; line-height: 1.6; & > * { font-family: "Microsoft YaHei", "DIN-Light"; font-weight: normal; font-size: 14px !important; white-space: nowrap; /*单行省略号*/ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .number { flex-shrink: 0; width: 140px; } .title { box-sizing: border-box; padding: 0 10px; } .date { flex-shrink: 0; width: 140px; } } } .bg { background-color: #000000cc; width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: -1; } } </style>
应用
// 打开图片 openPhoto(d) { this.photoData= { currentIndex: this.photos.findIndex((v) => v.ID == d.ID), //当前图片索引值 photos: this.photos.map((v) => ({ sm: v.smURL,//小图路径 lg: v.lgURL,//大图路径 title: this.$g.getFileFullName(v),//标题 date: v.GXSJ,//时间 size: this.$g.getFileSize(v),//文件大小 })), }; this.showPhotoPlayer = true; },
基于elment-UI的el-carousel和el-image组件