babel-plugin-transform-vue-jsx
babel-plugin-transform-vue-jsx copied to clipboard
How to pass props that collid with the event naming scheme (`onEventName`)?
In the README Difference from React JSX section it says:
render (h) {
return h('div', {
// Component props
props: {
msg: 'hi'
},
I'm looking for that msg: 'hi'
in the The equivalent of the above in Vue 2.0 JSX and cannot find it.
So how would I pass props?
Namely, I want to pass a props named "onUpload"
, but unfortunately this plugin automagically subscribes to the "upload"
event instead.
Please help.
You can use JSX spread:
const data = {
props: {
onUpload: 'foo',
},
}
return <MyComponent {...data} />
Thanks. Trying it now.
Still, that msg: 'hi'
is confusing in the README.
Does your reply mean that these:
return <MyComponent {...{props:{onUpload: 'foo'}}} />
return <MyComponent props={{onUpload: 'foo'}} />
will also work?
I think your confusion has to do with the fact that the examle renders a div element with props, which simply doesn't make sense in "real life".
render (h) {
return h('my-component', {
// Component props
props: {
msg: 'hi'
},
is the same as:
<my-component msg="hi" />
Then the README is missing this msg="hi"
you have just mentioned @LinusBorg
However, my problem is that code
render (h) {
return h('my-component', {
// Component props
props: {
onUpload: 'foo'
},
does not pass onUpload
as a prop
<MyComponent onUpload="foo"> // DOES NOT HAPPEN
That's because everything with on*
is turned into an event listener:
onUpload={this.foo} => v-on:upload="foo"
Look at the example again:
// event listeners are prefixed with `on` or `nativeOn`
onClick={this.clickHandler}
Thank you, I saw that.
Probably, I need to clarify why I really need to pass a prop which name starts with on
.
http://element.eleme.io/#/en-US/component/upload#attributes
As you can see a bunch of attributes in this third party component starts with on-
. I cannot change the prop names.
As the result JSX is impossible to use with the component.
That's why I asked:
Will that work?
return <MyComponent {...{props:{onUpload: 'foo'}}} />
return <MyComponent props={{onUpload: 'foo'}} />
Thank you, now I get it finally :D
I took the part you wrote in bold letters to be the core of your problem, but it wasn't.
The simple, yet probably unsatisfying answer:
You can't use JSX in that case. every JSX Attribute starting with on
and followed by an upper case character will be turned into an event instead of a prop. We needed a way to make event listeners possible, and since JSX doesn't like colons in its attribute names, we chose this pattern.
You will have to write a plain call to h()
for that.
return h('my-component', {
props: {
onUpload: this.foo,
}
})
(That being said, I have no idea why the authors of that third-party component don't use events for callbacks, as you usually do in Vue. Probably because they wanted an easy way to pass them on to child components, and that wasn't possible as easily before we introduced $listeners
in 2.3 or 2.4)
So: Not a bug in the README - expected behaviour that you have to work around due to technical limitations we have when translating JSX to Vue.
Thanks Linus!
Since original Vue syntax is v-on:upload
should we just follow the same pattern and minimise the unfortunate collisions even further and allow only this syntax:
v-on-upload
.
I mean do not treat onUpload
or on-upload
as event subscription. Only treat v-on-upload
.
Pros:
- Less collisions (like my above)
- Quite similar to original Vue syntax
- Opens the road for
v-bind:foo
->v-bind-foo
, and others likev-model
,v-pre
,v-cloak
,v-show
,v-html
,v-text
, etc.
Cons:
- breaking change
@koresar, I would vote against that because in vue we have events that are completely replace the need for "onSomeEvent" props. If there are components that use that kind of API that is a poor design decision in Vue world IMO.
Thanks @nickmessing I'm not quite sure which events you are talking about. Could you please list one or two "events that are completely replace the need"?
@koresar, so, instead of having a prop named "onSubmit" for a component, you declare an event named "submit" in the component and use that instead.
@nickmessing it's ok when you doing it in your code. But when you start using external components you are in trouble.
for example http://doc.huangsw.com/vue-easytable/app.html#/table they have on-custom-comp
event. I have no idea how to subscribe to it
also iview Scroll