Introduction to Svelte -- implementing cross framework component reuse with Web Components

Posted by swasheck on Wed, 15 Dec 2021 09:19:33 +0100

Use * * Svelte to develop custom cell components supported by VUE and React * *

In the previous section, we learned how to use Svelte to encapsulate web components to enable the use of spreadsheet components between different pages.

The benefits of cross framework reuse of Svelte encapsulated components are also obvious:

1. Using framework development, it is easier to maintain

2. After publishing, there is no framework dependency, and any other scenario can be used

3. The published Web Component is small in size

These unique advantages make Svelte have special advantages in component packaging. Previously, we learned how to freely use spreadsheet components between different pages. What if you want to really implement the same table components across different frameworks?

Next, we will continue to introduce to you how to cross the framework to make the spreadsheet components available in the native environment and various frameworks after encapsulating the spreadsheet components.

Cross framework component development

1, Developing AutoComplete Web Component using Svelte

Svelte has a rich ecosystem today. We can find an AutoComplete component developed by svelte through search. Address: https://github.com/pstanoev/simple-svelte-autocomplete.

Let's fork this project, make some simple modifications, and let it generate a Web Component (here, we need to pay attention to whether the content of the three-party formation agreement includes running modification and Publishing).

1. Modify Src / simpleautocomplete svelte

Add to the header:

<svelte:options tag="auto-complete" />

At the same time, modify items in the code and add some default information:

  // the list of items  the user can select from
  export let items = [];
  items = ["White", "Red", "Yellow", "Green", "Blue", "Black"];

2. Modify rollup config. js

Configure customElement in plugins

The result after setting is:

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. Run npm run build to package and generate web components

After running, the index. Will be generated in the root directory js and index mjs has two files. js is supported by UMD and mjs is the ES version. Later, we will directly use the index supported by UMD js file.

2, Frameless page test

  <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>


Import the generated index JS create autocompletecelltype and set it to single cell. The effect is shown in the figure:

3, Import is used in Vue framework to import autocomplete web component

<script>
  import  '@grapecity/spread-sheets-vue'
  import '../static/index' // Copy the packaged index JS to the static folder
  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>

Note the packaged index After JS is imported, an error about TS will be reported. Just delete the following contents in the file.

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion

The method is the same in React, so I won't repeat it here.

If you have other ideas and implementation ideas, you are also welcome to comment and exchange.

Topics: Javascript github React Vue.js eslint