前言
在上篇文章 Angular视图封装模式中我们简单了解了一下 Shadow Dom。Shadow Dom只是Web Components的组成部分之一。
Web Components 是原生提供的一套功能,它允许在Web文档和Web应用程序中创建可重用的小部件或组件。
简单说就是不用框架,利用原生技术Web Components就可以封装组件,实现组件化,Web Components主要由三部分组成:
- Custom elements(自定义元素) Custom element用于创建自定义HTML元素,提供了完整的生命周期
- HTML templates(HTML模板) HTML templates通过
<template>、<slot>实现内容分发 - Shadow Dom(影子DOM) Shadow Dom提供了封装的功能,使元素与主文档隔离,样式互补冲突
简单看一个例子
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<time-formatted datetime="1646472274953"></time-formatted>
</body>
<script>
class TimeFormatted extends HTMLElement {
connectedCallback() {
let date = new Date(parseInt(this.getAttribute("datetime")));
this.innerHTML = `${date.getFullYear()}-${date.getMonth()}-${date.getDay()}`;
}
}
customElements.define("time-formatted", TimeFormatted);
</script>
</html>
上述代码简单实现了一个 time-formatted 组件,或许你用过Angular,会觉得这和Angular太像了。
再写个例子看看
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<template id="my-article">
<p>this is a example</p>
<slot name="title"></slot>
<hr>
<slot name="content"></slot>
</template>
<my-article>
<h3 slot="title">Web Components</h3>
<div slot="content">Web Components 如何使用?和框架的区别是什么?是否可以替代框架呢?</div>
</my-article>
</body>
<script>
class MyArticle extends HTMLElement {
connectedCallback() {
const template = document.getElementById("my-article").content;
this.attachShadow({ mode: "open" }).append(template.cloneNode(true));
}
}
customElements.define("my-article", MyArticle);
</script>
</html>
该例子中定义了一个组件
my-article,并将模版template 通过shadow dom 挂在组件上,且模版中有两个具名插槽。或许你用过Vue,会觉得这和Vue太像了。没错,Vue slot的设计灵感正是来源于Web Components。
如果你想了解更多用法,请参考 教程。
疑惑
在了解Web Components之后有几个问题一直很困扰我:
- 在原生Api支持组件化的条件下,为什么人们还是愿意去拥抱框架?
- 用Web Components实现的组件和用框架实现的组件有什么区别?
- 会不会有一天框架被淘汰了?
一段时间后
就像电影里的几年后,主人公总是变强后归来。
疑惑终于不是疑惑了。
-
在原生Api支持组件化的条件下,为什么人们还是愿意去拥抱框架? 组件化只是框架提供的众多便捷中的一种,每一种框架都有对应的生态,例如路由、状态管理、脚手架、测试、文档等等。。。这也就是大家愿意拥抱框架的原因吧。
-
用Web Components实现的组件和用框架实现的组件有什么区别? 别忘了,Web Components可是原生的,完全不依赖框架环境,如果你用Web Components实现了一个组件,你可以在Vue项目里用,也可以在Angular项目里用,完全垮框架。Vue里也提供了具体使用的方法使用自定义元素;同样在Angular中也有对应的支持。 目前已经有很多用Web Components实现的UI库了,例如腾讯推出的OMI ,微软推出的fast.design
-
会不会有一天框架被淘汰了? 不知从哪篇文章看到的一句话:能淘汰框架的一定是框架。我非常赞同,框架不是单一的一种技术,而是一个生态,包含很多技术。除非有一天,原生Api也形成了一个生态圈,能解决框架解决的所有问题,那可能会有部分人放弃框架选择原生,但框架也不会被淘汰,只是技术人员又多了一种选择而已。