标签: web-component

如何在 Angular Web 组件(自定义元素)上调用方法

我创建了一个如下所示的 Angular Web 组件

@Component({
  selector: 'dlx-slider',
  templateUrl: './slider.component.html',
  styleUrls: ['./slider.component.scss'],
  encapsulation: ViewEncapsulation.Native,
})
export class SliderComponent implements OnInit {

  open() {
    console.log('open');
  }

  close() {
    console.log('close');
  }

}
Run Code Online (Sandbox Code Playgroud)

在我的应用程序模块中

export class AppModule {
  constructor(private injector: Injector) {
  }

  ngDoBootstrap() {
    this.defineElement(SliderComponent, 'dlx-slider');
  }

  private defineElement(component: any, elementName: string) {
    const el = createCustomElement(component, { injector: this.injector });
    customElements.define(elementName, el);

  }
}
Run Code Online (Sandbox Code Playgroud)

一切正常,我已经将它嵌入到一个简单的 HTML 页面中,如下所示

<head>
    <meta charset="utf-8">
    <title>TMIBot</title>
    <base href="/">

    <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, user-scalable=no">

    <title>Test Angular Elements</title> …
Run Code Online (Sandbox Code Playgroud)

web-component custom-element angular

6
推荐指数
2
解决办法
3460
查看次数

是否可以使用 ES2015 导入模板标签?

我一直在阅读,但我没有找到任何东西,如果有可能在不同的 html 文件中定义并使用 ESModule 导入以与 shadowRoot 一起使用,可能吗?

index.html,我在其中定义了 2 个 javscript 模块并使用了我的组件<hello-world></hello-world>

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>My First Component</title>
    <meta name="description" content="My First Component">
    <meta name="author" content="Ismael Rodriguez">
    <script type="module" src="js/my-template.js"></script>
    <script type="module" src="js/component.js"></script>
    <!--
        <template id="my-template">
            <h2>Hello World</h2>
         </template>
    -->
</head>

<body>
    <h1>Web Component</h1>
    <hello-world></hello-world>
</body>
Run Code Online (Sandbox Code Playgroud)

js/my-template.js,在这个模块中只导出一个带有标签 html 的字符串。

export const template = `
    <style>
        h3 {
            color: red;
            font-family: helvetica;
        }
    </style>
    <h3>Hello World</h3>
`;
Run Code Online (Sandbox Code Playgroud)

js/component.js,最后导入模块my-template.js。我发现这种方法可以使用 ESmodule 从我的模块中解释模板。我如何导入模板并在我的组件中使用(支持 Firefox)? …

web-component

6
推荐指数
1
解决办法
1938
查看次数

Lit-Element:哪个事件用于 DOM 更新?

github.com/Polymer/lit-element 上的文档描述了生命周期,如果某些 lit-element的属性发生更改。但是,如果元素的 DOM 内容发生更改,我似乎找不到有关生命周期的任何文档。

所以假设我有一些嵌套的 DOM 结构,我最外层的元素应该根据 DOM 内容显示一些东西。为简单起见,下面的示例将仅显示给定类型的子元素的数量。

现在,我的应用程序会插入一个新的嵌套元素(单击test下面的按钮)。在这一点上,我想更新显示的计数。

从我的测试来看,render()在这种情况下似乎不会再次调用,也不会updated()

我需要监听哪个事件或者我需要实现哪个函数来识别这样的变化?

我目前唯一的解决方法是requestUpdate()在 DOM 更新后手动使用,但我认为此类更改应该由 lit-element 本身处理。

  document.querySelector( 'button' )
          .addEventListener( 'click', () => {
            const el = document.querySelector( 'my-element' );
            el.insertAdjacentHTML( 'beforeend', '<my-nested-element>new addition</my-nested-element>' );
          })
