dexteryao 发表于 2021-9-15 11:56:35

使用Svelte开发VUE和React都支持的SpreadJS自定义单元格

之前有介绍过Svelte这个框架以及如何在Svelte中使用SpreadJS,通过Svelte封装的Web Component可以跨框架使用。SpreadJS提供了自定义单元格的功能,双击单元格就进入了编辑状态,通过编辑状态中提供的DOM编辑元素,可以接受用户录入比如官方示例中FirstName和LastName分开录入的示例。
我们也提供了很多集成第三方组件的自定义单元格示例,例如很常用的AutoComplete自动提示下拉框,但是这个autoComplete使用了JQuery,对于VUE和React等框架用户,并不愿意引入Jquery这个古老的东西。同样,由于生命周期的问题,框架提供的组件无法在自定义单元格的生命周期里直接使用。
因此,使用Svelte生成的Web Component成了一个不错的选择
1. 使用框架开发,相率高可维护性好
2. 发布后没有框架依赖,其他任何场景都可以使用
3. 发布的Web Component体积小

下面就介绍下如何使用Svelte开发一个VUE和React都框架下可以使用的SpreadJS 自定义单元格。
一. 使用Svelte开发ActoComplete Web Component
    Svelte的生态现在也已经丰富起来了,通过搜索我找到了一款Svelte开发的ActoComplete组件,https://github.com/pstanoev/simple-svelte-autocomplete,我们会fork这个项目,做一些修改,让他生成一个Web Component出来(这里大家一定要注意三方组建的协议,是否运行修改发布)。
    Svelte对发布Web Component提供了很好的支持,这里我们只需要修改两个地方便完成了第一步工作。
1. 修改src/SimpleAutocomplete.svelte
在头部添加:
<svelte:options tag="auto-complete" />
同时在代码中修改items添加一些默认信息
// the list of itemsthe user can select from
export let items = [];
items = ["White", "Red", "Yellow", "Green", "Blue", "Black"];

2. 修改rollup.config.js
在plugins中配置customElement
设置后的结果为:
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import svelte from 'rollup-plugin-svelte';
import pkg from './package.json';

export default [
{
    input: 'src/SimpleAutocomplete.svelte',
    output: [
      { file: pkg.module, format: 'es' },
      { file: pkg.main, format: 'umd', name: 'Autocomplete' }
    ],
    plugins: [svelte({
                        customElement: true,
                }), commonjs(), resolve()]
}
];3. 运行npm run build打包生成Web Component
运行后会在根目录生成index.js和index.mjs两个文件,js是umd的支持,mjs是ES版本,后面我们直接使用UMD支持的index.js文件。

二. 无框架页面测试。


    <div id="ss" style="height: 600px;"></div>
    <script type="text/javascript" src="index.js"></script>

    <script type="text/javascript">
      window.onload = function(){
      var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
      var sheet = spread.getActiveSheet();
      sheet.setCellType(1, 1, new AutoComplateCellType())
      }

      function AutoComplateCellType() {
      }
      AutoComplateCellType.prototype = new GC.Spread.Sheets.CellTypes.Base();
      AutoComplateCellType.prototype.createEditorElement = function () {
          var ac = document.createElement('auto-complete');
          ac.setAttribute("gcUIElement", "gcEditingInput");
          return ac;
      }
      AutoComplateCellType.prototype.updateEditor = function(editorContext, cellStyle, cellRect) {
            if (editorContext) {
                editorContext.style.width=cellRect.width;
                editorContext.style.height=32;
                editorContext.parentElement.parentElement.style.overflow = "visible";
                return {height: 32};
            }
      };
      AutoComplateCellType.prototype.getEditorValue = function (editorContext) {
            if (editorContext) {
                return editorContext.value;
            }
      };
      AutoComplateCellType.prototype.setEditorValue = function (editorContext, value) {
            if (editorContext) {
            editorContext.value = value
            }
      };
    </script>

引入生成的index.js 创建AutoComplateCellType,设置到单于格中,效果如图:

三. Vue框架中使用
通过import的方式引入autocomlate Web Component
<script>
import'@grapecity/spread-sheets-vue'
import '../static/index' // 复制打包的index.js到static文件夹下
import * as GC from "@grapecity/spread-sheets"

      function AutoComplateCellType() {
      }
      AutoComplateCellType.prototype = new GC.Spread.Sheets.CellTypes.Base();
      AutoComplateCellType.prototype.createEditorElement = function () {
          var ac = document.createElement('auto-complete');
          ac.setAttribute("gcUIElement", "gcEditingInput");
          return ac;
      }
      AutoComplateCellType.prototype.updateEditor = function(editorContext, cellStyle, cellRect) {
            if (editorContext) {
                editorContext.style.width=cellRect.width;
                editorContext.style.height=32;
                editorContext.parentElement.parentElement.style.overflow = "visible";
                return {height: 32};
            }
      };
      AutoComplateCellType.prototype.getEditorValue = function (editorContext) {
            if (editorContext) {
                return editorContext.value;
            }
      };
      AutoComplateCellType.prototype.setEditorValue = function (editorContext, value) {
            if (editorContext) {
            editorContext.value = value
            }
      };

export default {
//    name: 'sample-header'
    methods:{
      workbookInitialized(spread){
      var sheet = spread.getActiveSheet();
      sheet.setCellType(1, 1, new AutoComplateCellType())
      }
    }
}


</script>

这里注意打包的index.js 引入后会报一个关于ts的错误,删除文件中 一下内容即可。
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
在React中方式相同,这里就不赘述了。


页: [1]
查看完整版本: 使用Svelte开发VUE和React都支持的SpreadJS自定义单元格