使用 Vue中extends选项 扩展 Element image-viewer 组件
背景
有一天,领导和我说,在使用 table 表格展示图片记录的基础上加上以下功能:
- 当点击单元格图片项时,在图片预览的时候将图片的编号加上
- 按下键盘上下键时,切换不同的图片记录项
- 按下键盘左右键时,切换当前图片记录项的图片 内心:啊这,领导你知道我们使用的是 element 的组件么,提供的组件根本没这功能啊,是想让我自己实现一个么.... 啊这,还是学习看看有没有啥方法能改写 element 组件更快吧.....
实现思路
- 点击图片时,生成并添加图片编号至预览界面
- 使用
extends
扩展image-viewer
组件,重写方法覆盖image-viewer
监听键盘按下上下按键事件方法 - 监听键盘按下上下按键事件,更换正确的图片预览地址数组数据
实现过程中遇到的问题
- 问题: 当上一记录存在多张图片且切换到了该记录的第二张图片以后,再切换到下一记录时,组件会报错找不到元素
- 原因:
image-viewer
组件中的index
未正确设置 - 解决办法: 在
CustomerImageViewer
当预览地址发生改变时,改变index
的值
watch: {
urlList(){
this.index = 0;
}
},
总结
主要用了 vue
中 extends
选项来继承另外一个组件,然后重写该内部的方法,以达成我们自己的需求。在继承组件时,需要将该组件引入的依赖一并引入
代码实现
CustomerImageViewer.vue
import ElImageViewer from 'element-ui/packages/image/src/image-viewer';
import { on, off } from 'element-ui/src/utils/dom';
import { rafThrottle, isFirefox } from 'element-ui/src/utils/util';
import { PopupManager } from 'element-ui/src/utils/popup';
const mousewheelEventName = isFirefox() ? 'DOMMouseScroll' : 'mousewheel';
export default {
name: 'Customer-image-viewer',
extends: ElImageViewer,
watch: {
urlList(){
this.index = 0;
}
},
methods: {
deviceSupportInstall() {
this._keyDownHandler = e => {
e.stopPropagation();
const keyCode = e.keyCode;
switch (keyCode) {
// ESC
case 27:
this.hide();
break;
// SPACE
case 32:
this.toggleMode();
break;
// LEFT_ARROW
case 37:
this.prev();
break;
// RIGHT_ARROW
case 39:
this.next();
break;
}
};
this._mouseWheelHandler = rafThrottle(e => {
const delta = e.wheelDelta ? e.wheelDelta : -e.detail;
if (delta > 0) {
this.handleActions('zoomIn', {
zoomRate: 0.015,
enableTransition: false
});
} else {
this.handleActions('zoomOut', {
zoomRate: 0.015,
enableTransition: false
});
}
});
on(document, 'keydown', this._keyDownHandler);
on(document, mousewheelEventName, this._mouseWheelHandler);
},
},
};
Table.vue
<template>
<div class="view-page">
<div class="view-body">
<el-table :data="dataList">
...
<el-table-column label="图片" width="100" align="center">
<template slot-scope="{ row }">
<el-image @click="imgClickHandle(row)" :src="row.cover" style="width: 40px; height: 40px;cursor: pointer" ></el-image>
</template>
</el-table-column>
</el-table>
<customer-image-viewer
ref="imgViewer"
v-if="showViewer"
:initial-index="initialIndex"
:on-close="onClose"
:url-list="previewSrcList"
/>
</div>
</div>
</template>
<script>
import { getDataList } from '@/service';
import CustomerImageViewer from '@components/Customer-image-viewer';
export default {
name: 'TableList',
components: { CustomerImageViewer},
data() {
return {
dataList: [],
previewSrcList: [],
showViewer: false,
initialIndex: 0,
divDom: null,
indexMap: {},
// 用来记录选中了哪一记录的 index, 用于查询
imgIndex: 0
};
},
created() {
document.addEventListener('keyup', this.handleKeyup);
},
mounted(){
this.loadDataList();
},
methods: {
// 键盘监听事件
handleKeyup(event){
const e = event ;
if (!e) return;
const { key, keyCode } = e;
switch (keyCode) {
// UP_ARROW
case 38:
this.imgIndex = this.imgIndex > 0 ? (this.imgIndex - 1) : (this.dataList.length - 1) ;
break;
// DOWN_ARROW
case 40:
this.imgIndex = this.imgIndex < this.dataList.length - 1 ? (this.imgIndex + 1) : 0 ;
}
const no = this.dataList[this.imgIndex].no;
this.divDom && (this.divDom.innerText = '编号:' + no);
this.previewSrcList = this.indexMap[this.imgIndex];
},
async loadDataList() {
const res = await getDataList();
if (!res) return;
const list = res.list || [];
list.map((item, index) => item.index = index);
this.dataList = list;
const indexMap = {};
list.forEach((item, index) => {
indexMap[index] = item.photos;
});
this.indexMap = indexMap;
},
imgClickHandle({ index, no }){
this.showViewer = true;
this.imgIndex = index;
// 获取图片预览地址
this.previewSrcList = this.indexMap[index];
this.$nextTick(() => {
// 生成并添加图片编号至预览界面
const divDom = document.createElement('div');
const parentDom = document.getElementsByClassName('el-image-viewer__wrapper')[0];
divDom.innerText = '编号:' + no;
divDom.className = 'no-class';
parentDom.appendChild(divDom);
this.divDom = divDom;
});
},
// 关闭图片预览
onClose() {
this.showViewer = false;
this.divDom = null;
},
},
destroyed() {
document.removeEventListener('keyup', this.handleKeyup);
}
};
</script>
完结撒花
转载自:https://juejin.cn/post/7100845825122631687