网络组件是JavaScript和HTML等开源技术的集合,允许你创建可以在网络应用中使用和重用的自定义元素。你创建的组件是独立于你的其他代码的,所以它们很容易在许多项目中重用。
最重要的是,它是一个平台标准,由所有主要的现代浏览器支持。
网络组件里有什么?
- 自定义元素。这个JavaScript API允许你定义新类型的HTML元素。
- 影子DOM。这个JavaScript API提供了一种方法,将一个隐藏的单独的文档对象模型(DOM)附加到一个元素。这通过保持样式、标记结构和行为与页面上的其他代码隔离来封装你的网络组件。它确保样式不会被外部样式覆盖,或者反过来说,你的网络组件的样式不会 "泄露 "到页面的其他部分**。**
- HTML模板。该元素允许你定义可重复使用的DOM元素。该元素及其内容不在DOM中呈现,但仍可使用JavaScript进行引用。
你可以用你喜欢的文本编辑器和JavaScript编写一个简单的网络组件。这个方法使用bootstrap来生成简单的样式,然后创建一个简单的卡片式Web组件来显示作为属性传递给它的地点的温度。该组件使用Open Weather API,这需要你通过登录生成一个APPID/APIKey。
调用这个网络组件的语法需要地点的经度和纬度。
<weather-card longitude='85.8245' latitude='20.296' />
创建一个名为weather-card.js的文件,其中将包含你的网络组件的所有代码。从定义你的组件开始。这可以通过创建一个模板元素并在其中添加一些简单的HTML元素来完成。
const template = document.createElement('template');
template.innerHTML = `
<div class="card">
<div class="card-body"></div>
</div>
`
开始定义WebComponent类和它的构造函数。
class WeatherCard extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
}
….
}
构造函数附加了shadowRoot并将其设置为开放模式。然后,模板被克隆到shadowRoot。
接下来,访问属性。这些是经度和纬度,你需要它们来向Open Weather API发出GET请求。这需要在connectedCallback 函数中完成。你可以使用getAttribute 方法来访问这些属性,或者定义获取器来将它们绑定到这个对象。
get longitude() {
return this.getAttribute('longitude');
}
get latitude() {
return this.getAttribute('latitude');
}
现在定义connectedCallBack 方法,每当天气数据被挂起时,该方法就会取回天气数据。
connectedCallback() {
var xmlHttp = new XMLHttpRequest();
const url = `http://api.openweathermap.org/data/2.5/weather?lat=${this.latitude}&lon=${this.longitude}&appid=API_KEY`
xmlHttp.open("GET", url, false);
xmlHttp.send(null);
this.$card = this._shadowRoot.querySelector('.card-body');
let responseObj = JSON.parse(xmlHttp.responseText);
let $townName = document.createElement('p');
$townName.innerHTML = `Town: ${responseObj.name}`;
this._shadowRoot.appendChild($townName);
let $temperature = document.createElement('p');
$temperature.innerHTML = `${parseInt(responseObj.main.temp - 273)} °C`
this._shadowRoot.appendChild($temperature);
}
一旦天气数据被检索到,额外的HTML元素就会被添加到模板中。现在,你的类被定义了。
最后,通过使用方法window.customElements.define ,定义并注册一个新的自定义元素。
window.customElements.define('weather-card', WeatherCard);
第一个参数是自定义元素的名称,第二个参数是定义的类。这里是整个组件的链接。
你已经写好了你的第一个网络组件!现在是时候把它带到DOM中去了。要做到这一点,你必须在你的HTML文件中加载带有你的网络组件定义的JavaScript文件(命名为index.html)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<weather-card longitude='85.8245' latitude='20.296'></weather-card>
<script src='./weather-card.js'></script>
</body>
</html>
这就是你在浏览器中的网络组件。
因为网络组件只需要HTML、CSS和JavaScript,所以它们被浏览器原生支持,并且可以与前端框架无缝连接,包括React和Vue。下面的简单代码片断显示了如何在一个用Create React App引导的简单React App中使用Web组件。为此,你需要导入你之前定义的weather-card.js文件,并将其作为一个组件使用。
import './App.css';
import './weather-card';
function App() {
return (
);
}
export default App;
网络组件的生命周期
所有组件都遵循一个生命周期,从初始化到从DOM中移除(即卸载)。方法与每个生命周期事件相关联,这样你就可以更好地控制组件。网络组件的各种生命周期事件包括。
-
构造器。网络组件的构造函数在它被挂载之前被调用,这意味着它是在元素被附加到文档之前创建的。它用于初始化本地状态,绑定事件处理程序,并创建影子DOM。构造函数必须对
super(),以调用Web组件类所扩展的类。 -
ConnectedCallBack。当一个元素被加载(即插入DOM树)时,它被调用。它处理初始化创建DOM节点,主要用于实例化网络请求等操作。React开发者可以将其与
componentDidMount。 -
attributeChangedCallback。这个方法接受三个参数:
name,oldValue, 和newValue。每当组件的一个观察属性被改变时,它就被调用。属性是使用静态的observedAttributesgetter来声明观察属性的。static get observedAttributes() { return ['name', '_id']; }每当属性名称或
_id被改变时,attributeChangedCallback将被调用。 -
DisconnectedCallBack。当一个元素从DOM树上被移除(即解挂)时,它被调用。它等同于React的
componentWillUnmount。它被用来释放那些不会被自动收集垃圾的资源,比如取消对DOM事件的订阅,停止间隔计时器,或者取消所有注册的回调。 -
AdoptedCallback。它在每次自定义元素被移动到一个新的文档时被调用。它只在处理IFrames时出现。
模块化的开放源码
网络组件可以成为开发网络应用的一种强大方式。无论你是对JavaScript很熟悉,还是刚开始接触它,用这个伟大的开放标准创建可重复使用的代码是很容易的,无论你的目标受众使用什么浏览器。