Over the following pages, we will build a Vue app from scratch using a online shop called 'Plants Direct'. Along the way, coding challenges will be set to reinforce what you've learnt.
The team at Plants Direct have already been through the Requirements and Design stages and have identified the most important tickets to add to their first sprint. They put the static UI together in a previous sprint, which can be found here.
Your instructions are to download the files and open up the project in your favourite code editor and get ready to code along with your coach (right click and "Save link as...").
We recommend using the Live Server plugin for VSCode to host your code on localhost in the browser. By using Live Server, you'll benefit from live-reloading and you'll be able to run Lighthouse against your site (more on this in the Accessibility unit). In VSCode, head over to the extensions menu and search for 'Live Server' (by Ritwick Dey).
Once installed, right click the index.html
file you downloaded and click 'Open with Live Server'.
For this code-along, we will be using the Vue CDN link to grab the latest copy of Vue. This is perfect for training and development purposes. If you were to be developing a production frontend in Vue, you would use NPM to install Vue locally or you would use the Vue CLI. The Vue CLI is akin to Create React App in React in that it will scaffold and project for you that features live re-loading, more modularity, easy deployment and more.
Open up your index.html
file. In it, at the bottom, you'll see:
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
This gets the lastest version of Vue from the CDN.
Next up, we need to create an instance of Vue and tell us which element to mount on, which is just a fancy way of saying the element Vue will target to dynamically update content.
In main.js
, add:
// main.js
var app = new Vue({
el: '#app',
data: {
greeting: 'Hello, Vue!',
},
});
And in your HTML somewhere (within the #app div), add: {{ this.greeting }}
Refresh your page and you should see the greeting!
Feel free to delete the greeting and let's turn our attention to the data state. The data state is central to our app. Without it, Vue has nothing to display or dynamically update. Each component can have its own state if needed but for now, we'll add state to the global Vue component we have created.
In the Git directory where you found the source files, you will see a products.json
file. Open the contents and grab everything between the curly braces.
Add this data into your Vue app's data field:
// app component / main.js
data: {
cart: [],
// add other data here
},
Now add {{this.cart.length}}
between the parentheses in the navbar and then open the console add type app.cart.push(1)
. Add more items and see how Vue updates the state as well as the UI to reflect the changes. Very cool!
Let's move on and create our first component. One of the great strengths of frontend frameworks is the ability to turn a collection of HTML into a component that can be reused and centrally managed. Let's turn our product HTML into a Product component. In main.js
, add:
// main.js
const Product = Vue.component('Product', {
template: `
<div class="product">
<h3>{{product.name}}</h3>
<img src="./images/boston_fern_sm.jpg" />
<p>
Sed ut perspiciatis, unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam eaque ipsa
</p>
<ul>
<li>Likes moisture</li>
<li>Easy care</li>
</ul>
<p>£6.99</p>
<div class="promo-blocks__actions">
<a class="button--anchor">
Full Details
</a>
<button>
Add to cart
</button>
</div>
</div>
`,
props: ['product'],
});
The props
property tells the component to expect a property to be passed down called product
. More on this shortly.
Now return to your HTML and remove all the product HTML and replace it with:
<div class="promo-blocks products">
<product
v-for="product in this.products"
v-bind:key="product.productId"
v-bind:product="product"
></product>
</div>
Refresh your page and you should see the product component is reused and outputted three times. The problem is, most of the information is the same. To solve this, we'll need to tag everything up so the content is dynamic. To do this, we'll need to reference the product
prop that we passed down as well as the value we want. For example, to get the name of the product, we would use {{product.name}}
.
Notice the v-for
and v-bind
. You'll come across these often in Vue. The v-for
command allows you to loop through an array and output HTML or bind the item (in this case, aa key and the product) to a field that can be passed to a component. There are many things we can bind to, and we'll explore this in more detail later. Binding a unique key is considered good practice in Vue, so try and add this to you loops where possible.
Tag up your Product component so the data gets rendered dynamically.
NB: rendering the correct image might be tricky. We will solve this in the next lesson.
You'll notice we have an array of features yet the features are currently being outputted using static HTML. Add a v-for
to the unordered list and render out the list items dynamically.