vuejs / jsx-vue2

monorepo for Babel / Vue JSX related packages
https://jsx-vue2-playground.netlify.app/
1.47k stars 96 forks source link

Why props that start with 'on' has undefined values? #105

Open maratfakhreev opened 4 years ago

maratfakhreev commented 4 years ago

Hi. I've updated babel and whole vue environment in my project and have found that any props which names start with on like onEnter or onboarding have undefined values. When with https://github.com/vuejs/babel-plugin-transform-vue-jsx everything was fine.

Why it so? It's probably not so difficult to me change their names but what the point of this, is it some tech solution? And at last maybe you should mention about this restriction in readme if it's not a bug? To be honest I was really surprised when some of functionaly have broken after the upgrade)

Thank you.

CntChen commented 4 years ago

I think this behavior is a bug and fix it in this Pull request.

maratfakhreev commented 4 years ago

@CntChen nice PR, I hope it will be merged asap if it doesn't have any specific meaning.

rkingon commented 4 years ago

I've encountered this a few times (such a pita, tbh) but I think the reason behind the issue is that the VueJSX will automatically convert any on prefix to the @event style behavior of tradition vue template language.

I've used a few work-arounds...

1) Let them be $listeners instead of props (not really ideal, but sometimes works just fine, ie: onEnter becomes $listeners.enter -- this is sometimes fine when you just need to fire an event.

2) Ugly as sin, but for ones like onboarding -- you can pass in via props prop... <YourComponent props={{ onboarding: value }} />

rkingon commented 4 years ago

Note on $listeners -- sometimes you have async functions that you want on your onXyz -- For example, you may want to run async code on a onSubmit or something...

If you use traditional this.$emit('submit', () => {}) you will not be able to await.

For those situations, you can use the $listeners.submit function directly, rather than using $emit -- ie: await this.$listeners.submit

This was initially my primary use case for passing onXyx style functions as props instead of event listeners, before I realized that it worked just fine to ditch the $emit functionality all together.