Vanilla JS 中的 Web 组件:ngFor 和 v-for 的等价物?
Web Components in Vanilla JS: Equivalent of ngFor and v-for?
我有一个用 vanilla JS 定义的自定义组件:
class Article extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.render();
}
render() {
this.innerHTML = /*html*/ `
<div>this.getAttribute("title")</div>
`;
}
}
customElements.define("custom-article", Article);
然后我想从数组中实例化这些组件,具体来说(在 HTML 中):
这在 Angular 和 Vue.js(可能在所有其他 JS 框架中)都是微不足道的,但是我找不到关于在 Vanilla JS 中实现的相同功能的文档。
遗憾的是,JS 模板字面量还没有这样的功能 - 在处理 vanilla JS webcomponents 时,你会发现自己越来越少地使用 HTML 字符串。
这是一个 string-based 普通 JS 方法的示例,呈现水果列表:
class FruitList extends HTMLElement {
ul = document.createElement('ul');
fruits = ['Apple','Banana','Strawberry','Ananas','Cherry'];
constructor() {
super().attachShadow({mode: 'open'}).append(this.ul);
}
connectedCallback() {
this.render();
}
render() {
this.ul.innerHTML = this.fruits.reduce((s,f)=>s+=`<li>${f}</li>`,'');
}
}
customElements.define("fruit-list", FruitList);
<fruit-list></fruit-list>
然而,对于要创建的简单 HTML,完全放弃使用字符串效果很好:
class FruitList extends HTMLElement {
ul = document.createElement('ul');
fruits = ['Apple','Banana','Strawberry','Ananas','Cherry'];
constructor() {
super().attachShadow({mode: 'open'}).append(this.ul);
}
connectedCallback() {
this.render();
}
render() {
while (this.ul.firstChild) this.ul.firstChild.remove();
this.ul.append(...this.fruits.map(fruit => {
const li = document.createElement('li');
li.textContent = fruit;
return li;
}));
}
}
customElements.define("fruit-list", FruitList);
<fruit-list></fruit-list>
这还有一个好处,您可以更轻松地进行操作,例如将事件侦听器附加到动态创建的元素。
他的回答对 Connexo 进行了小幅改进
this.ul.append(...this.fruits.map(fruit =>
Object.assign(document.createElement('li'),{
textContent : fruit,
onclick : (evt) => console.log(fruit)
}));
我有一个用 vanilla JS 定义的自定义组件:
class Article extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.render();
}
render() {
this.innerHTML = /*html*/ `
<div>this.getAttribute("title")</div>
`;
}
}
customElements.define("custom-article", Article);
然后我想从数组中实例化这些组件,具体来说(在 HTML 中):
这在 Angular 和 Vue.js(可能在所有其他 JS 框架中)都是微不足道的,但是我找不到关于在 Vanilla JS 中实现的相同功能的文档。
遗憾的是,JS 模板字面量还没有这样的功能 - 在处理 vanilla JS webcomponents 时,你会发现自己越来越少地使用 HTML 字符串。
这是一个 string-based 普通 JS 方法的示例,呈现水果列表:
class FruitList extends HTMLElement {
ul = document.createElement('ul');
fruits = ['Apple','Banana','Strawberry','Ananas','Cherry'];
constructor() {
super().attachShadow({mode: 'open'}).append(this.ul);
}
connectedCallback() {
this.render();
}
render() {
this.ul.innerHTML = this.fruits.reduce((s,f)=>s+=`<li>${f}</li>`,'');
}
}
customElements.define("fruit-list", FruitList);
<fruit-list></fruit-list>
然而,对于要创建的简单 HTML,完全放弃使用字符串效果很好:
class FruitList extends HTMLElement {
ul = document.createElement('ul');
fruits = ['Apple','Banana','Strawberry','Ananas','Cherry'];
constructor() {
super().attachShadow({mode: 'open'}).append(this.ul);
}
connectedCallback() {
this.render();
}
render() {
while (this.ul.firstChild) this.ul.firstChild.remove();
this.ul.append(...this.fruits.map(fruit => {
const li = document.createElement('li');
li.textContent = fruit;
return li;
}));
}
}
customElements.define("fruit-list", FruitList);
<fruit-list></fruit-list>
这还有一个好处,您可以更轻松地进行操作,例如将事件侦听器附加到动态创建的元素。
他的回答对 Connexo 进行了小幅改进
this.ul.append(...this.fruits.map(fruit =>
Object.assign(document.createElement('li'),{
textContent : fruit,
onclick : (evt) => console.log(fruit)
}));