本帖最后由 AlexZ 于 2024-10-9 14:19 编辑
在两年前,我写过一篇文章,叫做在Vue3中使用SpreadJS常见问题总结。这里面提到了分别使用SpreadJS,或者Designer的一些问题。但是这两年期间内,越来越多的客户遇到了Vue框架问题,我决定再重新整理一下。
主要问题有:性能慢、白屏、最大堆栈问题、输入内容丢失需要双击显示等。
1、性能慢
同样的代码div id的designer设计器比gc-spread-sheets加载数据慢,是为什么?
【15】项目使用vue3,响应慢的问题
2、白屏
【15.0.5】vue3项目中,addSheet创建的表格,切换后会白屏
【v17】当使用open方法打开sjs文件后,进行预览白屏,切换回编辑模版页面也白屏
3、最大堆栈问题(maximum call stack size exceeded)
【resumeCalcService&calculate 函数vue中执行报错堆栈溢出】
【V17.1.1】 json渲染,显示内存溢出循环引用
4、输入内容丢失
如下动图所示:
5、其他
SpreadJS右键手动删除行后,页面未实时更新
SpreadJS refresh方法延迟
SpreadJS V15 在移动端不能滚动
下拉框内容,选中后不更新
最大的原因是使用了this.designer 或者this.spread 。在一些客户的代码中,频繁调用this.designer 或者this.spread。而SpreadJS组件是一个很复杂的控件,spread实例如果挂载当前的this上,导致spread实例被自动代理,所以,并不建议使用this.designer 或者this.spread。
但是,如果不使用this.designer 或者this.spread,要进行频繁传参,也是不合适的。
那么。怎么办呢?
在SpreadJS中,有一个API叫做findControl。
一、findControl
1、Designer(在线表格编辑器)
如下代码:
- <div id="gc-designer-container" style="width:100%;height:100vh;border:1px solid darkgray">
- var designer = new GC.Spread.Sheets.Designer.Designer(document.getElementById("gc-designer-container"));
- var designer = GC.Spread.Sheets.Designer.findControl(document.getElementById("gc-designer-container"));
复制代码 上述代码中,第一行是定义了一个id为“gc-designer-container”的dom元素。第二行代码,对Designer进行了实例化。第三行代码,我们发现可以通过findControl,传参dom元素来找到designer 对象。
也就是说,我们只需要全局保存dom元素,在其他方法中,如果要使用designer 对象 ,调用GC.Spread.Sheets.Designer.findControl(document.getElementById("gc-designer-container"))即可。
而在第三方框架中,大家也许没有使用上述的dom方式,而是用了这个gc-spread-sheets-designer组件。那么,又该如何处理呢?
- <gc-spread-sheets-designer :styleInfo='styleInfo' @designerInitialized='designerInitialized' id="gc-designer-container">
- </gc-spread-sheets-designer>
复制代码 接下来,在designerInitialized 初始化方法中,我们可以获取designer对象。然后通过getHost()保存其dom元素,将dom元素挂载在this上即可。
参考下面的代码:
- designerInitialized(designer){
- this.designer = designer.getHost()
- this.init()
- },
- init(){
- let designer = GC.Spread.Sheets.Designer.findControl(this.designer)
- let spread = designer.getWorkbook()
-
- },
复制代码 接下来 ,我们看一下,如果不用designer ,光用spread的设置方式。
2、SpreadJS
- <gc-spread-sheets @workbookInitialized="initWorkbook"
- styleInfo='styleInfo' >
- </gc-spread-sheets>
- initWorkbook: function (spread) {
- this.spread = spread.getHost();
- this.initData();
- },
- initData: function () {
- let spread = GC.Spread.Sheets.findControl(this.spread)
- },
复制代码
二、markRaw
如果项目已经开发很久了,上述改造工作量太大了,怎么办呢?
在vue3中,推出了一个markRaw的用法。具体参考这里:https://cn.vuejs.org/api/reactivity-advanced
因为作为vue的component, 只要往component上方一个property,vue就会用proxy把对象包了。这个封装是为了拿到变更后的对象来更新view。
当使用this.spread时,整个spread实例都被包了。不仅干扰到spread自己内部的数据访问。而且会引起一些问题。用markRaw,就是让vue不要包这个对象了,不进行代理。
【注】:此方法仅适用于Vue3。
|