Vue.js中Fabric.js对象重渲染异常问题求助
Vue2 + Fabric.js 点击画布时房间颜色随机切换问题的解决方案
问题根源分析
rooms数组监听缺失深度配置:父组件修改房间available属性时,默认浅监听无法触发更新;点击操作可能间接导致数组引用变化,触发loadJson时数据处于不一致状态。- 房间ID类型不匹配:Fabric对象的
room_id与rooms数组的id可能存在类型差异(如字符串/数字),导致匹配失败,错误设置不可用颜色。 - 无效渲染代码:
canvas.renderAll.bind(canvas)仅绑定上下文未执行,无法完成正确渲染。 - 全局
canvas变量冲突:全局变量可能在组件重渲染时残留旧状态或事件绑定。 loadJson意外触发:点击操作可能间接触发rooms监听,导致画布重复加载时数据未同步。
修复步骤
1. 修正rooms监听配置
开启深度监听与初始执行,确保数组内部属性变化和组件初始化时都能触发画布更新:
watch: { // 保留原有其他监听 rooms: { handler() { this.loadJson(this.jsonData); }, deep: true, // 监听数组内部元素属性变化 immediate: true // 组件初始化时执行一次 } }
2. 统一房间ID匹配类型
避免因类型差异导致匹配失败,统一转为字符串后再查找:
modifyObject(room) { // 保留原有代码 if (!isEmpty(room.room_id)) { const targetRoomId = String(room.room_id); const actualRoom = (this.rooms || []).find(item => String(item.id) === targetRoomId); room.set('fill', actualRoom && actualRoom.available ? availableColorOpacity : unavailableColorOpacity); // 保留原有事件绑定代码 } }
3. 修复画布渲染逻辑
移除无效的bind调用,修正未定义的room变量错误:
loadJson(jsonObj) { if (this.canvas) { this.canvas.loadFromJSON(jsonObj, () => { this.canvas.renderAll(); const objects = this.canvas.getObjects(); objects.forEach(object => this.modifyObject(object)); if (this.canvas.editor && this.canvas.editor.editorWorkspace) { // 替换未定义的room变量,使用画布自身尺寸 this.canvas.editor.editorWorkspace.setSize(this.canvas.width, this.canvas.height); this.canvas.editor.editorWorkspace.endDragging(); } this.canvas.renderAll(); }); } }
4. 将全局canvas改为组件实例属性
避免全局变量冲突,将画布实例挂载到组件内部:
// 移除全局let canvas = {} data() { return { // 保留原有数据 canvas: null }; }, mounted() { if (this.jsonData) { this.canvas = new fabric.Canvas('canvas', { selection: false, isDrawingMode: false, hoverCursor: 'default', width: 1700, height: 760 }); event.init(this.canvas); this.canvas.editor = new Editor(this.canvas); this.canvas.renderAll(); this.loadJson(this.jsonData); } }, // 所有用到canvas的地方替换为this.canvas(如watch、openTooltip等方法)
5. 确保事件绑定不重复
绑定mousedown事件前先移除旧绑定,避免多次触发逻辑:
modifyObject(room) { // 保留原有代码 if (!isEmpty(room.room_id)) { // 先移除所有mousedown事件 room.off('mousedown'); room.on('mousedown', () => this.mouseDown(room)); // 保留原有颜色设置代码 } }
总结
以上修改通过修正监听逻辑、统一数据类型、修复渲染代码、避免全局变量冲突四个核心方向,解决点击时房间颜色随机切换的问题,确保房间颜色仅在rooms数组数据变化时更新。
内容的提问来源于stack exchange,提问作者Mustafa Essa
相关产品推荐
相关产品推荐

