CustomElement: Additional event arguments of CustomEvent
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>
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?
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.
给个标准连接呢,我查mdn没有查到,如果真的不符合原始行为,我觉得还是有必要做加强
There is the description about CustomEvent.detail
in MDN: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail#value:
And I wrote an example in origin js on codesandbox.io.
我想我懂你意思了,在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
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.
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.
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.
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.
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?
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