Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Props: Passing Info into a Child Component

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

The text inside the Legend component is static. That won't work! Remember: our goal is to be able to re-use the Legend component from other places in our app and pass it the text that it should render. Somehow, we need to pass a value from the Products component down into the Legend component.

In PHP, if we created a function and needed some info to be passed into it, we would add an argument to the function. Simple! In Vue, components have a similar concept called "props".

Here's how it works. As soon as I need something to be passed into a component, that component needs a props option. Set this to an array with one key for each prop that an outside component should be able to pass. Call the one prop we need, how about, title.

... lines 1 - 6
<script>
export default {
... line 9
props: ['title'],
};
</script>

Thanks to this, any component that includes this component is now allowed to pass a title prop to it. We'll see what that looks like in a minute.

To use these, Vue makes all props available as variables in the template. Replace the hardcoded text with {{ title }}.

<template>
<span class="p-3">
{{ title }}
</span>
</template>
... lines 6 - 13

This component is now perfect: it says that it accepts a prop called title and then we use its value in the template. Lovely!

Back in products.vue, how can we pass that prop to legend-component? By adding an attribute: title="" and then whatever value you want, like TODO PUT LEGEND HERE.

<template>
... lines 2 - 47
<div class="row">
<legend-component title="TODO PUT LEGEND HERE" />
</div>
... lines 51 - 53
</template>
... lines 55 - 85

props are Read-Only

That should do it! When we refresh the page... it works! And the Vue dev tools are even more interesting! If you click on <Products>, you can still see the legend data, though, we're not using this anywhere at the moment. And when you click on <Legend>, nice! You can see its props!

We've just seen two of the most important things in Vue: data and props. data are values that will change while your app is running, which is why the Vue dev tools gives us the little pencil icon to modify them. But props are different: when a component receives a prop, it can't change it: the Vue dev tools doesn't give us a cute pencil icon for a prop. Props are just a way for a component to receive data.

I like to think of "props to a component" like "arguments to a function" in PHP. Think about it: in PHP, if we add an argument to a function, its main purpose is to allow whoever calls us to pass us data. Once we receive an argument, we don't usually change the argument's value. I mean, we could, but the main purpose of an argument is to read data, not modify it. Props are just like that.

Items in data are almost more like variables that you create inside the function to hold some new dynamic data: you create them for your own purposes and can set and change them as much as you want. Of course, if you were to call another function that needed one of these variables, you would pass it to that function as an argument. The same is true in Vue: in a few minutes, we're going to pass the legend data in the Products component into the Legend component as a prop.

Props and Data are Available in Templates

Oh, and one other thing about props and data. In a template, all props are available as variables, which means we can say {{ title }}.

But you might remember that earlier, when we used the legend data in a template, we did the same thing: we said {{ legend }}. It turns out that Vue makes both props and data available as variables in your template. Which, again, is a lot like a function in PHP: you have access to any arguments that were passed to you and any local variables that you create.

Next: it's cool that we can pass a prop from Products into <legend-component>. But what we really want to do is pass this dynamic legend data as the title prop so that when that legend changes, the text updates. We'll do this with an important concept called v-bind?

Leave a comment!

5
Login or Register to join the conversation
Fernando A. Avatar
Fernando A. Avatar Fernando A. | posted 2 years ago

can we have a skip button to the questions?
to me they add no value.

Reply

Hey Fernando A.!

Yep, we're going to add a feature for that - we realize that not everyone wants to go through those :).

Cheers!

1 Reply
Peter-K Avatar
Peter-K Avatar Peter-K | posted 3 years ago

Challenge 2 of this video: Correct answer is missing closing tag for title component

Reply

Hi Peter!

Thanks for spotting it! We'll fix soon! :)

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This course is also built to work with Vue 3!

What JavaScript libraries does this tutorial use?

// package.json
{
    "devDependencies": {
        "@symfony/webpack-encore": "^0.30.0", // 0.30.2
        "axios": "^0.19.2", // 0.19.2
        "bootstrap": "^4.4.1", // 4.5.0
        "core-js": "^3.0.0", // 3.6.5
        "eslint": "^6.7.2", // 6.8.0
        "eslint-config-airbnb-base": "^14.0.0", // 14.1.0
        "eslint-plugin-import": "^2.19.1", // 2.20.2
        "eslint-plugin-vue": "^6.0.1", // 6.2.2
        "regenerator-runtime": "^0.13.2", // 0.13.5
        "sass": "^1.29.0", // 1.29.0
        "sass-loader": "^8.0.0", // 8.0.2
        "vue": "^2.6.11", // 2.6.11
        "vue-loader": "^15.9.1", // 15.9.2
        "vue-template-compiler": "^2.6.11", // 2.6.11
        "webpack-notifier": "^1.6.0" // 1.8.0
    }
}
userVoice