Run Code Online (Sandbox Code Playgroud)
my-element, my-nested-element {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>

<!-- Works only on browsers that support Javascript modules like Chrome, Safari, Firefox 60, Edge 17 -->
<script type="module">
  import {LitElement, html} from …
Run Code Online (Sandbox Code Playgroud)

javascript web-component lit-element

6
推荐指数
1
解决办法
3097
查看次数

从 Javascript Lit 元素中分离 HTML 和 CSS

我们正在使用 Lit Element 并且我们的组件文件变得相当大,因为我们必须在 .js 文件中编写样式和 html。有没有办法将它们拆分成单独的文件,然后将它们导入到我们的组件中?这样做的最佳方法是什么?HTML 和 CSS 尤其让我们的工作流程变得困难,因为我们的文件变得过于臃肿。

更新:Supersharp 的建议帮助我分离了 CSS 和 html 模板,但我在将 html 模板与指定属性绑定时遇到了问题。我有一个服务文件,它为我指定的文件发出 XML 请求,我将它导入到我的组件文件中。这是我的组件:

import { LitElement, html} from '@polymer/lit-element';

import HtmlLoader from './Service/HtmlLoader';

class TestAnimatedButtonElement extends LitElement {

  static get properties() {
    return {
      _text: {
        type: String
      }
    }
  }

  constructor() {
    super();
    this.htmlTemplate = HtmlLoader.prototype.getHtmlTemplate('/src/Components/ExampleElements/test-animated-button-element.html');
  }

  render(){
    this.htmlTemplate.then( template => this.shadowRoot.innerHTML = template)
    return html( [this.htmlTemplate] );
  }

  handleButton(e) {
    //e.preventDefault();
    console.log('Button pressed');
  }
}
customElements.define('test-animated-button-element', TestAnimatedButtonElement);
Run Code Online (Sandbox Code Playgroud)

这是我的 html 文件: …

import module web-component lit-html

6
推荐指数
1
解决办法
4575
查看次数

从包含 Web 组件的插槽内容中捕获事件

我有一个简单的 Web 组件,其中包含<slot>. 它处理表单数据,并且在我内部有 UI 元素可以发出数据更改/选定事件。我想知道 web 组件如何对插槽内容发出的事件做出反应。沿着这些路线的东西:

<my-form-handler>
     <my-player-selector player-id="master"></my-player-selector>
     <my-player-selector player-id="challenger"></my-player-selector>
     <my-weapons-selector default="sword"></my-weapons-selector>
</my-form-handler>
Run Code Online (Sandbox Code Playgroud)

我知道我可以编写<my-form-handler ondataSelected="someFunction">假设选择器元素发出dataSelected事件。但这需要代码位于包含页面而不是 my-form-handler 中。

我没有使用任何框架(Vue、Angular、React),只是普通的 JS。

javascript web-component dom-events custom-element

6
推荐指数
1
解决办法
1141
查看次数

如何将对象(或关联数组)作为属性值传递给我的 Web 组件

我正在制作 vanilla-js 网络组件,需要将对象作为其值传递给属性,但每次都将其作为字符串。

我能够将字符串传递给组件的属性,但我知道我需要传递一个对象。

var obj = { name: "John", age: 30, city: "New York" };

const template = document.createElement('template');

class TabelComponent extends HTMLElement {

    constructor() {
        super();
        this.attachShadow({mode: 'open'});
        this.shadowRoot.appendChild(template.content.cloneNode(true));
    }

    connectedCallback() {
        console.log(this.content);
    }
    
    get content() {
        return this.getAttribute("content")
    }
}

window.customElements.define('table-component', TabelComponent);
Run Code Online (Sandbox Code Playgroud)
<table-component content=obj></table-component>
Run Code Online (Sandbox Code Playgroud)

我的属性“内容”应该将 obj 作为对象而不是字符串。我应该进入 { name: "John", age: 30, city: "New York" };控制台

html javascript object web-component

6
推荐指数
2
解决办法
1234
查看次数

Lit-Element:如何设置全局/重置 css

如果我使用 Lit-element,当前设置全局/重置 CSS 的最佳实践是什么?

我已经尝试过 1) 将它们内联到<style>我的文档根目录中,2) 像这个答案一样构建样式表

<script>
  var css = new CSSStyleSheet()
  css.replace('@import url("./style/static/reset.css")')
  document.adoptedStyleSheets = [css]
</script>
Run Code Online (Sandbox Code Playgroud)

但没有任何作用...

编辑 我的reset.css

blockquote,
body,
dd,
dl,
fieldset,
figure,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
legend,
p,
pre,
button,
ul {
  margin: 0;
  padding: 0;
}

