使用Svelte来构建Web Component (超简单方便)
来源 | OSCHINA 社区
译者 | 红薯
文章链接:https://my.oschina.net/javayou/blog/5609297
什么是 Web Component?
<style>
/* CSS code for our navbar */
</style>
<navbar>
<!-- Some long code for our navbar -->
</navbar>
什么是 Shadow DOM?
构建 Web Component
准备工作
对 HTML, CSS 和 JavaScript 有基本的认识
熟悉命令行操作环境
需要一个文本编辑器
最好对 Svelte 有一些基本的了解(可以看看我之前翻译的文章 https://my.oschina.net/javayou/blog/5309554 )
开始
第一个组件是一个卡片组件,接收三个属性分别是:卡片标题、卡片描述以及图片,该组件名为
<my-card />
第二个组件是一个带样式的按钮,接收一个
type
的属性,通过该属性来确定按钮的显示样式,组件名称为<cool-button />
npx degit sveltejs/template web-component-tut
cd web-component-tut
npm install
上述命令执行完毕就可以使用如下命令启动一个测试环境:
npm run dev
开发一个组件
src/Card.svelte
并定义组件的属性、样式以及 HTML 标签,代码如下:<script>
// component props
// Camel case not supported for props, see drawback section.
exportlet card_title, card_desc, card_img;
</script>
<main>
<divclass="card-container">
<divclass="card">
<imgsrc={card_img}alt="My product"/>
<divclass="card-body">
<divclass="row">
<divclass="card-title">
<h2>{card_title}</h2>
</div>
</div>
<p>
{card_desc}
</p>
<button>Do Something</button>
</div>
</div>
</div>
</main>
<style>
.card{
max-width:350px;
border-radius:5px;
box-shadow:04px6px0#00000033;
padding:0010px0;
}
.cardimg{
width:100%;
height:auto;
}
.card-body{
padding:5px10px;
}
.card-bodyp{
color:#575757;
margin-bottom:20px;
font-size:14px;
}
</style>
你可以在其他组件中使用这个卡片组件,如下所示(这一步可忽略):
<script>
importCardfrom"./Card.svelte";
</script>
<main>
<Card
card_title="My Card Title"
card_desc="Lorem ipsum dolor…"
card_img="path/to/my-image.png"
/>
</main>
/src/Button.svelte
代码如下:<script>
// Component props
exportlet type ="solid";
</script>
<buttonclass={type=="solid" ? "btn-solid":"btn-outline"}>
<slot/>
</button>
<style>
button{
padding:10px;
color:#fff;
font-size:17px;
border-radius:5px;
border:1px solid #ccc;
cursor: pointer;
}
.btn-solid{
background:#20c997;
border-color:#4cae4c;
}
.btn-outline{
color:#20c997;
background: transparent;
border-color:#20c997;
}
</style>
该组件的使用方法如下(可忽略):
importButtonfrom"./Button.svelte";
<Buttontype="outline">Click me</Button>
将自定义组件转成通用组件
rollup.config.js
在 plugins 增加一个 compilerOptions
配置项,在该配置项下增加 customElement: true 配置信息,如下所示:...
plugins:[
svelte({
compilerOptions:{
dev:!production,
customElement:true,
...
Card.svelte
文件,在文件开头第一行插入如下内容:<svelte:optionstag="my-card"/>
tag
属性值代表组件的标签名称。<svelte:optionstag="cool-button"/>
main.js
中引入这两个组件,打开 /src/main.js
将里面的内容替换成如下两行:importButtonfrom"./Button.svelte";
importCardfrom"./Card.svelte";
这里我们已经完成了两个组件的开发步骤,下一步就是打包组件以便其他的应用可以使用这两个组件,打开命令行窗口进入项目所在目录执行如下命令:
npm run build
build.js
和 build.map.js
, 文件位于项目下的 /build
目录。其中build.js
是打包的两个组件,而 build.map.js
是 build.js
源代码映射文件。bundle.js
拷贝到一个新目录,然后创建一个 index.html
文件,内容如下:<!DOCTYPE html>
<html>
<head>
<title>My website</title>
<scriptsrc="./build.js"></script>
</head>
<body>
<divclass="container">
<divclass="row">
<divclass="col">
<my-card
card_title="Red Person"
card_desc=" Lorem ipsum dolor sit, amet consectetur.."
card_img="https://bit.ly/34B3zHX"
>
</my-card>
<!-- Image credit - Shubham Dhage on unsplash.com -->
</div>
<divclass="col">
<divclass="border-bottom py-5">
<cool-button> Solid Cool Button </cool-button>
<cool-buttontype="outline"> Outlined Cool Button </cool-button>
</div>
</div>
</div>
</div>
</body>
</html>
这是一个再简单不过的 HTML 页面了,该页面使用了上述两个组件,在浏览器中显示为如下效果:
组件分割
rollup.config.js
的 input 和 output 中进行配置即可。exportdefault{
input:["src/Card.svelte","./src/Button.svelte"],
output:{
format:"iife",
dir:"public/build/",
},
...
npm run build
,我们就可以在 build 目录中看到两个文件 Button.js
和 Card.js
。<scriptsrc="Button.js"type="module"></script>
<cool-buttontype="outline">Click Me</cool-button>
<!-- another-page.html -->
<scriptsrc="Card.js"type="module"></script>
<my-cardcard_title="..."></my-card>
主要缺点
组件的属性名称不允许使用驼峰命名法,例如你会发现使用形如 cardTitle 这样的属性名就无法正常工作,而驼峰命名法又是 JavaScript 推荐的命名风格。这是一个 Bug,不过如果你使用的是 Vite ,那么有一个 workaround plugin 可以解决这个问题。
如果不标记 Web 组件,就无法在 Svelte 中重用它们 - 不幸的是,您还必须标记要在自定义 Web 组件中使用的每个 Svelte 组件
加入你有一个Header.svelte
文件需要作为<my-header />
组件输出,但同时这个组件又依赖另外一个Nav.svelte
文件,而 Nav.svelte 我们不希望作为 Web 组件输出,这个问题使得我们必须将 Nav.svelte 也作为组件输出,否则程序就会报错。好在这个问题现在也有解了(详情请看https://github.com/svelte-society/recipes-mvp/issues/41#issue-638005462),我们可以通过配置来解决这个问题,虽然看起来不是那么的爽,就这样吧,又不是不能用。浏览器的支持问题 — JavaScript
customElement
API 就是用来创建 Web Component 的底层 API,该 API 目前并没有被所有的浏览器支持,我们需要引入 Polyfill 来解决这个文件,详情请看https://github.com/webcomponents/polyfills/tree/master/packages/custom-elements。
总结
往期推荐
华为开发者贡献Linux内核补丁,将核心内核函数速度提升715倍
2022需求最大的8种编程语言
点这里 ↓↓↓ 记得 关注✔ 标星⭐ 哦~
微信扫码关注该文公众号作者