You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript Web Component中传递对象作为自定义元素属性

如何将对象作为Property传递给自定义元素

这个问题我之前也碰到过,自定义元素的attribute和property确实容易搞混——attribute本质上都是字符串类型,所以直接把对象通过${data}塞到attribute里,最终只会得到[object Object]这样的无效字符串,完全没法用。要传递复杂数据(比如数组、对象),直接操作自定义元素的property才是正确的路子,下面给你两种可行的方案:

方案1:直接设置自定义元素的Property(推荐)

这种方式最直接,因为自定义元素本质是JS类的实例,直接给它的实例设置property就和操作普通JS对象一样。

第一步:在自定义元素类中定义data Property

在组件的JS文件里,给自定义元素类添加data的getter和setter,这样设置数据时还能自动触发UI更新:

class MyDropdownList extends HTMLElement {
  // 存储内部数据
  _data = [];

  // 定义data的getter
  get data() {
    return this._data;
  }

  // 定义data的setter,设置时自动更新UI
  set data(newData) {
    this._data = Array.isArray(newData) ? newData : [];
    this.render(); // 调用渲染方法更新界面
  }

  // 元素挂载到DOM时初始化渲染
  connectedCallback() {
    this.render();
  }

  // 根据data渲染列表的示例方法
  render() {
    this.innerHTML = `
      <ul>
        ${this.data.map(item => `
          <li>
            ${item.name} 
            <span>${item.expand ? '✅ 展开' : '🔴 收起'}</span>
          </li>
        `).join('')}
      </ul>
    `;
  }
}

// 注册自定义元素
customElements.define('my-dropdown-list', MyDropdownList);

第二步:在主JS中给元素实例设置Property

HTML里只需要写空的自定义元素标签,然后在JS中获取实例并设置data:

<!-- HTML部分 -->
<my-dropdown-list></my-dropdown-list>
// 主JS部分
const data = [ 
  { name: "Peter", expand: false }, 
  { name: "Max", expand: false }, 
  { name: "Lucy", expand: true } 
];

// 获取自定义元素实例
const dropdownList = document.querySelector('my-dropdown-list');
// 直接设置data property
dropdownList.data = data;

这样设置后,自定义元素就能拿到完整的数组对象,而且后续如果data有更新,直接重新赋值dropdownList.data = newData就能自动触发UI更新。

方案2:通过JSON字符串Attribute同步到Property(适合静态数据)

如果你的数据是静态的,或者希望在HTML标签里直接写数据,可以把对象转成JSON字符串作为attribute传递,然后在自定义元素里监听这个attribute的变化,解析后同步到property。

第一步:修改自定义元素类,监听Attribute变化

class MyDropdownList extends HTMLElement {
  _data = [];

  // 声明要监听的attribute
  static get observedAttributes() {
    return ['data-json'];
  }

  get data() {
    return this._data;
  }

  set data(newData) {
    this._data = Array.isArray(newData) ? newData : [];
    this.render();
  }

  // 当监听的attribute变化时触发
  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'data-json' && newValue !== oldValue) {
      try {
        // 解析JSON字符串为对象/数组
        this.data = JSON.parse(newValue);
      } catch (error) {
        console.error('解析data-json失败:', error);
        this.data = [];
      }
    }
  }

  connectedCallback() {
    this.render();
  }

  render() {
    // 和方案1的render方法一致
    this.innerHTML = `
      <ul>
        ${this.data.map(item => `
          <li>
            ${item.name} 
            <span>${item.expand ? '✅ 展开' : '🔴 收起'}</span>
          </li>
        `).join('')}
      </ul>
    `;
  }
}

customElements.define('my-dropdown-list', MyDropdownList);

第二步:在HTML中传递JSON字符串Attribute

注意这里的JSON字符串必须用单引号包裹,内部属性用双引号,保证格式正确:

<my-dropdown-list data-json='[{"name":"Peter","expand":false},{"name":"Max","expand":false},{"name":"Lucy","expand":true}]'></my-dropdown-list>

这种方式适合静态数据,如果是动态数据,还是方案1更灵活。

内容的提问来源于stack exchange,提问作者sumit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 15:19:04