Svelte入门——Web Components实现跨框架组件复用

Posted powertoolsteam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Svelte入门——Web Components实现跨框架组件复用相关的知识,希望对你有一定的参考价值。

Svelte 是构建 Web 应用程序的一种新方法,推出后一直不温不火,没有继Angular、React和VUE成为第四大框架,但也没有失去热度,无人问津。造成这种情况很重要的一个原因是,Svelte 的核心思想在于【通过静态编译减少框架运行时的代码量】,它可以像React和VUE一样开发,但却没有虚拟DOM。,使它可以Svelte可以将代码编译为体积小、不依赖于框架的JS代码。

看起来满满优点,但因为过于灵活,导致大家无法写出高度一致的业务代码,以上优点并没有在实际的大项目中得到很好的体现。

Svelte 这款框架并不完美,却又没有在残酷的市场竞争中死掉,是因为它拥有一本特殊秘籍,一些使它成为其他框架无法替代的一员的功能。。

而对于 Svelte 来说,这本秘籍的名字就叫做——Web Components。

在多团队协同完成的大项目中,各个团队可能使用不同的框架版本,甚至不同的框架,这让不同项目之间的组件复用变得困难。"write one,run anywhere"就是一句空话。这种情况下Svelte就变成了沟通跨越框架鸿沟的桥梁,使用Svelte开发的无框架依赖的Web Components,可以在各个框架间复用。同时,Svelte的开发方式也不像写pure js那样繁琐。

下面以SpreadJS集成为例,介绍如何用Svelte开发一款spread-sheets Web Component供其他页面复用。

  1. 创建Svelte template工程。
    svelte 官方提供了template 工程,只要clone或者下载项目即可。

https://github.com/sveltejs/component-template

npx degit sveltejs/component-template my-new-component
cd my-new-component
npm install # or yarn

  1. 修改 rollup.config.js,添加 customElement: true 配置,输出为web component组件。

添加后的rollup.config.js如下。

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import pkg from './package.json';

const name = pkg.name
        .replace(/^(@\\S+\\/)?(svelte-)?(\\S+)/, '$3')
        .replace(/^\\w/, m => m.toUpperCase())
        .replace(/-\\w/g, m => m[1].toUpperCase());

export default 
        input: 'src/index.js',
        output: [
                 file: pkg.module, 'format': 'es' ,
                 file: pkg.main, 'format': 'umd', name 
        ],
        plugins: [
                svelte(
                        customElement: true,
                ),
                resolve()
        ],
;

  1. 更新 src/Component.svelte,创建spread-sheets组件。
<svelte:options tag="spread-sheets" />
<script>
    import  createEventDispatcher, onMount  from 'svelte';
    // Event handling
    const dispatch = createEventDispatcher();
    export let value ="";
    $: valueChanged(value);
    function valueChanged(newValue) 
      console.log("value changed", newValue);
      if(spread)
        let sheet = spread.getActiveSheet();
        sheet.setValue(0, 0, value);
      
    

    let spreadHost;
    let spread;
    function dispatchEvent(name, e) 
      // dispatch(name, e);
      const event = new CustomEvent(name, 
        detail: e,
        bubbles: true,
        cancelable: true,
        composed: true, // this line allows the event to leave the Shadow DOM
      );
      // console.log(event)
      spreadHost.dispatchEvent(event);
    
      onMount(() => 
          spread = new GC.Spread.Sheets.Workbook(spreadHost);
          let sheet = spread.getActiveSheet();
          sheet.setValue(0, 0, value);
          spread.bind(GC.Spread.Sheets.Events.ValueChanged, function(s, e)
            e.evnetName = "ValueChanged";
            dispatchEvent("changed", e);
          );
          spread.bind(GC.Spread.Sheets.Events.RangeChanged, function(s, e)
            e.evnetName = "RangeChanged";
            dispatchEvent("changed", e);
          );
      );



  </script>
  <style>
      
  </style>
  <div bind:this= spreadHost style="width: 100%; height:100%"></div>

这样我们的自定义组件就创建好了,只需要调用npm run build,就能编译出spread-sheets 组件了。

  1. 在页面引用组件。
    创建index.html页面,并引用编译好的js文件。同时引入spreadjs相关资源。
    直接使用spread-sheets标签添加SpreadJS。
<!doctype html>
<html lang="en">
  <head>
    <meta name="spreadjs culture" content="zh-cn" />
    <meta charset="utf-8" />
    <title>My Counter</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" type="text/css" href="https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/zh/purejs/node_modules/@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
  </head>
  <body>
    <!-- <spread-sheets-designer></spread-sheets-designer> -->
    <button onclick="getJSON()">GetJSON</button>
    <spread-sheets value="123" style="display:block; width: 80%; height: 400px;"></spread-sheets>


    <script src="https://demo.grapecity.com.cn/SpreadJS/WebDesigner/lib/spreadjs/scripts/gc.spread.sheets.all.14.1.3.min.js" type="text/javascript"></script>

    <script type="text/javascript" src="/dist/index.js"></script>
    <script type="text/javascript">

      document.querySelector("spread-sheets").addEventListener("changed", function()
        console.log(arguments)
      )

      window.onload = function()
        document.querySelector("spread-sheets").setAttribute("value", "234");
      

    </script>
  </body>
</html>

添加后效果如下图。

总结

虽然看起来Web Component完美解决了组件之间的复用问题,但是用Svelte 开发的Web Component也存在一些限制:比如,只能传递string 属性;绑定的attribute是单向绑定,想要获取组件内部更新值,需要绑定event获取。

如果大家对Svelte 有更多兴趣,欢迎留言交流~

以上是关于Svelte入门——Web Components实现跨框架组件复用的主要内容,如果未能解决你的问题,请参考以下文章

Svelte入门——Web Components实现跨框架组件复用

Svelte入门——Web Components实现跨框架组件复用

Svelte入门——Web Components实现跨框架组件复用

你问的Svelte来了--静态编译直出DOM独立分发Web Components位掩码变化追踪

你问的Svelte来了--静态编译直出DOM独立分发Web Components位掩码变化追踪

如何在运行时将编译的 svelte-components/-apps 导入 svelte-app