是的你可以。这只是正常现象@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
)。对象引用和函数不能用作属性的值。从技术上来说,仅string
s 可以是属性值,但 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>
`
}