找回密码
 立即注册

QQ登录

只需一步,快速开始

Ellia.Duan SpreadJS 开发认证
超级版主   /  发表于:2024-9-13 14:48  /   查看:570  /  回复:0
本帖最后由 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、输入内容丢失
如下动图所示:
spreadjs.gif

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(在线表格编辑器)
如下代码:

  1. <div id="gc-designer-container" style="width:100%;height:100vh;border:1px solid darkgray">
  2. var designer = new GC.Spread.Sheets.Designer.Designer(document.getElementById("gc-designer-container"));
  3. 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组件。那么,又该如何处理呢?
  1.     <gc-spread-sheets-designer :styleInfo='styleInfo' @designerInitialized='designerInitialized' id="gc-designer-container">
  2.     </gc-spread-sheets-designer>
复制代码
接下来,在designerInitialized 初始化方法中,我们可以获取designer对象。然后通过getHost()保存其dom元素,将dom元素挂载在this上即可。
参考下面的代码:

  1.     designerInitialized(designer){
  2.       this.designer = designer.getHost()
  3.       this.init()
  4.     },

  5.     init(){
  6.       let designer = GC.Spread.Sheets.Designer.findControl(this.designer)
  7.       let spread = designer.getWorkbook()
  8.       
  9.     },
复制代码
接下来 ,我们看一下,如果不用designer  ,光用spread的设置方式。
2、SpreadJS

  1. <gc-spread-sheets @workbookInitialized="initWorkbook"
  2.                         styleInfo='styleInfo' >
  3.         </gc-spread-sheets>
  4.   initWorkbook: function (spread) {
  5.       this.spread = spread.getHost();
  6.       this.initData();
  7.     },

  8. initData: function () {
  9.       let spread = GC.Spread.Sheets.findControl(this.spread)
  10.     },
复制代码

二、markRaw
如果项目已经开发很久了,上述改造工作量太大了,怎么办呢?
在vue3中,推出了一个markRaw的用法。具体参考这里:https://cn.vuejs.org/api/reactivity-advanced


因为作为vue的component, 只要往component上方一个property,vue就会用proxy把对象包了。这个封装是为了拿到变更后的对象来更新view。
当使用this.spread时,整个spread实例都被包了。不仅干扰到spread自己内部的数据访问。而且会引起一些问题。
用markRaw,就是让vue不要包这个对象了,不进行代理。

【注】:此方法仅适用于Vue3。











0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部