Vanilla JS异步Web Component:connectedCallback中menuData始终undefined求助
问题分析与解决方案
你的代码里有三个核心问题导致this.menuData始终为undefined:
response.json()未使用await:response.json()返回的是Promise对象,直接赋值给this.menuData会导致它是未resolved的Promise,而非实际的接口返回数据。- 静态
render方法的this指向错误:你定义的static render是箭头函数,静态方法中的箭头函数不会绑定类的上下文,且静态方法本身的this指向类(NavigationMenu)而非实例,根本访问不到实例的menuData。 - 调用
render的方式错误:connectedCallback里调用的是静态的NavigationMenu.render(),不是当前实例的方法,无法获取实例的menuData。
修正后的完整代码
class NavigationMenu extends HTMLElement { constructor() { super(); this.menuData = ''; this.loading = false; this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = ` <style> nav { display: flex; flex-direction: row; gap: 1rem; } </style> <nav id="NavigationMain"></nav> `; } async fetchMenuEndpoint(url) { this.loading = true; try { const response = await fetch(url); // 等待Promise解析为实际JSON数据 const json = await response.json(); this.menuData = json; // 数据获取后调用实例的render方法 this.render(); } catch (error) { console.error('菜单数据获取失败:', error); } this.loading = false; } async connectedCallback() { await this.fetchMenuEndpoint('/?view=navigation'); } // 改为实例方法,而非静态方法 render() { console.log(this.menuData); // 可添加渲染菜单到DOM的逻辑示例 const nav = this.shadowRoot.getElementById('NavigationMain'); if (this.menuData && this.menuData.length) { nav.innerHTML = this.menuData.map(item => `<a href="${item.url}">${item.label}</a>`).join(''); } }; } customElements.define('navigation-menu', NavigationMenu);
关键修正点说明
- 添加
await到response.json():确保获取到实际的JSON数据再赋值给this.menuData。 - 将
render改为实例方法:移除static关键字,让render里的this指向当前组件实例,正常访问this.menuData。 - 在
fetchMenuEndpoint成功回调中调用this.render():确保数据获取完成后再执行渲染逻辑,避免提前调用导致数据未加载。 - 移除静态方法调用:不再调用
NavigationMenu.render(),转而使用实例的this.render()。
内容的提问来源于stack exchange,提问作者Alex Herascu
相关产品推荐
相关产品推荐

