使用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]