Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do not require Props when using defineComponent with setup function #5730

Closed
westbrma opened this issue Apr 16, 2022 · 7 comments
Closed

do not require Props when using defineComponent with setup function #5730

westbrma opened this issue Apr 16, 2022 · 7 comments

Comments

@westbrma
Copy link

What problem does this feature solve?

I like that you can pass a setup function into defineComponent however if you require props in your component you then need to pass a component options object.

What does the proposed API look like?

I want to simply do this:

const MyComp = Vue.defineComponent((p: { name: string }) => {
	return <div>{p.name}</div>;
});

instead of

const MyComp = Vue.defineComponent({
	props: {
		name: String
	},
	setup(p) {
		return <div>{p.name}</div>;
	}
});

This makes it look much cleaner and decreases a level of indentation.

This is even cleaner and works without explicitly setting props:

const MyComp = (p: { name: string }) => {
	return <div>{p.name}</div>;
};

however it only works as a "Functional Component" and does not keep state. React lets me define components like this. In React I use Mobx to get Vue like Reactivity so I need to wrap my components in Observerable(). I would love to get the best of both worlds and have elegant jsx components with the proxy based Vue reactivity.

@LinusBorg
Copy link
Member

LinusBorg commented Apr 16, 2022

That's not supported right now, indeed. If no runtime props are declared, then ($)props are empty - and everything you pass to that component will be in context.attrs.

There has been some discussion about how we could make something like what you expect possible here:

vuejs/rfcs#282

But it has been going nowhere concrete yet.

I'll close this issue in favor of the RFC discussion.

What you can explore for your specific scenario though is:

const MyComp = Vue.defineComponent((p: { name: string }) => {
	return <div>{p.name}</div>;
});

MyComp.props = ['name']

@westbrma
Copy link
Author

Ok, that is basically what I did by introducing this helper function:

function Component<T>(props: string[], setup: T): T {
	let r = Vue.defineComponent(setup);
	r.props = props;
	return r;
}

@westbrma
Copy link
Author

@LinusBorg since all props are passed when you do not use defineComponent it seems like it should also work that way for consistency when using defineComponent.

@LinusBorg
Copy link
Member

LinusBorg commented Apr 16, 2022

I'm not sure what you mean when you say:

since all props are passed when you do not use defineComponent

I suspect you mix this up with functional components which are a different thing.

@westbrma
Copy link
Author

I'm not sure what you mean when you say:

since all props are passed when you do not use defineComponent

I suspect you mix this up with functional components which are a different thing.

Correct, that is what I meant (functional components). The only difference is one does not keep state, however they both allow for props to be passed but functional components do not require you to explicitly name them.

@LinusBorg
Copy link
Member

LinusBorg commented Apr 19, 2022

Stateful components do require that.

We can't change that behavior in 3.x for backwards compatibility. Most we can do is come up with a new option for enabling this on a per component Basis.

There has been some discussion about that In our RFC repo's discussions section, but it has dried up some time ago, there wasn't to much input coming.

@westbrma
Copy link
Author

I wonder if this could be enabled globally or have an alternative defineComponent that has that functionality. I personally think that setup functions should be stateful without wrapping them in a function and have functional components require the extra step. Since so many people are using typescript and jsx I think that making that feel very natural in Vue should be a goal.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants