基于viewer图片组件的需求解决过程记录
原来系统中的图片预览使用了这个开源组件:v-viewer
现在有个需求要在图片的浏览过程中删除这些图片,那么能想到就是在 viewer 的操作栏中添加一个删除按钮,点击删除按钮后,删除当前图片。

刚开始想到的是去修改组件的源码,但是这样做的话,后期跑路其他怨种接手我的代码就会出问题,所以就想到了使用最原始的方法来实现这个需求,就是手动创建一个按钮元素,然后添加到 viewer
的操作栏中。
那么就涉及到一个新的问题,什么时候去执行这个逻辑呢?一个是添加按钮,另外一个就是给按钮绑定点击事件,去执行业务逻辑,还有既然我们要删除这个元素,就要知道目前操作的是哪张照片,这是后端大哥说你传给我图片的地址就行了。
因为v-viewer
组件是基于viewer.js
的,所以可以去看一下 viewer.js`的文档,看看有没有什么事件可以使用,
一个ready
事件,当查看器实例准备好进行查看时会触发此事件,还有一个view
事件,当用户开始查看图像时会触发此事件,完美符合上述我们的需求。
看下具体实现吧,我在全局引入使用该组件的东西
<template>
<div
v-viewer="{ toolbar: true, navbar: false, title: false }"
class="images"
ref="images"
@ready="handleReady"
@view="handleView"
>
<img v-for="src in images" :key="src" :src="src" />
</div>
</template>
<script>
export default {
name: 'Viewer',
data() {
return {
images: [
'https://picsum.photos/200/200',
'https://picsum.photos/300/200',
'https://picsum.photos/250/200',
],
}
},
methods: {
createDOMElement(htmlString) {
const parser = new DOMParser()
const parsedDocument = parser.parseFromString(htmlString, 'text/html')
return parsedDocument.body.firstChild
},
handleReady() {
const toolBar = document.querySelector('.viewer-toolbar ul')
const htmlStr =
'<li class="deleteImg" style="display:flex;align-items:center;justify-content:center;"><i style="color:white;font-size:14px;">X</i></li>'
toolBar.appendChild(this.createDOMElement(htmlStr))
const deleteImg = document.querySelector('.viewer-toolbar ul .deleteImg')
deleteImg.addEventListener('click', () => {
console.log('delete')
})
},
handleView(e) {
console.log(e.detail.image.src) // 打印图片地址
},
},
}
</script>
<style scoped></style>
效果如下,点击按钮触发了事件,写业务代码就完了

在不影响第三方组件源代码、不影响组件整体样式风格的情况下,完美解决了这个需求!

需要注意的一点是如果使用组件模式,上面的两个事件是无法使用的,看了源代码,它实现的组件没有这两个自定义事件。只有一个inited
,调用时机应该和ready
差不多,需求已经实现就不折腾了。
如果涉及到多数据源的问题,指令模式就很棘手,因为只要数据源发生变化,v-viewer
组件就会重建,它就会调到第一张,很早之前做过这个需求,就是让它保持在当前浏览的图片上,使用的就是组件模式+多数据源,点击图片在更新数据源。但如果使用指令只能使用单一数据源,做这种需求很麻烦,暂时还未想到比较好的解决方案。