如何将JavaScript对象和函数传递给Web组件

13

大家好,我是一名JavaScript的初学者,目前正在探索JS Web组件,但由于某些用例而遇到了困难。

1) 我想将一个JS对象传递到我的组件中,例如:

<my-component data=obj ></my-component> 

需要在我的组件代码中使用,例如:

And require to use inside my component code Like

需要在我的组件代码中使用,如下所示:
connectedCallback () {
    console.log(this.data) // it should print {"name":"xyz" , "role" : "dev"}
} 

2 ) 我还需要传递一些函数或者可能是回调函数,例如:

function myFunction(e){
   console.log(e)
}

<my-component click=myFunction ></my-component>

请尝试在答案中添加代码片段,这将帮助我更好地学习JS。 谢谢

4个回答

18
你应该通过JavaScript传递大型对象。
通过自定义元素方法:
let comp = document.querySelector( 'my-component' )
comp.myMethod( obj )

或者设置属性:

comp.data = obj

1
对于函数而言,它们都是相同的。如果使用 LitHTML,则有一种特殊的语法来通过属性传递对象 <my-comp .things=${myObj}>... 但使用 JavaScript 方式是更好的选择。 - Yves Lange

13

最好使用属性而不是属性来传递复杂数据。

myEl.data = {a:1,b:'two'};

在自定义元素上,标准的 on 事件可以很好地工作:

function myFunction(e){
  alert(JSON.stringify(e.target.data));
  e.target.data = {a:1,b:"two"};
}

class MyComponent extends HTMLElement {
  constructor() {
    super();
    this._data = 0;
    this.attachShadow({mode:'open'}).innerHTML="Click Me";
  }

  static get observedAttributes() {
    return ['data'];
  }

  attributeChangedCallback(attrName, oldVal, newVal) {
    if (oldVal !== newVal) {

    }
  }

  get data() {
    return this._data;
  }
  set data(newVal) {
    this._data = newVal;
  }
}

customElements.define('my-component', MyComponent);
<my-component onclick="myFunction(event)"></my-component>

如果你的组件触发了自定义事件,那么最好通过代码来访问它:

function specialEventHandler(evt) {
  // do something
}

myEl.addEventListener('special-event;', specialEventHandler);

这种做法相对于通过属性传递的方式来说,究竟有何优势呢?我感觉两种方式同样复杂。 - Ringo
3
通过属性传递是简单的JS:el.property = {complex value} 通过属性传递需要解析逻辑。 - Intervalia

7

我曾参加过与Andreas Galster一起开设的Udemy课程,导师通过属性传递了一个JSON对象。

正如您所看到的,它还需要使用encodeURIComponent和decodeURIComponent来进行转换。

attributeChangedCallback (name, oldValue, newValue) {
        if (newValue && name === 'profile-data') {
            this.profileData = JSON.parse(decodeURIComponent(newValue));
            this.removeAttribute('profile-data');
        }
    
        this.render();
    }

传入:

<profile-card profile-data=${encodeURIComponent(JSON.stringify(profile))}>

</profile-card>

这段代码在我的机器上运行良好。


只有在 JavaScript 空间中使用组件时才有效。如果组件在 HTML 文档中使用,我该怎么做? - chovy
@chovy 你可以在HTML文件中添加一个脚本标签,或者只需包含一个单独的JS文件。 - Travis Howell

1

广告1) 您需要使用JSON.stringify(obj)

广告2) 据我所知,所有属性都需要定义为字符串。您可以传递全局函数,并在组件内尝试使用eval(fn)


嗨,感谢您的回答。1)我已经尝试了JSON.stringify(obj),但它没有给我完整的数据,可能有一些属性长度限制。2)eval(fun)也无法工作,因为该组件在影子DOM中呈现,而不是在实际DOM中,所以存在范围问题。 - Vikrant Agrawal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接