通过自定义事件通信的 Webcomponents 无法发送数据
Webcomponents communicating by custom events cannot send data
我对 webcomponents 很感兴趣(并且对 javascript 很陌生),我正在尝试设置一个虚拟的微前端应用程序。好的,组件由不同的 Web 服务器(老实说是 webpack devserver)提供服务,并正确显示在 'aggregator' 页面中。我还添加了一个 customevent 以将一些文本从一个 web 组件发送到另一个,但这是行不通的。这是发件人网络组件:
const tmplt = document.createElement('template');
tmplt.innerHTML = `
<div>
<label for="sendnpt">message:</label>
<input id="sendnpt" type="text"></input>
<button id="sendbtn">Send the message</button>
<div id="msglog"></div>
</div>
`;
var input = {};
window.customElements.define('team-zero', class TeamZero extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(tmplt.content.cloneNode(true));
this.button = this._shadowRoot.getElementById('sendbtn');
input = this._shadowRoot.getElementById('sendnpt');
this.button.addEventListener('click', function(evt) {
var msg = {
bubbles: true,
detail: {}
};
msg.detail.name = input.value;
console.log('sending msg: ' + JSON.stringify(msg))
window.dispatchEvent(new CustomEvent('greet', msg));
});
}
connectedCallback() {
console.log('connected and ready!');
}
});
这是收件人:
const m = require('mithril');
window.customElements.define('team-one', class TeamOne extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
window.addEventListener('greet', (msg) => {
console.log("a message arrives: " + JSON.stringify(msg));
});
}
connectedCallback() {
console.log('connected!');
m.mount(this._shadowRoot, {
view: function(vnode) {
return m("div", "team-0ne runs mithril!");
}
});
}
});
问题是发出并接收了事件,但其中没有 detail
。为什么接收器组件无法记录另一个正在发送的文本,我错过了什么?
您可以看到整个虚拟项目[=13=]。
不同于 click
、
等默认事件
自定义事件需要 composed:true
到 'escape' shadowDOM
注意:除了数据你还可以传递函数引用
window.customElements.define('my-element', class extends HTMLElement {
constructor() {
super().attachShadow({mode:'open'}).innerHTML = `<slot></slot>`;
let report = (evt) =>
document.body.append(
document.createElement("br"),
`${this.id} received: ${evt.type} - detail: ${JSON.stringify(evt.detail)} `,
evt.detail.callback && evt.detail.callback(this.id) // not for 'click' event
);
window.addEventListener('greet', report); // Custom Event
window.addEventListener('click', report); // button click
this.onclick = () =>
window.dispatchEvent(new CustomEvent('greet', {
bubbles: true,
composed: true,
detail: {
fromid: this.id,
callback: this.callback.bind(this)
}
}));
}
callback(payload){
return `${this.id} executed callback function(${payload})`;
}
});
<my-element id=ONE><button>Click One</button></my-element>
<my-element id=TWO><button>Click Two</button></my-element>
另见:https://pm.dartus.fr/blog/a-complete-guide-on-shadow-dom-and-event-propagation/
我对 webcomponents 很感兴趣(并且对 javascript 很陌生),我正在尝试设置一个虚拟的微前端应用程序。好的,组件由不同的 Web 服务器(老实说是 webpack devserver)提供服务,并正确显示在 'aggregator' 页面中。我还添加了一个 customevent 以将一些文本从一个 web 组件发送到另一个,但这是行不通的。这是发件人网络组件:
const tmplt = document.createElement('template');
tmplt.innerHTML = `
<div>
<label for="sendnpt">message:</label>
<input id="sendnpt" type="text"></input>
<button id="sendbtn">Send the message</button>
<div id="msglog"></div>
</div>
`;
var input = {};
window.customElements.define('team-zero', class TeamZero extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(tmplt.content.cloneNode(true));
this.button = this._shadowRoot.getElementById('sendbtn');
input = this._shadowRoot.getElementById('sendnpt');
this.button.addEventListener('click', function(evt) {
var msg = {
bubbles: true,
detail: {}
};
msg.detail.name = input.value;
console.log('sending msg: ' + JSON.stringify(msg))
window.dispatchEvent(new CustomEvent('greet', msg));
});
}
connectedCallback() {
console.log('connected and ready!');
}
});
这是收件人:
const m = require('mithril');
window.customElements.define('team-one', class TeamOne extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
window.addEventListener('greet', (msg) => {
console.log("a message arrives: " + JSON.stringify(msg));
});
}
connectedCallback() {
console.log('connected!');
m.mount(this._shadowRoot, {
view: function(vnode) {
return m("div", "team-0ne runs mithril!");
}
});
}
});
问题是发出并接收了事件,但其中没有 detail
。为什么接收器组件无法记录另一个正在发送的文本,我错过了什么?
您可以看到整个虚拟项目[=13=]。
不同于 click
、
等默认事件
自定义事件需要 composed:true
到 'escape' shadowDOM
注意:除了数据你还可以传递函数引用
window.customElements.define('my-element', class extends HTMLElement {
constructor() {
super().attachShadow({mode:'open'}).innerHTML = `<slot></slot>`;
let report = (evt) =>
document.body.append(
document.createElement("br"),
`${this.id} received: ${evt.type} - detail: ${JSON.stringify(evt.detail)} `,
evt.detail.callback && evt.detail.callback(this.id) // not for 'click' event
);
window.addEventListener('greet', report); // Custom Event
window.addEventListener('click', report); // button click
this.onclick = () =>
window.dispatchEvent(new CustomEvent('greet', {
bubbles: true,
composed: true,
detail: {
fromid: this.id,
callback: this.callback.bind(this)
}
}));
}
callback(payload){
return `${this.id} executed callback function(${payload})`;
}
});
<my-element id=ONE><button>Click One</button></my-element>
<my-element id=TWO><button>Click Two</button></my-element>
另见:https://pm.dartus.fr/blog/a-complete-guide-on-shadow-dom-and-event-propagation/