我正在嘗試使用 lit Element 設計 Web 組件,我需要有關事件的幫助。正如我們從附加的代碼片段中看到的,我們可以@change="${this.handleEvent}"在 html 模板中使用并處理handleEvent(e){}lit Element 組件內的函式。通過這種方式,事件僅在點亮的 Web 組件中受到限制和控制。
但是,當其他人使用我們的 Web 組件時,他們無法控制或訪問定義組件中這些事件的值。那就是我們不能像<my-element onchange="handleEvent(e)"></my-element>.
那么,有沒有辦法實作與常規 html 事件類似的行為,而不是撰寫在 lit Element web 組件中受限的事件。
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>
<script type="module">
import { LitElement, html, css } from 'https://unpkg.com/lit-element/lit-element.js?module';
class MyElement extends LitElement {
static get properties() {
return {
checked: { type: Boolean, attribute: true }
};
}
static get styles() {
return [
css`
div {
padding: 10px;
width: 90px;
border: 2px solid orange;
}
`
];
}
render() {
return html`
<div>
<input
@change="${this.handleEvent}"
?checked="${this.checked}"
type="checkbox" /> Checkbox
</div>
`;
}
handleEvent(e) {
console.log(`Checkbox marked as: ${e.target.checked}`);
}
}
customElements.define('my-element', MyElement);
</script>
<my-element></my-element>
// I am expecting to pass an event and handle it in the importing component.
// Something like: **<my-element onchange="handleEvent(e)"}></my-element>**
uj5u.com熱心網友回復:
如果你想監聽元素之外的事件,你應該分派這樣的事件:
const event = new Event('my-event', {bubbles: true, composed: true});
myElement.dispatchEvent(event);
關于事件的 Lit 檔案很好地概述了如何以及何時調度事件https://lit.dev/docs/components/events/#dispatching-events
uj5u.com熱心網友回復:
通常,使用您自己的自定義元素,您可能還想定義自己的 API 以將其提供給組件的使用者。這通常還伴隨著定義您自己的組件發出的事件。
看這個簡單的(不亮,但你懂的)例子:
customElements.define('foo-bar', class extends HTMLElement {
input = document.createElement('input');
constructor() {
super();
this.input.type = 'checkbox';
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(this.input);
this.input.addEventListener('change', this.handleChange.bind(this));
}
// replaces the internal change event with an event you publish to the outside world
// this event is part of your defined API.
handleChange(e) {
e.stopPropagation();
const stateChange = new CustomEvent('state-change', {
bubbles: true,
composed: true,
detail: { checked: this.input.checked }
});
this.dispatchEvent(stateChange);
}
});
document.addEventListener('state-change', (e) => { console.log(e.detail); })
<foo-bar></foo-bar>
如果您還想像標準 HTML 元素一樣支持宣告性事件系結(并且使用它被廣泛認為是不好的做法),您可以使用觀察到的屬性來實作:
customElements.define('foo-bar', class extends HTMLElement {
input = document.createElement('input');
constructor() {
super();
this.input.type = 'checkbox';
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(this.input);
this.input.addEventListener('change', this.handleChange.bind(this));
this.declarativeValueChangeListener = this.declarativeValueChangeListener.bind(this);
}
// replaces the internal change event with an event you publish to the outside world
// this event is part of your defined API.
handleChange(e) {
e.stopPropagation();
const stateChange = new CustomEvent('state-change', {
bubbles: true,
composed: true,
detail: { value: this.input.value }
});
this.dispatchEvent(stateChange);
}
static get observedAttributes() {
return [ 'onstatechange' ];
}
attributeChangedCallback(attr, oldVal, newVal) {
if (oldVal === newVal) return; // nothing changed, nothing to do here
if (newVal === null) { // attribute was removed
this.removeEventListener('state-change', this.declarativeValueChangeListener)
} else { // attribute was added
this.addEventListener('state-change', this.declarativeValueChangeListener)
}
}
declarativeValueChangeListener() {
const functionStr = this.getAttribute(this.constructor.observedAttributes[0]);
eval(functionStr);
}
});
function baz() { console.log('baz executed through declarative binding of an outside handler!'); }
<foo-bar onstatechange="baz()"></foo-bar>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/339334.html
標籤:javascript 聚合物 瓦丁 网络组件 点亮元素
上一篇:如何只抓取字符的第一部分?
