Skip to main content

“组件” 回调函数触发了,没有render

这两种方式都能触发this.handleSelectAbi 调用,但是只有前者可以触发render , 为什么

<button @click=${this.handleSelectAbi}>handleSelectAbi</button>
<abi-table .onClick=${this.handleSelectAbi} .datas=${this.abiList}></abi-table>

解决方案

  1. 使用回调,需要在 constructor 绑定到当前 lit 组件
  2. 使用事件,正常

这个问题可能与事件处理的绑定方式和组件的属性更新机制有关。让我们深入分析一下这两种情况:

1. 按钮点击事件

<button @click=${this.handleSelectAbi}>handleSelectAbi</button>

在这种情况下,点击按钮会直接调用 this.handleSelectAbi 方法,且这个方法内的 this 上下文是当前的 LitElement 实例。这样可以确保 this.abi 属性被正确更新,并触发重新渲染。

2. 自定义元素事件

<abi-table .onClick=${this.handleSelectAbi} .datas=${this.abiList}></abi-table>

在这种情况下,abi-table 组件的 onClick 属性被绑定到 this.handleSelectAbi 方法。这里可能存在以下几个问题:

  1. 事件绑定方式:确保 abi-table 组件内部正确触发了 onClick 事件。
  2. 上下文问题:确保 this.handleSelectAbi 方法在 abi-table 组件中被调用时,this 上下文仍然是当前的 LitElement 实例。

解决方案

1. 确保事件绑定正确

确保 abi-table 组件内部正确触发了 onClick 事件。例如:

class AbiTable extends LitElement {
// 假设你有一个方法触发点击事件
handleRowClick() {
const event = new Event('click', { bubbles: true, composed: true });
this.dispatchEvent(event);
}

render() {
return html`
<div @click=${this.handleRowClick}>Click me</div>
`;
}
}

customElements.define('abi-table', AbiTable);

2. 确保上下文正确 Ok

确保 this.handleSelectAbi 方法在 abi-table 组件中被调用时,this 上下文仍然是当前的 LitElement 实例。你可以使用箭头函数来确保上下文正确:

<abi-table .onClick=${(event) => this.handleSelectAbi(event.detail)} .datas=${this.abiList}></abi-table>

或者在 constructor 中绑定上下文:

constructor() {
super();
this.handleSelectAbi = this.handleSelectAbi.bind(this);
}

示例代码

确保 abi-table 组件正确触发事件,并确保上下文正确:

// abi-table.js
import { LitElement, html } from 'lit';

class AbiTable extends LitElement {
handleRowClick() {
const event = new CustomEvent('click', { detail: { abi: '{"name": "John", "age": 30}' }, bubbles: true, composed: true });
this.dispatchEvent(event);
}

render() {
return html`
<div @click=${this.handleRowClick}>Click me</div>
`;
}
}

customElements.define('abi-table', AbiTable);
// my-element.js
import { LitElement, html } from 'lit';
import { state, customElement } from 'lit/decorators.js';
import './abi-table.js';

@customElement('my-element')
class MyElement extends LitElement {
@state() abi = [];

constructor() {
super();
this.handleSelectAbi = this.handleSelectAbi.bind(this);
}

handleSelectAbi(event) {
const item = event.detail;
console.log("item", item);
try {
this.abi = JSON.parse(item.abi);
console.log("handleSelectAbi", this.abi); // 验证解析后的结果
this.requestUpdate(); // 强制触发更新
} catch (error) {
console.error("Failed to parse ABI", error);
}
}

render() {
console.log("render abi", this.abi); // 验证渲染时的 abi 值
return html`
<button @click=${this.handleSelectAbi}>handleSelectAbi</button>
<abi-table .onClick=${(event) => this.handleSelectAbi(event)} .datas=${this.abiList}></abi-table>
<pre>${JSON.stringify(this.abi, null, 2)}</pre>
`;
}
}

通过确保事件绑定和上下文正确,应该能够解决 render 方法没有被触发的问题。