img {
  max-width: 100%;
}
Run Code Online (Sandbox Code Playgroud)

我建立在来自https://open-wc.org/guide/#quickstart的文件夹结构脚手架之上

web-component lit-element

6
推荐指数
1
解决办法
2491
查看次数

使用 @angular/elements 为每个组件生成不同的 js 包

我有一个巨大的 Angular 应用程序,其中有几个组件导出为@angular/elements.

这些组件(尽管它们仍然使用共享服务和组件)用于网站的不同部分,该部分不是单页应用程序的一部分,而是由服务器提供的独立页面。

导出的角度元素 在新页面中运行良好,但我认为加载整个 SPA 包(si 5MB+)只是为了渲染两个组件是不可接受的。如何为每个角度元素生成不同的 javascript 文件?

我想像这样渲染我的组件:

<my-first-component />
<script src="./my-first-component.js"></script>

<my-second-component>
<script src="./my-second-component.js"></script>
Run Code Online (Sandbox Code Playgroud)

但是如果页面生成单个包,组件(或者更好的是自定义元素)将不会相互独立!很明显,在这种情况下,串联不起作用

我怎么解决这个问题?

谢谢

web-component custom-element angular angular-elements angular7

6
推荐指数
0
解决办法
326
查看次数

模板:命名空间自定义元素的名称以避免冲突

我们的平台建立在带有 Web 组件的微前端架构上。我们正在为其中一些使用 Stencil,这意味着我们在一个网页中有多个 Stencil 应用程序。此外,我们还有一个 UI 库,也是用 Stencil 构建的,我们希望在这些微前端组件中使用它。

我们希望使用 Stencil UI 库作为 Stencil 微前端组件的构建时依赖项。但由于标签名称冲突,目前这是不可能的:

理论上,两个微前端可以提供两个不同版本的 UI 库。但是,在运行时,它们会发生冲突,因为它们都试图用customElements.define. 当然,这不会发生,因为 Stencil 在注册新名称之前检查现有名称 - 但结果同样糟糕:第一个加载的组件总是获胜,如果它是旧版本或具有不同的 API,其他组件会打破。

一个解决方案是在构建或运行时命名空间/前缀标记名称,但网络标准中没有任何内容(尚未)。虽然namespaceStencil 中有一个配置选项,但这似乎并不能解决此类问题。

使用纯 ES6,我们至少可以执行以下操作(即使用动态标签名称注册自定义元素):

export class InnerComponent extends HTMLElement
{
    static register(prefix) {
        customElements.define(`my-${prefix}-inner-component`, InnerComponent)
    }

    constructor() {
        super()
        this.shadow = this.attachShadow({ mode: "open" })
    }

    connectedCallback() {
        this.shadow.innerHTML = `<span>this is some UI component</span>`
    }
}
Run Code Online (Sandbox Code Playgroud)

而且我确信我们可以在 Webpack 等中使用某种构建时解决方案来实现相同的目标。

但是 Stencil 是否有类似的可能?或者还有什么办法可以解决这个问题?

javascript web-component stenciljs micro-frontend

6
推荐指数
1
解决办法
533
查看次数

如何获取自定义元素的内容

我正在创建一个自定义元素,它将能够将其内容从 Markdown 转换为 HTML。但是,我无法获取自定义元素的内容。

<!doctype html>
<html>
<body>
   <template id="mark-down">
      <div class="markdown"></div>
   </template>
   <!-- Converts markdown to HTML -->
   <script src="https://cdn.jsdelivr.net/gh/showdownjs/showdown/dist/showdown.js"></script>
   <script>
      customElements.define('mark-down',
         class extends HTMLElement {
            constructor() {
               super()
               let template = document.querySelector('#mark-down').content
               this.attachShadow({ mode: 'open' }).appendChild(template.cloneNode(true))
            }
            connectedCallback() {
               console.log(this) // Returns the whole <mark-down> node and its contents
               console.log(this.innerHTML) // So why does this return a blank string?
               // This should theoretically work --> let markdown = this.innerHTML
               let markdown = '## Test'
               let converter …
Run Code Online (Sandbox Code Playgroud)

html javascript web-component

6
推荐指数
1
解决办法
510
查看次数