前言
哈喽,大家好,我是海怪。
最近不是写了一篇关于京东微前端框架的文章嘛 《初探 MicroApp,一个极致简洁的微前端框架》,里面提到了一个叫 Web Components 的东西。虽然对它早有耳闻,但是一直也没怎么仔细看过,所以就深入了解了一下,今天给大家做个简单分享 😃
下面的实践代码都放在 Github 这个仓库里了。
是什么
Web Components 实际上一系列技术的组合,主要包含 3 部分:
- 自定义元素。 在 HTML 基础标签外扩展自定义标签元素
- Shadow DOM。 主要用于将 Shadow DOM 的内容与外层 document DOM 隔离
- HTML 模板。 使用
<template>
来定义组件模板,使用<slot>
作为插槽使用
也正是因为它是一系列 API 的组合,所以在使用时,我们要同时关注这些 API 的兼容性:
将上面技术合理使用后,就可以 将功能、逻辑封装到自定义标签中,通过复用这些自定义的组件来提高开发效率。 听起来就像是 Vue.js
和 React
做的那一套,实际上,在使用 Web Components 的时候,也是很像的。
上手
接下来我们通过实现一个 <book-card>
Web Component 来学习一下怎么使用它吧。
自定义元素
首先,创建一个 index.html
,在里面直接调用 <book-card>
组件。
<body>
<book-card></book-card>
<script src="./BookCard.js"></script>
</body>
因为浏览器不认识 <book-card>
所以,我们需要在 BookCard.js
里注册它,并在 index.html
中引入并执行 BookCard.js
。
class BookCard extends HTMLElement {
constructor() {
super();
const container = document.createElement('div')
container.className = 'container'
const image = document.createElement('img')
image.className = 'image'
image.src = "https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp"
const title = document.createElement('p')
title.className = 'title'
title.textContent = '切尔诺贝利的祭祷'
const desc = document.createElement('p')
desc.className = 'desc'
desc.textContent = 'S·A·阿列克谢耶维奇'
const price = document.createElement('p')
price.className = 'price'
price.textContent = `¥25.00`
container.append(image, title, desc, price)
this.appendChild(container)
}
}
customElements.define('book-card', BookCard)
上面已经实现了最基础的 DOM 结构了:
上面一直执行
createElement
并设置属性值的行为是否有点像 React 的React.createElement
呢?
HTML 模板
这样一行一行地生成 DOM 结构不仅写的累,读的人也很难一下子看明白。为了解决这个问题,我们可以使用 HTML 模板 。直接在 HTML 里写一个 <template>
模板:
<body>
<template id="book-card-template">
<div class="container">
<img class="image" src="https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp" alt="">
<p class="title">切尔诺贝利的祭祷</p>
<p class="desc">S·A·阿列克谢耶维奇</p>
<p class