Vanilla JS中的Web组件:相当于NGFOR和V-FOR?

发布于 2025-01-22 07:27:42 字数 448 浏览 0 评论 0原文

我有一个在香草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中相同功能的文档。

I have a custom component defined in 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);

I then would like to instantiate these components from an array, specifically (in the HTML):

This is trivial to do in both Angular and Vue.js (and probably in every other JS framework), however I can't find documentation on the same functionality being implemented in Vanilla JS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

终陌 2025-01-29 07:27:42

可悲的是,JS模板文字尚未具有这样的功能 - 在使用Vanilla JS WebComponents工作时,您会发现自己越来越少地使用HTML字符串工作。

这是香草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>

这也具有整洁的优势,您可以更轻松地将事件听众附加到动态创建的元素上。

Sadly, JS template literals don't come with such functionality yet - you're going to find yourself working less and less with HTML strings when working on vanilla JS webcomponents.

Here's an example of a string-based approach in vanilla JS, rendering a list of fruits:

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>

Yet for simple HTML that is to be created, dropping the use of strings altogether works just fine:

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>

This also has the neat advantage that you can much more easily e.g. attach event listeners to the dynamically created elements.

归途 2025-01-29 07:27:42

对Connexo的略有增强他的答案

this.ul.append(...this.fruits.map(fruit => 
                      Object.assign(document.createElement('li'),{
                         textContent : fruit,
                         onclick : (evt) => console.log(fruit)
                      }));

Small enhancement on Connexo his answer

this.ul.append(...this.fruits.map(fruit => 
                      Object.assign(document.createElement('li'),{
                         textContent : fruit,
                         onclick : (evt) => console.log(fruit)
                      }));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文