在另一个内部创建一个 web 组件并将其附加到另一个上是否是一种不好的做法?
Is it bad practice to create a web-component inside another and append it to said other?
基本上我有一个 Web 组件 "x" 并且我在 "x" 中动态创建了一个表单组件,它将附加到 "x".
当然,我可以在创建 "x" 的地方进行,在创建 "x" 之后。
基本上是这样的:
class X extends LitElement {
render() {
return html`
<div>
<slot name="form-component">${this.appendFormComponent()}</slot>
</div>
<slot></slot>
`
}
appendFormComponent() {
const formComponent = document.createElement('input')
formComponent.slot = "form-component"
this.append(formComponent)
}
// side note, is running this append inside the render function a terrible
// idea and where should I do it instead? I mean doing it in the render
// function does appear to work...
}
正如您所怀疑的,这绝对是一个糟糕的想法,因为您将 命令式 范式与 声明式 范式混合在一起。但是,如果您确实需要这样做并且因为您正在使用 LitElement,您可以使用适当的生命周期方法很好地抽象声明性和命令性 UI 代码:
class X extends LitElement {
render() {
return html`
<div>
<slot name='form-component'></slot>
</div>
<slot></slot>
`;
}
// Executed only once
firstUpdated() {
const formComponent = document.createElement('input');
formComponent.slot = 'form-component';
this.append(formComponent);
}
}
此外,您尝试的方法可能存在问题。仅通过渲染功能即可轻松解决您的问题:
class X extends LitElement {
render() {
return html`
<div>
<slot name='form-component'>
<!-- Notice the use of INPUT TAG here -->
<input type='text' />
</slot>
</div>
<slot></slot>
`;
}
}
使用 firstUpdated
和 document.createElement
之类的东西应该用来创建 UI 组件,这些组件具有打破 UI 作为函数的偏移元素State 概念。这些组件是日期选择器、多 select 下拉菜单、对话框等,它们直接将 DOM 元素附加到 body 以准确管理 Z-index 和固定定位。
此外,根据您的评论,如果您有需要分配给输入文本的动态函数,只需创建一个包装函数,例如:
class X extends LitElement {
// Input change event handler
onChange() {
// A guard to check presence of dynamic function
if (this.someDynamicFuction) {
this.someDynamicFuction();
}
}
render() {
return html`
<div>
<slot name='form-component'>
<!-- Notice the use of INPUT TAG here -->
<input type='text' @change=${this.onChange} />
</slot>
</div>
<slot></slot>
`;
}
}
基本上我有一个 Web 组件 "x" 并且我在 "x" 中动态创建了一个表单组件,它将附加到 "x".
当然,我可以在创建 "x" 的地方进行,在创建 "x" 之后。
基本上是这样的:
class X extends LitElement {
render() {
return html`
<div>
<slot name="form-component">${this.appendFormComponent()}</slot>
</div>
<slot></slot>
`
}
appendFormComponent() {
const formComponent = document.createElement('input')
formComponent.slot = "form-component"
this.append(formComponent)
}
// side note, is running this append inside the render function a terrible
// idea and where should I do it instead? I mean doing it in the render
// function does appear to work...
}
正如您所怀疑的,这绝对是一个糟糕的想法,因为您将 命令式 范式与 声明式 范式混合在一起。但是,如果您确实需要这样做并且因为您正在使用 LitElement,您可以使用适当的生命周期方法很好地抽象声明性和命令性 UI 代码:
class X extends LitElement {
render() {
return html`
<div>
<slot name='form-component'></slot>
</div>
<slot></slot>
`;
}
// Executed only once
firstUpdated() {
const formComponent = document.createElement('input');
formComponent.slot = 'form-component';
this.append(formComponent);
}
}
此外,您尝试的方法可能存在问题。仅通过渲染功能即可轻松解决您的问题:
class X extends LitElement {
render() {
return html`
<div>
<slot name='form-component'>
<!-- Notice the use of INPUT TAG here -->
<input type='text' />
</slot>
</div>
<slot></slot>
`;
}
}
使用 firstUpdated
和 document.createElement
之类的东西应该用来创建 UI 组件,这些组件具有打破 UI 作为函数的偏移元素State 概念。这些组件是日期选择器、多 select 下拉菜单、对话框等,它们直接将 DOM 元素附加到 body 以准确管理 Z-index 和固定定位。
此外,根据您的评论,如果您有需要分配给输入文本的动态函数,只需创建一个包装函数,例如:
class X extends LitElement {
// Input change event handler
onChange() {
// A guard to check presence of dynamic function
if (this.someDynamicFuction) {
this.someDynamicFuction();
}
}
render() {
return html`
<div>
<slot name='form-component'>
<!-- Notice the use of INPUT TAG here -->
<input type='text' @change=${this.onChange} />
</slot>
</div>
<slot></slot>
`;
}
}