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供其他页面复用。
- 创建Svelte template工程。
svelte 官方提供了template 工程,只要clone或者下载项目即可。
https://域名/sveltejs/component-template
npx degit sveltejs/component-template my-new-component
cd my-new-component
npm install # or yarn
- 修改 域名,添加 customElement: true 配置,输出为web component组件。
添加后的域名如下。
import svelte from \'rollup-plugin-svelte\';
import resolve from \'@rollup/plugin-node-resolve\';
import pkg from \'./域名\';
const name = 域名
.replace(/^(@\S+\/)?(svelte-)?(\S+)/, \'$3\')
.replace(/^\w/, m => 域名perCase())
.replace(/-\w/g, m => m[1].toUpperCase());
export default {
input: \'src/域名\',
output: [
{ file: 域名le, \'format\': \'es\' },
{ file: 域名, \'format\': \'umd\', name }
],
plugins: [
svelte({
customElement: true,
}),
resolve()
],
};
- 更新 src/域名te,创建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) {
域名("value changed", newValue);
if(spread){
let sheet = 域名ctiveSheet();
域名alue(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
});
// 域名(event)
域名atchEvent(event);
}
onMount(() => {
spread = new 域名域名book(spreadHost);
let sheet = 域名ctiveSheet();
域名alue(0, 0, value);
域名(域名域名eChanged, function(s, e){
域名tName = "ValueChanged";
dispatchEvent("changed", e);
});
域名(域名域名eChanged, function(s, e){
域名tName = "RangeChanged";
dispatchEvent("changed", e);
});
});
</script>
<style>
</style>
<div bind:this={ spreadHost} style="width: 100%; height:100%"></div>
这样我们的自定义组件就创建好了,只需要调用npm run build,就能编译出spread-sheets 组件了。
- 在页面引用组件。
创建域名页面,并引用编译好的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://域名.cn/spreadjs/SpreadJSTutorial/zh/purejs/node_modules/@grapecity/spread-sheets/styles/域名域名">
</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://域名.cn/SpreadJS/WebDesigner/lib/spreadjs/scripts/域名域名.域名.js" type="text/javascript"></script>
<script type="text/javascript" src="/dist/域名"></script>
<script type="text/javascript">
域名ySelector("spread-sheets").addEventListener("changed", function(){
域名(arguments)
})
域名ad = function(){
域名ySelector("spread-sheets").setAttribute("value", "234");
}
</script>
</body>
</html>
添加后效果如下图。
总结
虽然看起来Web Component完美解决了组件之间的复用问题,但是用Svelte 开发的Web Component也存在一些限制:比如,只能传递string 属性;绑定的attribute是单向绑定,想要获取组件内部更新值,需要绑定event获取。
如果大家对Svelte 有更多兴趣,欢迎留言交流~