vue3 reactive 与 fabric之间爆发的疑难杂症

359 阅读2分钟

概要

最近在做一个设计器项目,因为与canvas交互很多,因此考虑后,打算使用vue3+vite+js的形式去做,使用js是因为自己原生js比较熟练,操作dom、操作canvas比较擅长;

因为要频繁操作canvas,所以使用的是fabric.js这个库,但今天发现了第一个疑难杂症bug;

先上代码吧:

let testWork = reactive({})

const testInit = () =>{
    testWork = new fabric.Canvas("designer-main", {
        backgroundColor: 'rgb(240,240,240)',
   
    });


    console.log('testWork',testWork)


    testWork.setWidth(500);
    testWork.setHeight(500);

    // 使用 IText,可编辑文本
    var text = new fabric.IText(
        '疑难杂症',
        {
            top:300,
            left:125,
            fontSize:35,
            fontFamily: 'Comic Sans'
        }
    )
    testWork.add(text);


}

此时打印出来的数据是这样的:

image.png

最终的效果是这样的;

image.png

选择的canvas块可以放大缩小、旋转、删除等等操作;

如果仅仅如此,vue3的reactive与fabric没有太大问题;

但,一个设计器不可能只有一个canvas对象,所以要使用多个canvas对象,就需要给testWork加上id,改一下代码:

let testWork = reactive({})

const testInit = () =>{
    testWork['id'] = new fabric.Canvas('designer-main', {
        backgroundColor: 'rgb(240,240,240)',
        includeDefaultValues: false,// 指示toObject/toDatalessObject是否应该包含默认值,如果设置为false,则优先于对象值
        perPixelTargetFind: true, //这一句说明选中的时候以图形的实际大小来选择而不是以边框来选择
        hasBorders: false,
    });


    console.log('testWork',testWork['id'])


    testWork['id'].setWidth(500);
    testWork['id'].setHeight(500);

    // 使用 IText,可编辑文本
    var text = new fabric.IText(
        '疑难杂症',
        {
            top:300,
            left:125,
            fontSize:35,
            fontFamily: 'Comic Sans'
        }
    )
    testWork['id'].add(text);


}

打印出来的数据:

image.png

class上面,多了一个Reactive;

然后就出bug了,渲染没有任何问题,但是放大缩小、旋转、删除等等操作全部失效;

然后找到当前渲染的canvas文字,数据格式是这样的:

image.png

canvas中也加上了Reactive;

虽然不知道为什么会这样,但一定是跟vue3的reactive有关,如果使用let testWork = reactive({}),然后使用testWork[id]去接收fabric,暂时没有解决办法;

替代方案,将testWork设置成全局变量,比如挂在到window上即可;