Props & Re-Using Components
A little HTML, CSS, & JavaScript knowledge if recommended for this course.
Blog post component
Along with isolating our code, another benefit of using components is they can be re-used. And not only that, we can also re-use the same component and pass it different values.
To see this, create a new blog post component:
// script.js
app.component("blog-post", {
template: `
<article>
<h3>{{title}}</h3>
<p v-html="body"></p>
<p class="read_more">Read More</p>
</article>
`,
});
Place this, and all other components above app.mount()
In the index.html, locate the <section id="blog">:
<section id="blog">
<article v-for="(post, index) in posts" :key="post.id">
<h3>{{post.title}}</h3>
<p v-html="post.body"></p>
<p class="read_more">Read More</p>
</article>
</section>
Remove the article element (including contents), and replace with our component:
<!-- index.html -->
<section id="blog">
<blog-post></blog-post>
</section>
The app-header component had a data section to store our variables. This blog-post component will instead be passed data using props.
The same component can contain a data section and also receive props.
Passing props
Props are like regular attributes. We can use them to send data to a component, our blog-post component needs a title and a body:
<blog-post title="title 1" body="description 1"></blog-post>
We can also re-use this blog-post component. Each time we do this, each component is independent of the others and has it’s own data, often referred to as state, so they will not conflict with each other:
<blog-post title="title 1" body="description 1"></blog-post>
<blog-post title="title 2" body="description 2"></blog-post>
Just passing these props is not enough though for them to be used.
Declaring props
Inside the component, we add a props array to declare the props we expect this component to receive:
// script.js
app.component("blog-post", {
props: ["title", "body"],
template: `
<article>
<h3>{{title}}</h3>
<p v-html="body"></p>
<p class="read_more">Read More</p>
</article>
`,
});
You should now see the two blog posts in the browser.
Although this works, it's not an efficient way of creating multiple blog posts.
Looping with components
A better way would be to use a v-for loop. Return back to using one blog-post component, and loop over our posts array:
<!-- index.html -->
<section id="blog">
<blog-post v-for="post in posts" :key="post.id" post="post"></blog-post>
</section>
This also receives the post object as a prop, since this is a variable, we need to use the v-bind syntax (:):
<blog-post v-for="post in posts" :key="post.id" :post="post"></blog-post>
Just like earlier when we used v-bind for class and style attributes, this tells Vue to now read the post as a variable containing a post object, rather than just the string of “post”.
Remember, each post object will have an id, title, and body property:
// script.js
const posts = [
{
id: 1,
title: "Why I learned Vue",
body: "I'm baby chambray street art <strong>thundercats</strong> occupy four loko church-key disrupt. Shaman neutra bushwick chicharrones",
},
// ...
We therefore need to update the components props and template to reflect this:
app.component("blog-post", {
props: ["post"],
template: `
<article>
<h3>{{post.title}}</h3>
<p v-html="post.body"></p>
<p class="read_more">Read More</p>
</article>
`,
});
Refresh the browser, and the components now have all the data they need passed as props.