面试题答案
一键面试事件监听
- 鼠标事件监听:在Vue的模板中,通过
@mousedown
、@mousemove
和@mouseup
指令来监听鼠标的按下、移动和松开事件。
<template>
<div @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp"></div>
</template>
- 键盘事件监听:使用
@keydown
指令来监听键盘事件,并结合event.ctrlKey
和event.key === 'z'
判断是否是Ctrl + Z
快捷键。
<template>
<div @keydown="handleKeyDown"></div>
</template>
处理逻辑
- 绘图逻辑:
handleMouseDown
中记录起始坐标,并开始一个绘制状态。handleMouseMove
在绘制状态下根据当前坐标和起始坐标绘制图形(可以是线条等)。handleMouseUp
结束绘制状态,并将绘制的图形保存到一个数组中,用于后续的撤销操作。
export default {
data() {
return {
isDrawing: false,
startX: 0,
startY: 0,
drawings: []
};
},
methods: {
handleMouseDown(event) {
this.isDrawing = true;
this.startX = event.offsetX;
this.startY = event.offsetY;
},
handleMouseMove(event) {
if (this.isDrawing) {
// 这里可以调用实际的绘图函数,如drawLine(this.startX, this.startY, event.offsetX, event.offsetY)
}
},
handleMouseUp() {
this.isDrawing = false;
// 假设这里有一个函数getCurrentDrawing获取当前绘制的图形
const drawing = getCurrentDrawing();
this.drawings.push(drawing);
}
}
};
- 撤销逻辑:
handleKeyDown
中判断是Ctrl + Z
快捷键时,从drawings
数组中移除最后一个绘制的图形,并重新绘制画布。
export default {
methods: {
handleKeyDown(event) {
if (event.ctrlKey && event.key === 'z') {
if (this.drawings.length > 0) {
this.drawings.pop();
// 重新绘制画布的函数,如redrawCanvas(this.drawings)
}
}
}
}
};
性能优化
- 防抖与节流:
- 对于
@mousemove
事件,由于其触发频率很高,可以使用节流(throttle)技术,确保在一定时间间隔内只执行一次绘图逻辑,减少不必要的计算。 - 例如使用
lodash
的throttle
函数:
- 对于
import throttle from 'lodash/throttle';
export default {
data() {
return {
// 其他数据...
throttledHandleMouseMove: null
};
},
created() {
this.throttledHandleMouseMove = throttle(this.handleMouseMove, 50);
},
methods: {
handleMouseMove(event) {
if (this.isDrawing) {
// 实际绘图逻辑
}
}
},
beforeDestroy() {
this.throttledHandleMouseMove.cancel();
}
};
- 批量操作:
- 在撤销操作时,不要每次都立即重新绘制整个画布,而是将多个撤销操作合并,在合适的时机一次性重新绘制。可以设置一个队列,当撤销操作触发时,先将操作放入队列,然后在队列达到一定数量或者一定时间间隔后,再统一执行重新绘制操作。
- 使用Web Worker(可选):
- 如果绘图操作非常复杂,占用大量CPU资源,可以考虑使用Web Worker将部分计算密集型任务放到后台线程执行,避免阻塞主线程,提高应用的响应性。
通过上述事件处理架构、处理逻辑以及性能优化措施,可以使复杂的绘图应用在高并发操作下保持良好的性能和响应。