Open ckhatton-transreport opened 1 year ago
To be more clear you only need to assign a props
variable if you plan to use the prop in the script section and the first example on the Props docs page demonstrates this (but doesn't make it explicit).
For example this works:
<script setup lang="ts">
defineProps<{ title: string; likes: number }>();
</script>
<template>
<h1>{{ title }}</h1>
<h2>{{ likes }} likes</h2>
</template>
Examining the transpiled code makes this clear
<script setup lang="ts">
const props = defineProps<{ title: string; likes: number }>();
</script>
...
const __sfc__ = /*#__PURE__*/ _defineComponent({
__name: 'Comp',
props: {
title: null,
likes: null
},
setup(__props) {
const props = __props; // <-- unused variable
return (_ctx, _cache) => {
return (_openBlock(), _createElementBlock(_Fragment, null, [
_createElementVNode("h1", null, _toDisplayString(__props.title), 1 /* TEXT */ ),
_createElementVNode("h2", null, _toDisplayString(__props.likes) + " likes", 1 /* TEXT */ )
], 64 /* STABLE_FRAGMENT */ ))
}
}
})
That is good to know. I am not sure if it was because of my dyslexia, but that was not that apparent when I first read it - maybe it needs to be illustrated more clearly or stipulated in a block-quote?
Note: You only need to assign a props variable if you plan to use the prop in the script section.
That is good to know. I am not sure if it was because of my dyslexia, but that was not that apparent when I first read it - maybe it needs to be illustrated more clearly or stipulated in a block-quote?
Note: You only need to assign a props variable if you plan to use the prop in the script section.
i've just learned this too, but to be fair taking a 2nd look at the doc there are examples of props definition without using a variable
<script setup lang="ts"> defineProps<{ title?: string likes?: number }>() </script>
https://vuejs.org/guide/components/props.html#prop-passing-details
I've personally come to the opinion that you should always be using const props =
and then in your templates using props.var
rather than relying on Vue's magic to do it for you. Not using props
as a namespace creates ambiguity in the template when you have code like this:
<script setup lang="ts">
defineProps<{ foo: string }>();
const foo = ref('Hello world');
</script>
<template>
<div>{{ foo }}</div>
</template>
It is unclear for the reader of the code whether the template is displaying props.foo
or foo.value
in the template. You just have to know that Vue will prefer locally created variables over props
in the template. And even then the reader may not know the intention of the authors code and maybe this is a subtle bug. Better to always be explicit (and if possible avoid shadowing props variables in the first place.)
<script setup lang="ts">
const props = defineProps<{ foo: string }>();
const bar = ref('Hello world');
</script>
<template>
<div>{{ props.foo }}</div>
</template>
<script setup lang="ts"> defineProps<{ foo: string }>(); const foo = ref('Hello world'); </script>
I think in that case you already get an error that 'foo' is already defined. Cannot redeclare block-scoped variable 'foo'.
.
I'm using eslint, maybe that makes it more clear.
I don't see that error in a default eslint setup. When creating a new project with vue's recommend npm create vue@latest
you do get the following error
3:7 error Duplicate key 'foo'. May cause name collision in script or template tag vue/no-dupe-keys
Which is fine, but that relies on the linter rules to be setup correctly. I think my reasoning for being explicit still stands.
https://vuejs.org/guide/components/props.html#props-declaration
When it comes to the example of passing an object of props, it isn't clear that you still need to use
const props =
if you want to use those props.The example should instead be:
And the TypeScript example:
:octocat: