defineProp
macro for single prop definition
#513
Replies: 8 comments 9 replies
-
Look really promising to me, I love it! A few ideas about the design of the argument:
const foo = defineProp('foo') // type: String, required: false
const foo = defineProp() // type: null, required: true
const foo = defineProp<string>() // type: String, required true
const foo = defineProp<string | undefined>() // type: String, required false
const foo = defineProp(undefined, {
required: false,
type: String
}) // type String, required: false Then maybe we could save one argument: const propName = defineProp<T>(): Ref<T>
const propName = defineProp<T>(defaultValue): Ref<T>
const propName = defineProp<T>(defaultValue, restOptions)
const propName = defineProp<T>(defaultValue, restOptions, bindingName) |
Beta Was this translation helpful? Give feedback.
-
using <script lang="ts" setup>
// component meta => props, emits, defineOptions, etc.
// Business logic
</script> |
Beta Was this translation helpful? Give feedback.
-
After reading the proposal, it doesn't seem to be worth adding yet another syntax for props, it will just divide more the ecosystem. Adding a new API has a long term impact as well, not short term. As code samples might be written in different syntaxes online and become harder to understand. Especially given that one could totally use Vue without this feature but also use it everywhere instead of I also think it has way too many overloads and that having 2:
But even then, I feel like it just add yet another syntax to remember compared to the existing object: |
Beta Was this translation helpful? Give feedback.
-
I really like that proposal. It is too verbose setting the default value for props right now <script lang="ts" setup>
// current approach #1
import { PropType } from 'vue';
const props = defineProps({
variant: {
type: String as PropType<'primary' | 'secondary'>,
default: 'primary',
},
size: {
type: String as PropType<'xs' | 'sm' | 'md'>,
default: 'xs',
},
});
console.log(props.variant);
console.log(props.size);
// current approach #2
const props = withDefaults(
defineProps<{
variant: 'primary' | 'secondary';
size: 'xs' | 'sm' | 'md';
}>(),
{
variant: 'primary',
size: 'xs',
}
);
console.log(props.variant);
console.log(props.size);
// proposal
const variant = defineProp<'primary' | 'secondary'>('primary');
const size = defineProp<'xs' | 'sm' | 'md'>('xs');
console.log(variant.value);
console.log(size.value);
</script> I assume that defining props is a piece of code that is written almost in every component and it introduces a lot of noise in the current shape of API. |
Beta Was this translation helpful? Give feedback.
-
I like the problem this RFC is addressing - when teaching people the composition API it's come up multiple times that while it's possible to group most things by business domain, not by Vue's functionality (like with the options API), that doesn't apply to prop definitions. I'm not sure this is the best solution, though. I also think the current API, especially with reactive props destructuring, can be made to solve this problem with only a small change—making it possible to use const { foo } = defineProps<{ foo?: boolean }>();
// Logic dealing with foo here
const { bar = 'default' } = defineProps<{ bar?: string }>();
// Logic dealing with bar here That does feel pretty dependent on the reactive props destructure RFC (which I'm not too sure of the status of), but potentially solves the same problem without requiring any new APIs. |
Beta Was this translation helpful? Give feedback.
-
Hi, I have used this macro via vue-macros package for some time and It is very nice and useful to organize well the code in components in separated parts Also, while using the macro I get some more ideas of other possible implementations A similar approach as
|
Beta Was this translation helpful? Give feedback.
-
I think I like it. Early
I kind of think that with hindsight this might have been the preferred approach. So I feel like
Feedback on API design: const propName = defineProp() // : Ref<any>
const propName = defineProp<string>() // : Ref<string | undefined>
// Not all options depicted: also type (for JS), validator, etc.
const propName = defineProp<string>({ required: true, default: "world" }) // Ref<string>
const prop = defineProp<string>("propName")
const prop = defineProp<string>("propName", { default: "world" })
// ^ Ref<string>, under strictNullCheck if undefined can be manually assigned I'd expect:
// defineProp<string | undefined>({ default: "world" }) |
Beta Was this translation helpful? Give feedback.
-
@johnsoncodehk Idea here is all properties of vue2 object like computed, mounted, watch are without define prefix, |
Beta Was this translation helpful? Give feedback.
-
Summary
Provides a DX excellent props definition method for script setup.
Basic example
Motivation
We align the usage of prop with
ref()
/computed()
, which can effectively improve the fluency of thinking when writing SFC.On the other hand, the situation where people used to dislike
.value
is reversed, and now most people like.value
based code. For me.value
is a clear hint that the value is responsive, which actually reduces the mental load.Detailed design
Basic Usage
With Options
TypeScript
Reusing Props definitions
We don't prevent
defineProps
from being used together withdefineProp
, so for reuse props definitions can still usedefineProps
.For consistency, users can use
toRefs
to destructuredefineProps
to refs.Props Inheritance
Since props are not collected into a single object, you need to use
$props
in the template instead of the variable define bydefineProps
.Drawbacks
defineProp
is a new API that does the same thing withdefineProps
and might cause some confusion for users in the short term.Alternatives
defineProps
Adoption strategy
This is a new feature for backward compatibility.
Beta Was this translation helpful? Give feedback.
All reactions