是否可以将函数传递给stencilJs
组件?
类似的东西:
@Prop() okFunc: () => void;
我有一个模态,想要动态调用模态页脚中单击的Ok
按钮上的传递函数,就像普通HTML按钮上的onClick
一样。
答案 0 :(得分:2)
您只需向任何组件添加@Prop() someFunc: Function
,然后从外部传递即可
<any-component someFunc={() => console.log('coming from the outside')} />
在anyComponent中,只需检查if (this.someFunc) { this.someFunc() }
答案 1 :(得分:2)
是的,可以。它只是一个普通的@Prop()
声明,在TSX中可以很好地发挥作用。但是...
如另一个答案和注释中所述,如果您使用纯HTML格式的Stencil组件,则将无法使用Stencil的attribute-prop绑定将函数(或任何非标量值)传递给道具通过HTML属性。
这意味着如果要附加事件或将功能属性传递到Stencil组件,则必须与DOM交互。一旦您的组件进入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) => { ... })
如果出于某些原因绝对必须在HTML文档中执行此操作,
<my-stencil-component ... >...</my-stencil-component>
<script>
var componentInstance = document.currentScript.previousElementSibling
componentInstance.someFunc = function(...) { ... }
</script>
认识到Properties ≠ Attributes
很重要。道具是JavaScript Properties,在这种情况下,代表元素的DOM对象的属性。 Attributes是XML属性,尽管HTML属性具有一些独特的特征,并且其行为与典型的XML稍有不同。
在可能的情况下,模具将自动为您的属性“绑定” HTML属性,尤其是标量值(boolean
,number
,string
)。对象引用及其功能不能用作属性的值。从技术上讲,只有string
是属性值,但是当您指定类型时,Stencil足够聪明,可以将string
转换为其他标量类型(boolean
或number
)。您的@Prop()
。
我为团队开发了一种解决方案,可以使用MutationObserver
将包含JSON的属性绑定到Stencil属性。它基本上会监视特殊属性bind-json
,然后将以json-
开头的属性映射到相应的camelCase 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,而且对all kinds of other reasons I won't get into here来说也是个问题,使用它实际上会使您的应用在任何现代安全检查中都自动失效。
在故事书的故事中,我们将回调函数定义绑定到window
,并使用<script>
标签和document.currentScript
或querySelector
将函数prop和事件绑定传递给组件实例:
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>
`
}