docs icon indicating copy to clipboard operation
docs copied to clipboard

Props (Composition API)

Open ckhatton-transreport opened this issue 2 years ago • 6 comments

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:

// in <script setup>
const props = defineProps({
  title: String,
  likes: Number
})

And the TypeScript example:

<script setup lang="ts">
const props = defineProps<{
  title?: string
  likes?: number
}>()
</script>

:octocat:

ckhatton-transreport avatar Jan 24 '23 14:01 ckhatton-transreport

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>

SFC Playground

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 */ ))
        }
    }

})

jaredmcateer avatar Feb 04 '23 18:02 jaredmcateer

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.

ckhatton-transreport avatar Feb 06 '23 12:02 ckhatton-transreport

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

ne0guille avatar Oct 18 '23 21:10 ne0guille

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>

jaredmcateer avatar Oct 19 '23 16:10 jaredmcateer