Redian新闻
>
使用Svelte来构建Web Component (超简单方便)

使用Svelte来构建Web Component (超简单方便)

公众号新闻


来源 | OSCHINA 社区

译者 | 红薯

文章链接:https://my.oschina.net/javayou/blog/5609297


每个开发人员都应该关注代码中的可重用性以及代码的业务隔离,这样可以让业务逻辑与应用架构分离,提升系统的扩展性。而 Web Component 就是这样一个技术,可以让我们创建一个独立的可重用组件。
本文将介绍使用 Svelte 创建通用的 Web Component 的完成过程。『通用』指的是该组件不局限于 Svelte 应用,还可以用于任何 JavaScript 应用程序(如 Vue、React 等),同时还将介绍使用 Svelte 创建 Web Component 的一些局限性。

什么是 Web Component?

Web Component 可以让我们创建可重用的、自定义的封装了样式以及功能的 HTML 元素。
例如,我们使用如下代码来创建一个导航条:
<style>
/* CSS code for our navbar */
</style>
<navbar>
<!-- Some long code for our navbar -->
</navbar>
如果用 Web Component 技术,我们可以定义一个自定义元素(如 <custom-navbar/>),然后你可以在网页任一地方使用该元素显示导航条,同时这个导航条的样式和页面其他元素的样式是完全隔离的,不会相互影响。而这项技术被称之为 Shadow DOM (影子 DOM)。

什么是 Shadow DOM?

Shadow DOM 是一个较小的、独立的 DOM,它与主 DOM 分开渲染,允许我们将样式和标记行为隔离到单个组件中。Shadow DOM 本质上允许我们将组件功能进行封装和隔离,我们可以单独对其设置样式、编写功能脚本,而不会干扰应用程序的其余元素。
你大概对 Web Component 有一个基本的认识,下面我们开始用 Svelte 来编写一个简单的组件。

构建 Web Component

准备工作

