我们能否将 Blazor 组件呈现为独立的 DOM 片段,或以其他方式在普通 HTML/JS 页面中作为标准 Web 组件使用?
从 Blazor 架构角度来看,这可能是一个天真的问题。我远非 Blazor 专家,但我认为它可以成为遗留 Web 应用程序增量式“棕地”现代化的有用技术。我惊讶地发现官方似乎不支持这种方法。
举例来说,考虑这个简单的 Web 组件示例,它呈现了一个自定义元素 <date-info>
:
// define a custom web component
customElements.define("date-info", class DateInfo extends HTMLElement {
constructor() {
super();
// create an "open" (vs "closed") shadow DOM,
// i.e., accessible to the outside JavaScript
this.attachShadow({ mode: "open" });
}
async connectedCallback() {
console.log(`${this.constructor.name}.${this.connectedCallback.name} called`);
// get the content from the server,
// this could be a Blazor component markup
try {
const response = await fetch("https://worldtimeapi.org/api/ip");
const data = await response.json();
const content = new Date(data.utc_datetime).toString();
this.shadowRoot.innerHTML = `<span>${content}</span>`;
}
catch(e) {
console.error(e);
const info = document.createTextNode(e.message);
this.shadowRoot.appendChild(info);
}
}
});
<!-- use the web component -->
<p>Current time: <date-info/></p>
https://worldtimeapi.org/api/ip
,而是要获取并呈现 Blazor/Server 组件的分离标记,例如:@* this is a Blazor component *@
<p>@(DateTime.Now)</p>
此外,我希望这个标记保持功能和动态性,即客户端DOM事件和服务器端更新对于这个Blazor组件的包装Web组件的生命周期进一步传播。可以将其设置为Blazor @page并加载到iframe中,但我更想将其呈现为外部页面DOM的一部分。到目前为止,我遇到了以下问题:显然,这不是2018年Blazor设计目标之一:https://github.com/dotnet/aspnetcore/issues/16033。后来,Steve Sanderson创建了一个(非官方)库来测试隔离的Blazor组件,理论上可以用来获得独立的Blazor组件标记:https://dev59.com/w1IH5IYBdhLWcg3wOrO7#60457390。到目前为止,这是解决这个问题的最佳方法吗?