将函数传递给模板组件

2024-01-05

是否可以将函数传递给stencilJs成分?

就像是:

@Prop() okFunc: () => void;

我有一个模态,想要动态调用传递的函数Ok在模态页脚中单击按钮,就像onClick在普通的 HTML 按钮上。


是的你可以。这只是正常现象@Prop()声明并在多伦多证券交易所表现得非常好。然而...

正如另一个答案和评论中所述,如果您使用纯 HTML 格式的 Stencil 组件,您将无法使用 Stencil 的 attribute-prop 绑定通过以下方式将函数(或任何非标量值)传递给 prop: HTML 属性。

使用 DOM API

这意味着你必须与 DOM 交互如果您想附加事件或将函数属性传递给 Stencil 组件。一旦您的组件进入 DOM,与任何其他自定义元素相比,它实际上没有什么特别之处。

如果没有 JSX 或其他模板 DSL(例如 Angular),您将需要附加事件并使用 JavaScript DOM API 设置函数或对象引用属性:

const componentInstance = document.querySelector('my-stencil-component')

// This works and will trigger a rerender (as expected for a prop change)
componentInstance.someFunc = (...) => { ... }

// This works for any event, including custom events fired from Stencil's EventEmitter
componentInstance.addEventListener('myCustomEvent', (event: MyCustomEvent) => { ... })

如果你绝对must由于某种原因,请在 HTML 文档中执行此操作:

<my-stencil-component ... >...</my-stencil-component>
<script>
  var componentInstance = document.currentScript.previousElementSibling
  componentInstance.someFunc = function(...) { ... }
</script>

为什么我必须这样做?

重要的是要认识到这一点Properties ≠ Attributes。道具有JavaScript 属性 https://developer.mozilla.org/en-US/docs/Glossary/property/JavaScript,在本例中,是表示元素的 DOM 对象的属性。属性 https://developer.mozilla.org/en-US/docs/Glossary/Attribute是 XML 属性,尽管 HTML 属性具有一些独特的特征并且其行为与典型 XML 略有不同。

Stencil 将在可能的情况下自动将 HTML 属性“绑定”到属性 - 特别是对于标量值(boolean, number, string)。对象引用和函数不能用作属性的值。从技术上来说,仅strings 可以是属性值,但 Stencil 足够智能,可以进行转换string到其他标量类型(boolean or number)当您指定您的类型时@Prop().


其他解决方案

我为我的团队开发了一个解决方案,使用以下方法将包含 JSON 的属性绑定到 Stencil 属性:MutationObserver。它基本上监视一个特殊属性bind-json,然后映射以开头的属性json-到相应的驼峰命名法 DOM 属性上。用法如下:

<my-stencil-component
  bind-json
  json-prop-name='{ "key": "value" }'>
</my-stencil-component>

随着MutationObserver在适当的情况下,这与以下内容相同:

const componentInstance = document.querySelector('my-stencil-component')
componentInstance.propName = JSON.parse(componentInstance.getAttribute('json-prop-name'))

然而,对于绑定确​​实没有令人满意的解决方案功能纯 HTML 格式。如果没有某种丑陋的黑客手段,这真的是不可能完成的eval在另一条评论中描述。这不仅会污染组件的 API,还会带来问题由于各种其他原因我不会进入这里 https://stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil并且它的使用将自动使您的应用程序在几乎任何现代安全检查中失败。

在我们的 Storybook 故事中,我们将回调函数定义绑定到window,并使用<script>标签和document.currentScript or querySelector将函数 props 和事件绑定传递给组件实例:

const MyStory = ({ ... }) => {
  window.myStoryFunc = () => { ... }
  window.myStoryClickHandler = () => { ... }
  return `
    <my-stencil-component ... >...</my-stencil-component>
    <script>
      const componentInstance = document.currentScript.previousElementSibling
      componentInstance.someFunc = window.myStoryFunc
      componentInstance.addEventListener('click', window.myStoryClickHandler)
    </script>
  `
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将函数传递给模板组件 的相关文章