Subscribe on changes!

CustomElement: Additional event arguments of CustomEvent

avatar
Feb 5th 2023

What problem does this feature solve?

In standard js CustomElement api, the detail property can be any type. But when use this.$emit or setup emit on the custom element, additional event arguments (payload) will be exposed as an array on the CustomEvent object as its detail property, it is not convenient for users to use and not match the original javascript standard. So I think when we only pass one additional event argument, it shouldn't be exposed as an array.

What does the proposed API look like?

When only passing one additional event argument:

  • component code:
<script setup>
const emit = defineEmits(['getValue'])

function buttonClick() {
  emit('getValue', 8)
}
</script>
  • user use code:
<template>
  <my-element @customClick={getValue}></my-element>
</template>
<script setup>
function getValue(e) {
  console.log('value is: ' + e.detail) // value is: 8
}
</script>

When only passing one multiple event arguments:

  • component code:
<script setup>
const emit = defineEmits(['getValues'])

function buttonClick() {
  emit('getValues', 1, 2, 3)
}
</script>
  • user use code:
<template>
  <my-element @customClick={getValues}></my-element>
</template>
<script setup>
function getValues(e) {
  console.log('value is: ' + e.detail) // value is: [1, 2, 3]
}
</script>
avatar
Feb 5th 2023

I'm confused. You say additional event content should not be exposed as an array. But your "proposed API" example shows just that: the arguments being exposed as an array.

So which is it? And if now an array, how should it work?

avatar
Feb 6th 2023

I'm confused. You say additional event content should not be exposed as an array. But your "proposed API" example shows just that: the arguments being exposed as an array.

So which is it? And if now an array, how should it work?

There are two examples in my "proposed API". My mean is when the number of additional event argument is 1, it should be exposed as itself; and when the number of additional event argument is more that one, it should be exposed as an array.

avatar
Feb 6th 2023

给个标准连接呢,我查mdn没有查到,如果真的不符合原始行为,我觉得还是有必要做加强

avatar
Feb 6th 2023

给个标准连接呢,我查mdn没有查到,如果真的不符合原始行为,我觉得还是有必要做加强

There is the description about CustomEvent.detail in MDN: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail#value

image

And I wrote an example in origin js on codesandbox.io.

avatar
Feb 6th 2023

我想我懂你意思了,在vue的实现中,将arg直接传递出来。这使得参数总是以数组的形式传递给开发者。但是我认为其实这和customEvent的标准并不违背,detail确实可以是任意类型,只是在vue中实现customElement时选择了将事件参数总是以数组的形式通过detail来传递,我认为这是设计如此而已

I think I understand what you mean. In the implementation of vue, arg is passed directly. This makes the parameters always passed to the developer as an array. But I think this does not violate the standard of customEvent, detail can indeed be of any type, but when implementing customElement in vue, It chose to always pass the event parameters in the form of an array through detail to pass, I think it's by design

avatar
Feb 6th 2023

Yes, I understand. However, for users of web component components, in most scenarios, they only need to use e.detail but now they need to use e.detail[0], the use cost has increased.

avatar
Feb 7th 2023

It's hard to change now, as all users of a Vue web component now already use it like this. So it's a breaking change.

avatar
Feb 7th 2023

It's hard to change now, as all users of a Vue web component now already use it like this. So it's a breaking change.

I understanded it. At present, the capability of customEvent of Vue is quite different from that of javascript standard. It is not only the type of detail property, but also the lack of the properties defined in Event() such as bubbles , cancelable and composed: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#syntax

I think it is better to add a new argument to the defineCustomEvent api. When it is true, it can support these capabilities; and when it is false or undefined, it can maintain the current logic. This will not affect current users.

avatar
Feb 14th 2023

Should be changed to match standards. if you want to emit an array - then you emit an array. As many of us wants to convert to vue on a component level - one could easily switch between old component written in some old framework with vue-components when they emit custom events the same way.

avatar
Feb 28th 2023

It's hard to change now, as all users of a Vue web component now already use it like this. So it's a breaking change.

@LinusBorg @baiwusanyu-c I added a new api to implement this function in #7787 , would you please supply some advices?

avatar
Feb 28th 2023

It's hard to change now, as all users of a Vue web component now already use it like this. So it's a breaking change.

@LinusBorg @baiwusanyu-c I added a new api to implement this function in #7787 , would you please supply some advices?

Adding an API to solve this problem does ensure maximum compatibility. However, from a design point of view, I think two APIs with similar functions are a bit strange, maybe it can be used as a transitional solution, so I still support your idea. And in a future version (3.3 or 3.4), I suggest to keep an API (defineStandardCustomElement or defineCustomElement) wdyt ? @LinusBorg