为了完成本文剩余的内容学习,需要你对掌握以下知识:
  • 对 HTML, CSS 和 JavaScript 有基本的认识

  • 熟悉命令行操作环境

  • 需要一个文本编辑器

  • 最好对 Svelte 有一些基本的了解(可以看看我之前翻译的文章 https://my.oschina.net/javayou/blog/5309554 )

开始

本文我们将开发两个组件:
  • 第一个组件是一个卡片组件,接收三个属性分别是:卡片标题、卡片描述以及图片,该组件名为 <my-card />

  • 第二个组件是一个带样式的按钮,接收一个 type 的属性,通过该属性来确定按钮的显示样式,组件名称为 <cool-button />

同时我们将使用两种组件的发布方式,一个是打包到单一文件,另外一个是每个组件发布到一个独立的文件中。
下图显示的是两个组件运行后的外观:
我们从创建一个 Svelte 应用开始,并安装必须的包:
npx degit sveltejs/template web-component-tut
cd web
-component-tut
npm install

上述命令执行完毕就可以使用如下命令启动一个测试环境:

npm run dev
然后我们打开浏览器访问 http://localhost:8080 就可以看到一个最基础的 Svelte 应用运行起来后的样子:

开发一个组件

使用 Svelte 生成通用 Web Component 的过程类似于创建常规 Svelte 组件的过程,只是进行了一些修改。
为了创建第一个卡片组件,我们首先创建一个文件 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>

将自定义组件转成通用组件

我们需要将自定义 Svelte 组件转成通用的 Web Component ,这样才可以在其他框架中直接使用。
要做这个转换操作,我们需要在 Svelte 配置文件中设置让编译器生成自定义元素。打开 rollup.config.js 在 plugins 增加一个 compilerOptions配置项,在该配置项下增加 customElement: true 配置信息,如下所示:
...
plugins
:[
svelte
({
compilerOptions
:{
dev
:!production,
customElement
:true,
...
然后我们需要给两个组件分别定义一个元素名称,打开 Card.svelte 文件,在文件开头第一行插入如下内容:
<svelte:optionstag="my-card"/>
上述 tag 属性值代表组件的标签名称。
同样的,打开 Button.svelte 给第二个组件指定一个标签名称:
<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 页面了,该页面使用了上述两个组件,在浏览器中显示为如下效果:

组件分割

在某些情况下我们不需要将多个组件打包到同一个 js 文件中,我们希望每个组件有一个独立的 js 文件。要实现这个场景只需在 rollup.config.js 的 input 和 output 中进行配置即可。
在 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>

主要缺点

到这里我们已经掌握了使用 Svelte 开发 Web Component 的方法,这个过程非常之简单,但是,使用 Svelte 开发 Web 组件会有一些缺点如下:
  • 组件的属性名称不允许使用驼峰命名法,例如你会发现使用形如 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

总结

在本文中,我们学习了如何使用 Svelte 创建通用卡片和按钮组件,生成捆绑文件,拆分它们,甚至在单独的 HTML 页面中重用此组件。
动手试试吧?
本文翻译自:Build web components with Svelte - LogRocket Blog(https://blog.logrocket.com/build-web-components-svelte/


往期推荐



谷歌发文批评苹果:实在是 “拖大家后腿”

华为开发者贡献Linux内核补丁,将核心内核函数速度提升715倍

2022需求最大的8种编程语言



这里有最新开源资讯、软件更新、技术干货等内容

点这里 ↓↓↓ 记得 关注✔ 标星⭐ 哦~

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
非游记(三)以后面试官问你 为啥不建议使用Select *,请你大声回答他!​【租房】1.1起租 | 1047 Commonwealth Ave | 学生公寓studio | 租金¥2995,带家具使用Somalytics的睡眠面罩 以全新方式追踪睡眠一键从Prompt到PowerPoint,斯坦福博士生自制的PPT生成神器火了使用 PowerFlex 在 Kubernetes 平台上部署 Microsoft SQL Server 大数据集群习近平会改行党主席制吗?常委会为何不会扩充为9人?WPP收购北美数字机构Fēnom Digital;凯捷旗下The Works公司公布新任命(广告狂人日报)重磅!悉尼小红书博主们注意啦~这里招募要求超简单,只需简单几步即可轻松实现流量变现!Ousted Luckin Founder Charts Comeback With New Coffee Business1.1入住|Commonwealth Ave上近BU步行5分钟高性价比两室无厅租金2150,包水暖。Prompt总结 | 从MLM预训任务到Prompt Learning原理解析与Zero-shot分类、NER简单实践在美国259.幻想、合住?老房客Can China’s Esports Athletes Mount a Comeback?[电脑] Intel + Intel + Intel: Arc 750 Limited Edition + 13700KF 开箱Vue 3是最佳选择吗? 耗时两周从Vue 2迁移到Svelte后:代码执行更快、体验更佳Online Study Rooms Rife With Vulgar Content, Media Report SaysNeurIPS 2022 | 重振PointNet++雄风!PointNeXt:改进模型训练和缩放策略审视PointNet++​【租房】1.1起租 | 1047 Commonwealth Ave | 学生公寓studio | 租金2995|带家具文革前的上海交大篮球(ZT)bāo huā shēng?bō huā shēng?2023年A-level艺术考试最新变化!Component2 恢复!半中介费|12.19入住|Commonwealth Ave上近BU步行5分钟高性价比Studio租金1950,包水暖。SvelteKit 1.0正式发布【免中介费,12月入住一室公寓,近BC和地铁绿线】Brighton地区Commonwealth Ave.|无忧精选公寓楼Web Series Revisits Hostels Serving as Refuge for Migrant Women【TSVC】2023年TSVC要投什么?- Zoom首轮投资人展望2023秋行南意 行程 感受英国秋招丨精品投行Moelis & Company开放2023 Internship​1.1起租 1047 commenwealth ave 学生公寓studio 租金2995,带家具Companies Promote Digital and Smart Agriculture in ChinaNECLTA第十一届年会成功举行 NECLTA Annual Conference Held at Tufts Univ.
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。