我可以将函数作为属性传递给Web组件吗?

PS.*_*PS. 8 web-component custom-element native-web-component

我正在尝试为input元素创建一个本机Web组件.我希望该组件具有自定义验证功能,类似于聚合物的纸张输入自定义验证器功能.我不确定我是否可以将自定义验证器函数作为属性传递给(web组件)输入元素的实例.任何建议,将不胜感激.

Int*_*lia 9

最好通过属性传入函数,因为所有属性都是字符串。

如果必须将其作为属性传递,那么您需要将该字符串转换为函数。然后问题就变成了该函数的范围。

如果您假设该函数的作用域是全局的,那么您可以使用该字符串作为对象的属性名称window。要执行代码,您可以这样做:

window[fnName]();
Run Code Online (Sandbox Code Playgroud)

但这是相当有限的,因为您可能想调用自己的类或对象的成员函数。

您可以在名称中使用点符号func="myObj.fnName()",如果您不担心使用警告,eval您可以这样做:

eval(el.getAttribute('func'));

当然,这会让您面临各种可能的注入攻击。img但是,标签和标签也是如此script。

为了更安全,你可以尝试这样做:

设置属性时不带():

`func="myObj.fnName"`
Run Code Online (Sandbox Code Playgroud)

尝试进行调用的代码如下所示:

var parts = el.getAttribute('func').split('.');
var obj = window;
var found = parts.some( part => {
  var next = obj[part];
  if (next) {
    obj = next;
    return true;
  }
});

if (found) {
  obj();
}
Run Code Online (Sandbox Code Playgroud)

但这也会阻止您传递任何参数。

这种复杂性正是 AngularJS、React、Vue 等事物存在的原因。这也是我避免通过属性传入函数的原因。

如果您通过属性传递它,那么您的代码可能如下所示:

el.callme = globalfunc; // or
el.callme = this.localFunc; // or
el.callMe = (some params) => { /* do something */ };
Run Code Online (Sandbox Code Playgroud)

或者任何你想要的东西。

活动

说了这么多之后,我还建议做大多数本机组件所做的事情。也就是说,当需要做某事时,或者当某些事情发生变化并且外界可能对这些变化感兴趣时,调度一个事件。

在你的元素中你只需调用

this.dispatchEvent(new CustomEvent('event name', {bubbles: true, detail: {your detail}});
Run Code Online (Sandbox Code Playgroud)

然后任何关心您活动的人都会收听。


Sup*_*arp 5

属性是字符串,而不是函数。您可以将aa函数作为字符串传递,然后使用该函数对其求eval()值。出于安全原因,这不被视为一种好的做法。

另一种解决方案是将其作为Javascript属性传递给自定义元素:

function validate( value ) { return Number.isInteger( value) }
myCustomElement.validation = validate
Run Code Online (Sandbox Code Playgroud)

或者,使用箭头功能:

myCustomElement.validation = v => Number.isInteger( va )
Run Code Online (Sandbox Code Playgroud)

function validate( value ) { return Number.isInteger( value) }
myCustomElement.validation = validate
Run Code Online (Sandbox Code Playgroud)
myCustomElement.validation = v => Number.isInteger( va )
Run Code Online (Sandbox Code Playgroud)

  • 也不是最佳实践,但可以将全局方法名称作为字符串传递,并且可以在没有 eval 的情况下执行。 (2认同)