hellof2e / quark-core

Fast 4Kb size! Web Components with JSX. (Web Components 构建工具,4kb!构建跨技术栈组件)
https://quark-ecosystem.github.io/quarkc-docs/#/
MIT License
321 stars 27 forks source link

依赖的组件的自定义事件无法被监听 #75

Closed topazur closed 2 months ago

topazur commented 2 months ago

我有一个已封装的 sh-tag 组件,内部抛出了 sh-close 事件,但是我在另一个 web-components 组件中无法监听该事件?是要用 addEventListener 才行吗?但是遍历的tag有很多个?也无法做事件委托

这是另一个 web-components 组件使用 sh-tag 的部分代码:

<div>
{
  plainList.map((item, idx) => {
    return (
      <sh-tag
        key={`plain_${item}__${idx}`}
        className="overflow-item"
        closable
        onShClose={(e) => {
          console.log('不触发: ', 1, e)
        }}
        onShclose={(e) => {
          console.log('不触发: ', 2, e)
        }}
        onshClose={(e) => {
          console.log('不触发: ', 3, e)
        }}
        onshclose={(e) => {
          console.log('不触发: ', 4, e)
        }}
        onclose={(e) => {
          console.log('不触发: ', 5, e)
        }}
        onClick={(e) => {
          console.log('原生的click事件,不符合: ', 6, e)
        }}
      >
        {item}
      </sh-tag>
    )
  })
}
</div>
topazur commented 2 months ago

sh-tag:

// this.$emit('sh-close', event)
this.dispatchEvent(new Event('sh-close', event))

另一个 web-components 组件:

componentDidMount() {
    this.$on('sh-close', (e) => {
      console.log('[vscode-log] index.tsx@Line 65:1 ', e) // 只能监听 dispatchEvent 发出的事件
    })
    this.addEventListener('sh-close', (e) => {
      console.log('[vscode-log] index.tsx@Line 65:2 ', e) // 只能监听 dispatchEvent 发出的事件
    })
  }

直接在html中使用:

<sh-tag id="case1_closable" closable animable>可关闭</sh-tag>

<script>
        case1_closable.addEventListener('sh-close', (event) => {
          console.log("[vscode-log] index.html@Line 110: ", event); // 监听 dispatchEvent 和 $emit 发出的事件
        })
</script>

只有 dispatchEvent发出的事件可以被其他web-components监听,我的测试结果是这样的。 那感觉 dispatchEvent 的能力更加强大,已经满足需求了,为什么还要封装 $emit 呢

topazur commented 2 months ago

$emit 加了 { bubbles: true }

dyf19118 commented 2 months ago

看下来问题是发生在quarkc组件彼此嵌套时?

增加$emit应该是为了迎合vue用户在书写组件时的习惯。

topazur commented 2 months ago

好的,上述问题已解决

dyf19118 commented 2 months ago

好的,上述问题已解决

好的。

顺带一提,由于quarkc在处理事件分发时没有像vue/react那样对camelCase或kebab-case风格的自定义事件名进行标注化处理。 因此当你使用this.$emit('sh-close')时,事件对象监听的事件名也应当是'sh-close'(而这对于JSX语法来说是不支持的)。 所以你可以选择不用kebab-case,而是使用像shclose(对应onshclose)或shClose(对应onshClose)这样的名称作为$emit的事件名。

topazur commented 2 months ago

好的,上述问题已解决

好的。

顺带一提,由于quarkc在处理事件分发时没有像vue/react那样对camelCase或kebab-case风格的自定义事件名进行标注化处理。 因此当你使用this.$emit('sh-close')时,事件对象监听的事件名也应当是'sh-close'(而这对于JSX语法来说是不支持的)。 所以你可以选择不用kebab-case,而是使用像shclose(对应onshclose)或shClose(对应onshClose)这样的名称作为$emit的事件名。

谢谢,很有帮助!