xb18
xb18
文章39
标签0
分类0
Web Components

Web Components

定义组件

1
2
3
4
5
6
7
8
9
class UserCard extends HTMLElement {
constructor() {
super();
let container = document.createElement('div');
container.classList.add('container');
container.innerText = 'UserCard';
this.appendChild(container);
}
}

声明自定义组件

1
window.customElements.define('user-card', UserCard);

使用

1
2
3
<body>
<user-card></user-card>
</body>

模板

在html中编写模板:

1
2
3
4
5
6
7
<template id="userCardAttr">
<div class="user-card-attr">
<span>name</span>
<span>====></span>
<span>value</span>
</div>
</template>

UserCard的container中添加模板:

1
2
3
let templateElem = document.getElementById('userCardAttr');
let userCardAttr = templateElem.content.cloneNode(true);
container.appendChild(userCardAttr);

获取模板节点以后,克隆了它的所有子元素,以便创建多个实例;

样式

自定义组件可以添加样式

1
user-card { /*xxx*/ }

template中可以添加style,不会影响外部样式;也可appendChild添加link引入css

1
2
3
4
5
6
7
8
9
10
11
12
<template id="userCardAttr">
<style>
:host { /* 无效?? */
font-size: 22px;
}
.user-card-attr {
background-color: wheat;
padding: 8px;
border-radius: 4px;
}
</style>
</template>

Web components 的一个重要属性是封装——可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁。

props

可以向组件添加动态参数

1
<user-card font-size="20px" card-title="UserCard"></user-card>

UserCard部分

1
2
3
4
5
6
7
8
class UserCard extends HTMLElement {
constructor() {
// .....
container.innerText = this.getAttribute('card-title');
container.style.fontSize = this.getAttribute('font-size');
// .....
}
}

Shadow DOM

Shadow DOM封装出来的DOM元素是独立的,外部的配置不会影响到内部,内部的配置也不会影响外部!

外部不能通过JavaScript来访问到!

1
2
3
4
5
6
7
8
9
class UserCard extends HTMLElement {
constructor() {
super();
let shadow = this.attachShadow( { mode: 'closed' } );
// ...
// this.appendChild(container);
shadow.appendChild(container);
}
}

进阶

可以把DOM中template使用JS注入网页,这样就可以仅加载JS就可以使用自定义组件!

现代浏览器版JQ大法或许会再次流行!

数据与视图的绑定?关键点!Vue相当于自定义组件的友好使用版 但自定义组件可以减少代码量 提升加载速度

SSR?

自定义组件更底层,Vue更实用

https://cn.vuejs.org/guide/extras/web-components.html

本文作者:xb18
本文链接:http://xb18.github.io/2023/10/19/WebComponent/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可