You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中Fabric.js对象重渲染异常问题求助

Vue2 + Fabric.js 点击画布时房间颜色随机切换问题的解决方案

问题根源分析

  1. rooms数组监听缺失深度配置:父组件修改房间available属性时,默认浅监听无法触发更新;点击操作可能间接导致数组引用变化,触发loadJson时数据处于不一致状态。
  2. 房间ID类型不匹配:Fabric对象的room_id与rooms数组的id可能存在类型差异(如字符串/数字),导致匹配失败,错误设置不可用颜色。
  3. 无效渲染代码:canvas.renderAll.bind(canvas)仅绑定上下文未执行,无法完成正确渲染。
  4. 全局canvas变量冲突:全局变量可能在组件重渲染时残留旧状态或事件绑定。
  5. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:05:57