如何添加简单的 Web 组件?

问题描述 投票:0回答:2

有没有一种简单的方法可以将 Web 组件添加到 drupal 中?我已经尝试过,但我的组件没有显示,它完全删除了非 html 组件标签,它正确加载了 js 文件,当我控制台记录它时,它仅在

static get observedAttributes()
函数上返回日志。

js代码:

class MyComponent extends HTMLElement {
  static get observedAttributes() {
    return ['message'];
  }

  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'message') {
      this.render(newValue);
    }
  }

  render(message) {
    this.shadowRoot.innerHTML = `
      <style>
        .message {
          font-size: 20px;
          color: blue;
        }
      </style>
      <div class="message">${message}</div>
    `;
  }
}

customElements.define('my-component', MyComponent);

我通过这个钩子添加一个带有此 Web 组件的库:

/**
 * Implements hook_node_view() to add a library to the node view.
 *
javascript drupal web-component drupal-10
2个回答
2
投票

Drupal 的渲染 API 会自动清理任何应该解析为 HTML 的内容。 https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21theme.api.php/group/theme_render/10

这会影响代码的

'#markup' => '<my-component message="' . $message . '"></my-component>',
部分,由于清理限制,输出中会省略非标准 HTML 标记,因为您的
<my-component>
标记不在允许标记的白名单中。

从上面链接的页面:

#markup
:指定数组直接提供 HTML 标记。除非标记非常简单,例如段落标记中的解释,否则通常最好使用
#theme
#type
代替,以便主题可以自定义标记。 请注意,该值是通过
\Drupal\Component\Utility\Xss::filterAdmin()
传递的,它会去除已知的 XSS 向量,同时允许非 XSS 向量的 HTML 标签列表。
(例如, 和 是不允许的。)请参阅
\Drupal\Component\Utility\Xss::$adminTags
查看允许的标签列表。

如果您的标记需要任何不在此列表中的标签,那么您可以实现主题挂钩和/或资源库。或者,您可以使用键

#allowed_tags
来更改过滤哪些标签。

此视频可能对您有帮助:为 DRUPAL 创建和使用 WEB 组件


1
投票

我不知道Drupal是做什么的。
Web 组件是 HTML,就像 CMS 中的任何其他 HTML 一样;
不需要在 CMS 中进行任何特殊处理。

检查控制台是否有

customElements.get("my-component")

应该返回组件类
如果不是,则定义组件的 Javascript 不会被执行。

您的 Web 组件缺少

connectedCallback
,
并且
attributeChangedCallback
在元素在 DOM 中 connected 之前触发 。 (每个观察到的属性一次!) 因此,您必须通过检查
attributeChangedCallback( "message" ,...)首先
this.isConnected
守护

其余的更改只是为了优化您的 Web 组件

<script> customElements.define('my-component', class extends HTMLElement { static get observedAttributes() { return ['message']; } constructor() { super() .attachShadow({ mode: 'open' }) .innerHTML = ` <style> div { font-size: 20px; color: blue } </style> <div></div>`; } attributeChangedCallback(name, oldValue, newValue) { if (this.isConnected) this[ name ](); } connectedCallback(){ this.message(); } message(msg = this.getAttribute("message") || "No message attribute!") { this.shadowRoot.querySelector("div").innerHTML = msg; } }); </script> <my-component></my-component> <my-component message="Hello Cool Web Component World!"></my-component>

使用

<slot>
 简化您的 Web 组件

对于(简单)消息,不需要

attribute

shadowDOM 中的

<slot>

 会自动显示 lightDOM(Web 组件本身的内部 HTML)
另请参阅
命名的 SLOThttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot

SLOT 是

反应式
document.querySelector("my-slot-component").innerHTML = "GREAT! Components!";


将更新 ShadowDOM 中的 
reflected 插槽

有关样式槽的长篇阅读和深入研究,请参阅:

::shadowDOM 槽中嵌套子级的槽式 CSS 选择器

<script> customElements.define('my-slot-component', class extends HTMLElement { constructor() { super() .attachShadow({ mode: 'open' }) .innerHTML = ` <style> div { font-size: 20px; color: blue; } </style> <div><slot>No message specified</slot></div>`; } }); </script> <my-slot-component></my-slot-component> <my-slot-component>Hello Fantastic Web Component World!</my-slot-component>

© www.soinside.com 2019 - 2024. All rights reserved.