Transcripts
1. Welcome!: Welcome to the Vue.js Academy course. I'm excited to have you with me. My name is Chris, and I'm a web developer and also an experienced online course creator, teaching thousands of satisfied students. Vue.js is one of the most up and coming JavaScript frameworks available today. It's also one of the most fun to learn and it's packed with lots of amazing features enabling you to build both small websites right through to complex single-page applications. So why choose this course over other Vue.js courses available? Well, this course takes a project-based approach. We will see exactly how each concept you will learn immediately fits into real projects. The course is beginner friendly too. We start by building a guest list application where we'll start off with the basics. I have provided a [inaudible] starter template for the first project so we can dive straight into learning what Vue.js has to offer. During this project, you become confident with how Vue works, and also the core concepts such as binding data, methods, computer properties, and so much more. You will also learn about the Vue life cycle stages we can tap into. Project 2 builds on what we've already learned so far. We introduce you to build tools and also improve our workflow by using the latest technologies such as the Vue CLI, Webpack, and Bubble too. This project will be a greeting card application where the user can edit and create their own personalized greeting card. Along with this being a fun project to build, you will learn so many techniques, such as using components and how to pass data between them along with integrating your app with Firebase for image storage. Also, we will cover adding animations and transitions to your apps to make sure they really stand out. Everything you learn will be immediately put into practice in the projects to really give you a better understanding of how they all fit into real applications. What are you waiting for? Hit the Sign Up button now and learn one of the hottest JavaScript frameworks available today.
2. What is Vue.js and why should I use it?: If you are unfamiliar with vue.js or JavaScript libraries and frameworks in general, some of the questions you may be asking is, what is vue.js and why should I learn it in the first place? Well, vue.js is a really fun and easy to use JavaScript framework for building user interfaces. The core of the framework is very lightweight and fast, and it can be used in projects of any science from easily dropping it into an existing website or application to just using it to control a small part, such as adding a new components, right through to medium or large single-page applications. Considering the lightweight size of the vue.js core, it is still packed with lots of features which you will learn about during this course. The core can also be extended to add more features, such as frontend routing and state management. If you've built websites before, you should already be familiar with HTML, CSS, and JavaScript, which are the building blocks of vue.js applications. This means you can make use of your existing skills to [inaudible] up and learning even faster. Vue.js handles the view layer only, meaning you're free to integrate it with any of the libraries backends, making it really easy and flexible to adopt. If you've used other frameworks or libraries such as React, a lot of the core concepts will be familiar, such as using a virtual DOM and building reusable components. React is also great to use too, but to my opinion, vue.js is a lot easier to get started with, and is also being seen to outperform React on certain performance tests. These are just some of the reasons why vue.js has seen a huge rise in popularity and also looks at to become an even bigger player in the future. Now, we know some of the benefits of using vue.js, now let's get Visual Studio code setup, so we can jump straight into building our first project.
3. Visual studio installation: For this course, we will need a few things to get up and running. First, we need a text editor. You may already have a preference or one that you already use. For this course, I'll be using Visual Studio Code, which is ideal for JavaScript coding, and also has a built-in terminal which we'll need later in the course. You can use any text editor you like but here are some popular texts editor options, such as Atom, Brackets, WebStorm, and of course, Visual Studio Code. If you already have one of those and have a web browser, feel free to move on to the next video. If not, I would recommend that you go over to code.visualstudio.com and follow the download instructions for your platform. Once you've done this, comeback and we'll add some plug-ins to help them working with Vue.js. Once the installation is completed, I'm going to add a plug-in to add Vue.js to code snippets and also some syntax highlighting. If you open up your text editor and click on the extensions icon at the bottom of the options, you'll see I already have Vue 2 Snippets installed. To install this, you can click on the search bar and search for Vue 2. What I'm going to use is Vue 2 Snippets, which is by [inaudible] , then click on the install button and you're good to go. Finally, you will also need a web browser. I would recommend Chrome by Google, but you can use any web browser you like. This is it for the initial setup. Now let's jump into building our first Vue.js application.
4. Section Intro: Vue Basics : As with all my courses, I like to waste no time in getting our hands dirty and actually building real projects. This course is no different and we're going to get started by building a guest list application, where the user can register their interests in an event and have the name added to the guest list. The project will be relatively simple, but we'll cover all the basics. You will need to get started building vue.js-ups. Let's go ahead and get started.
5. Download project starter: Attached this video is a starter project which we're going to use to jump straight into vue js. I want to download mine and place it onto the desktop for easy access. But you can place yours anywhere. Just as long as it's convenient for you. Now you should already have your text editor all set up. I'm going to open Visual Studio Code and then once it opens, I'm going to drag the project starter over into the text editor. Then let's take a little look at what's included. If we open up the index.html, it's just a basic HMO's data. In head section we just have some basic meta tags, the title. We also have some links to bootstrap. We are just going to use this for some basic styling and layout. The body of the project starts with a main div, which has an id of app. This is going to be the main container and we'll take a look at this in more detail when we look at the view instance. Well then, you just have some basic rows and containers and some information about the guest list. If we open up the project folder and then if we double-click on index.html. You can then see the basic structure of what we have. We have a row which has some information about the events, such as the event date, the event title and a description. We also have a text input where the user can add their name and then submit it to add it to the guest list. Then below that we have another row and then an overall below this, which is going to be the place where all the names are added to. At the moment it says no names added yet. But we'll add the functionality throughout this section to make this work. Over in the app.css we just have some basic styling just to make it look a little bit nicer. The app.js is empty for now. But this is the place where we'll add the view JS functionality as we go through this section. This is just a basic overview of what's included with the project as a start-up package. This will become a lot more familiar as you go through this section. Next up we'll look at how to install vue js and how to add it to the starter projects and then we'll begin working inside this app.js by taking a look at the view instance.
6. Installing Vue.js: In the last video, we should have downloaded the project starter, which I've placed on my desktop for easy access. You should also have a text editor ready to use. In my case, I'm using Visual Studio Code. In this video we're going to show you a few examples of how we can get started with installing Vue.js. I'm going to go over to my web browser and I'm going to be using Chrome for the rest of this course. Then we're going to go over to Vue.js.org, which is the official website for Vue.js. If you click on the guide on the top right-hand corner, and then once it loads up, you should see a navigation menu on the left. To begin, we need to go on to the installation menu, and he will provide you with some options of how to get started. The first one is how to include Vue.js Within script tags, so we can click on either the development version or the production version. The development version has the debug mode and also the warnings. The production version doesn't have these and it's minified. All we need to do is click on one of these buttons and then we get the download, then we can save these files inside of our application and link to them using script tags. This technique is just the same as including any of your scripts such as j-query. Another option is to use the CDN link, we shall be using for this project. This is a link where the Vue.js library is hosted externally. If we click on the recommended link there, wouldn't taken to a hosted version of Vue.js, and this is the latest version. Will come back to this just in a moments. The next option is using NPM or the Node Package Manager. We will be using NPM In the next project, but for now I just want to keep things simple, we'll focus on Vue. js and then in the basics. There's also the Vue.cli, which is an easy way to scaffold out Vue.js projects. Again, we'll use this later on, but for now I'm just going to go up to the CDN link and then click on the link, and then we need it copy this URL link. Then if we go back over to your text editor and then open up the projects. If we go over to the index.html, when it go to the head section just below the title, and then add in the script tags, and then we can add the source attributes and then paste in the link to the Vue. js library, and then save that. That's how quick and easy is to add Vue.js as a CDN link. With Vue.js now added to our app, we'll now move on to the next video where we'll take a look at adding the Vue.instance.
7. The Vue instance & the data object: Now we have access to the Vue.js library by using ECD and link. We can now begin working with inside of our app.js file. App.js is included in starts project. You should already have download it. This file you can name anything you like. So you're free to choose if you prefer. We will begin by accessing the view object, and this allows us to create a new view instance by typing New View, followed by the parenthesis and a semicolon. This new view instance is going to basically control our application and the HTML data to be rendered to the screen. We then need to pass in a options objects, which contains various options, which we'll explore throughout this course, such as HTML view, which HTML element we wanted to mount to. It also contains all of our methods and data. First, let's take a look at el. This keyword tells you which HTML element to control. In our case, we want to control the index.html page. So I'm going to use the main surrounding div container, which would give a AID of up. So we can set the string value of el to be equal to up with the hash prefix because it's AID. This is just like a CSS selector. So if we wanted to control a div with a class instead of an ID, we'll just replace the hash with a dot. Now we've selected our elements. We want to be working with the data property. This contains an object which stores all of the data we want to use inside of this view instance. At the moment, all of the data inside our app is just plain HTML, which Vue.js Clooney has no control over. For example, all the data about the listed events, such as the event dates, the event title, and event description is hand coded. We can change this by adding it to the data object inside of our view instance. So I'm going to begin transferring this hand-coded information over to our date property. So let's begin by including dates. So select the date from there, put it out HTML. Then if we go over to our dates property, we can set a name for this dates. So I want to call mine eventDate followed by the column, and then inside of a string, we can add the date inside of there. We can then do the same with the event title. So back over in the index page, if you put the name of Summer Festival, and then inside of our data, back over in our app.js, and then next we'll call this the eventTitle. Then just as before with our days as a string. So pasting this between the quotations. Then finally, we will also do the same for the event description. So go over to the index page, put the event description, and then just under the eventTitle, we'll create the eventDescription data name, and then paste this in as a value. So now we need a way of adding this data back into our HTML. To insert this data into our code, we do it with a special template syntax of double curly braces. You will also see this referred to as mustache syntax or text interpolation. This is how we link our data with the DOM. This also means that the data is reactive and will be updated when there is a change with the data. Inside of these curly braces, we can add the name of the date property which we just created. So let's start with the eventDates in the place of where we put out the date just before. So let's save that and refresh the browser, and now we can see the date is appearing back on the screen. So this date is now working because it's inside of the double curly braces. So Vue.js knows to look for this property name inside of the date object which we just created. It will also be updated whenever the value of eventDate is changed. So what I'd like you to do now is do exactly the same for the eventTitle and also the eventDescription. So pause and give that a go. If it's something you don't feel comfortable with, just yet, don't worry. I'll continue now by adding the eventTitle. So do the same just as before. In place of the title, we'll add the double curly braces and then add the eventTitle. Finally, in a place where we put the eventDescription will also add the eventDescription into there. So save that and we'll do a final refresh just to check it's all working okay. So it's not looking great. We've got the dates, the title, and also the description, if [inaudible] back on the page. But this time we have Vue.js controlling the data. So finally, I just want to finish off with one last thing. Because these free data properties are related, I am going to group them together inside of their own events object. This is totally optional, but it makes sense especially if we extend up by creating more than one events. So back inside the data property, we want to create the events object. Then I'm going to cut the eventDate, the eventTitle and eventDescription, and then make sure these pasted inside of the new event object. Now back over in the browser, if we do a refresh, we see that the data disappears. This is because we need to tell Vue that these properties and now inside of an object called events. So it just means make one more change inside the index page. So all we need to do is our events in front of eventDates, the same with eventTitle, and then finally the same with eventDescription. So hit save. Now if we go back over to the browser and gives a refresh, we should see that all our data is back on the screen. So now we've created our Vue instance and looked at how to use the data object to control a text inside of our application. Next up, we'll take a look at how Vue JS handles templates and utilizes the virtual DOM. I'll see you there.
8. Templates & the virtual DOM: In the last video, we looked at how to create a Vue instance and also how to add reactive data to our app. How does Vue js manages data to make it reactive and update our page when there is a change? But let's take a little look at what goes on in the background. If we go to the browser developer tools inside of Chrome, we can access these with a right-click and then select "Inspect". If will then select the Div with the class of card block, we can take a little look at the contents and we can see that the event title, the event dates, and the event description is added between P-tags or headings. So the HTML output is different to what we have typed inside of the Editor. We don't have any of the double curly brace syntax and we cannot see the names of our data properties, such as event title. This is because Vue.js takes our HTML code and creates a template based on it behind the scenes. This templates, which is created is unused to render to the DOM with valid HTML code. Using a template instead of directly updating the DOM with our code also provides additional benefits. When our data, for example, is updated inside of the app, Vue then works out which parts of the template is changed. Since Vue is aware of exactly which part is changed, it will only re-render this change part of the template. So by only re-rendering the minimum amount of code to the real DOM. This has the effect of making our Vue.js applications really fast as manipulating the DOM is typically one of the most expensive operations to perform. If you're not familiar with the DOM, it stands for Document Object Model. It's a structured representation of a documents. In our case, the document being the webpage. In most simple cases, the DOM, which is created, looks like our HTML code, which were right and here we see a typical visual representations of the DOM, which is like a tree of objects starting with the HTML elements on the top and then we have the head section and the body section, and then all of our nested elements contained within the head section of the body section. So this should look familiar to you if you've had some HTML experience. Because obtained need DOM elements takes time, Vue.js also uses what is called the virtual DOM. These templates which Vue. js creates a compiled into virtual DOM render functions. The virtual DOM is like a copy of the real DOM and this allows view behind the scenes to compare the real DOM with the virtual DOM and only updates where and when is necessary. So don't worry too much if you don't quite understand what this all means for now. We get plenty of practice with how Vue works and how it renders templates as you go for the course. So this is how Vue.js works with templates and also the virtual DOM. I just wanted to give you a little background into what is going on behind the scenes when we're writing our code. Next up, we'll look at two-way data mining using a V model directive.
9. Two way data binding with v-model: We have looked at creating our Vue instance and added the data objects. I want to set a new data property, but this time I'm going to use it with a view directive called v-model. Directives have a -v prefix, and you will see them a lot throughout this course. The special attributes provided by Vue.JS, which add special reactive behavior to the DOM using v-model sets up two-way data binding. If you are unfamiliar with two-way data binding, it just means that the data can be passed both ways. In the examples we've looked at so far, we can update the properties inside of the data objects, and then these changes are then passed to the Vue. With two-way data binding, we can still do this, but we can also update the Vue elements such as input fields and this then updates the value of our data. Vue.JS makes this two-way data flow really simple, by providing us with this directive called v-model. Let's begin by setting v-model on our text input fields. If you go over to our index.html page, and then locate our text inputs, we can add v-model and then set the name of the data property want to bind to. So in our case, "newNameText". Next we need to set newNameText as a property in the data objects. This way, we can set the initial value if we want to, and because it's two-way data mining we can also update the value with the input field. So over in app.js outside the events object add our property of newNameText: So I'm going to set the initial value of newNameText to be equal to an empty string. We can add an initial value inside of that if we want to. So to see the value of newNameText we just need to go over to the index.html page, and then use the double curly brace syntax to output the newNameText. Now if we type anything inside the input field, we see the value of newNameText updated immediately. This is how we can use two-way data binding with Vue.JS. One important thing to remember is that Vue.JS does not care about the placeholder or initial value of the input fields. The data inside of the Vue instance will always be a priority and considered correct over the input fields initial value. We will cover using v-model weighed over input types and text areas later on in the course. For now though, let's move on and take a look at event handlers and how we can take the names added to this input field and push them to an array.
10. Event handling & methods: Now we've looked at two-way data binding. I want to now move on to capturing the value entered into the input fields and then push it to an array. This array will hold all the names entered into the input field and then we can list all of these names inside of the attendance section below. We want to go to the app.js and create our empty array. I'm going to add a new data property called guest name and initially we're going to set this to an empty array. Now this is created over in index.html. Now we need to create an event handler to push the names to this array. Once the submit button has been pressed, in vue.js, we use the V on Directive to listen to DOM events. These DOM events and not specific to view.js. We can use any of the DOM events normally available to us, such as onClick, keyup, keydown, and many, many more. Again, just like in the last video where we use V-model, this directive also has the v dash prefix. Next we locate our form elements and then as an attribute, we can add our V on Directive. First we add V on, and then after the colon we add the name of the event handler we want to trigger. In our case, we're going to listen for the submit event and then we add the name of the method which we want to run once the form has been submitted. After the name of the events, in our case of myths, we can also add event modifiers. A common event modifier is to prevent the defaults. If you use JavaScript for working with inputs and forms of all, you may have already used event dot prevent default. This stops the default behavior, which for the submit button is to refresh the page. Few just makes this really easy for us to address behavior to our event handlers simply by adding it after the event handler name just like this. Prevent the default we'll stop our data from being lost when the page is refreshed. This also over event modifiers too, which we'll cover later on in this course. For now we've added form submitted as the name of our method, but not yet created it inside of our view instance. Let's do this now over in the app dot js. Just like when we added the data property objects inside of the view instance, we can also use the reserved methods keyword. Methods also takes in an object, so we'll open up a set of curly braces. Inside here we can add our first method of forms submitted. This method is triggered each time the form is submitted. Form submitted is a function and inside this function we can begin by adding a console log, just to check this is working okay. We want to log to the console the value of new name text, which is linked to the input field. This keyword allows us to access all the properties inside of the view instance. To access the new name text property, we use this dot new name text. We've seen this a lot throughout the course. Now we'll go back over to the app and then go inside the console. We can type a name inside of the input field, and we should see the value appearing inside the console. Now we know this method is being triggered okay. We can now finish our method by pushing the new name value to the guest name array. Let's first remove the console log, and in the place of this we can select this dot guest name, which is the name of our array. Because this is an array, we can use the push method. Then inside the brackets, we'll tell vue.js, What we want to push onto the array. In our case, we want to push the value of the input fields, so we can select our word at this, dot new name text. Then to finish off this method, the last thing I want to do is once a name is being added to the array, we want to just clear the input field by setting this dot new name text to once again set to an empty string. To see the values which are inside of the array, we can use texts interpolation again, or the double curly braces syntax to output this inside the index.html. If we look for the level four heading, which has the text of no names added yet, we can use the curly brace syntax to output the guest name array. Now let's save that and we head over to Chrome and refresh the browser. We can now add names to the input field and now we've hit submit. This should now be pushed to the array and then outputed to the screen. We have the new names now added to the array, which is great. The names are just displaying as they are inside of the array, so at the moment it doesn't look very good. But not to worry, we'll fix this in the next video. We'll take a look at list rendering with For loops.
11. List rendering: We now take the users name inputs and push it to an array when the submit button is pressed. We did this by adding an event listener to the form and then calling a method when the form is submitted. This method inside of the Vue instance is some JavaScript code which takes the contents of the input field stored inside of new name texts and then pushes it to this guestName array. Now we have the guestName array we want to loop through these names and then render them to the screen. Vue.js, like normal JavaScript can do this with a for loop. However, Vue makes creating a for loop much simpler and cleaner than using Vanilla JavaScript. All we need to do is create a v-for directive like this. If we go over to the Index.html Page and then scroll down towards the Bomb. If we look for the div with a class of cards-success rounded and name-box, we're going to add our for loop to this div. So adding this for loop is as simple as adding attributes, just like before when we used v-model but this time we use v-for, and then what is set is to be equal to name in guestName. So this first name is totally up to you, you can name it anything you want. It's just an alias for each array element that will loop over, guestName is name of the source array so it's the one we just created before and it's output the contents of this for loop, we use the interpolation again. So you see double curly braces and then we type in name, which we've used in the for loop. So now we can save this, refresh the browser and now if we go up to the inputs, we can begin to add names and we now see them outputted to the screen but this time using a for loop v-for can also be added to over elements. We're not just limited to admit to a div. It can be added to a span, paragraph tags or anything you like. So now we see the contents of the array display twice, once using the for loop and then once from the last video, where we outputted the guestName/ with the guestName inside of the curly braces and save that and now we're just left with the contents of the for loop. So this is how easy is to create a for loop using Vue.js. Now let's move on to conditional rendering where we'll look at if else statements using Vue.
12. Conditional rendering in Vue: Our app is now coming well. When we add a name to the input box and hit "Submit", the name is added to the attending div down at the bottom. As you can see there we still have the text saying no names added yet. We now want to look at conditional rendering. Conditional rendering is not as complicated as it may sound. It simply will render some content depending on the circumstances just like a normal JavaScript if-else statements, if you're familiar with these. In our case, if there are names inside the guest name array, we want to display them at the bottom. If there are no names inside the array, we only want to show the text saying no names added yet. We can add this inside the index.html page. If we locate the div with the class of card block, inside of our div with the class of card block, we have two divs inside there. The first is where we want to loop through the names and display them inside of the div tags. I'm going to add a if-statement to this div. Vue just makes it really easy for us to do with the v-if directive. Once you add this as an attribute, we then want to check if the length of the guest name array is greater than zero. If there are any names inside the array, the condition becomes true and the div is then rendered to the screen. Otherwise, if the array is empty then the condition is false. The following div will be rendered if we add a v-else statement. So let's add v-else to the following div. For the v-else to work it must immediately follow the elements with the v-if directive. If for example, there was another div in-between these two, the else statement would not work. Give that a save and head over to the browser and give that a refresh. Now we'll see the statement saying no names added yet. Then if we go up to our input box and add a name, we see the name is added and also the text is removed. Such are working good and I want to add a normal JavaScript if statement to our form submitted method and the reason for this is if we go over to our form, and we enter a name, we can see added to the list. So that's fine. However, if we just go to the input and press enter without a name we can still see that something is added to the array. Other than this, if-statement will make sure that name must be entered before it's pushed to the array. We can do this over in the form submitted method in the app.js file. Inside the function body we'll construct the existing code with an if-statements and the condition we want to check is if this.newNameText. Length is greater than zero or if some characters have been entered, then we want to go ahead and push this to the array. Let's give that a saved and test that in the browser. If we hit "Enter" on the form input, we see that no new name has been added to the array. Let's just add a new name and test that's working okay. There we go so all the p is fine. The last thing I want to do in this video is to display how many guests are attending or how many names we have inside the array. You can see if you just look up above the names, we can see there's a div with the class of card header with an attending section. Inside of the brackets I'm going to add the double curly braces, and then find out how many names is inside the guest name array. We simply type guestName.Length and this will output how many items are inside the array. Let's save that and add some names to the array and see if this works. Great. So we see that increasing by one with each name. Now this works because dot length is just a JavaScript property and we can add any JavaScript we want inside of these double braces. We're not just limited to outputting data from our Vue instance. For example, if we add 8 plus 10 also inside the double braces, and then go over to our app we can see that 10 is added to each number. So we'll just remove that because it's not needed for our app. Hopefully you can now see that we can now mix Vue data and also Vanilla JavaScript and we'll look at this more later on in the course but for now this is how conditional rendering or if-else statements work in Vue JS and you can now really see how simple it is to work with them.
13. Binding elements to attributes: I want to now show you how to use a directive called v-bind. We use this directive to work with normal HTML attributes such as class, source, and the href attributes. These are all just normal HTML attributes. However, we can not pass in reactive data to them using the double curly brace syntax. So in the index.html, if we locate the event date div with the class of card-header, it would try to add a new class with the name of [inaudible] and add this using a double curly brace syntax, this won't actually work. So to demonstrate this, let's add a new property over in app.js inside the data objects, just below the guestName array. So let's add 'formSubmitClass'. We'll use this to add a new class name whenever our form is submitted. To change the background color of the card headed div and also the blue button to green, I will initially set this to be an empty string. To begin with, because we only want to add a class when the form is actually submitted, so down in the form-submitted method, right at the very bottom, I'm going to add the formSubmitClass, and then we can set this to be something new each time the form is submitted. So I'm going to set this to be a text string of Submitted. So now each time a form is submitted, formSubmitClass will be set to the value of Submitted. Now down in the CSS, we can set the submittedClass to have a background color of green. So let's save that and go over to the browser. So you can see if we refresh and then hit the Submit button, that the background color doesn't change. So this is expected behavior because we mentioned before that the cards add dynamic data as an attribute. So to apply this class in HTML, we need to do two things. First, we need to remove the curly braces from the class and just have the data property inside of the causations. Then second, we need to add the v-bind prefix to the attribute name. So now it's worth noting as you can see inside of this element we do have two class attributes. One is the static HTML class which you can still use and also the one we just added with v-bind, which is reactive and under the control of view.js. We can also bind this attribute on more than one element, too. So let's add the formSubmitClass to the submitButton, too. This also means that if our data changes, the update will be reflected everywhere, too. So now let's give this a go. If we save that and then refresh the browser and add a name, we can see once the form is submitted that we do get the new background color. So just as a quick recap of what we have done there, we went into the HTML page and then added a class of formSubmitClass. Then inside of our data objects, we set this formSubmitClass to be empty originally. So this means that initially no new styles are added. We then changed his empty string to be the text of Submitted, just below inside the formSubmitted method. So each time the form is being submitted, the text of Submitted is added as a class. So we're not limited to just binding to classes, but combined to any normal HTML attribute too, such as we can add a source attribute if we are working with images and have the image file path controlled by view. The same with adding the style attributes, and this is what we'll look at in the next video.
14. Binding styles: Now we know how to use the v-bind directive to bind vue.js with HTML attributes. Now let's look at how to use the same directive that the style attributes. No, we can't pass in a double curly braces or the interpolation, which you pointed out in the last video. However, this time we can use the single curly braces. This is because we're passing in a style objects and objects inside a JavaScript that's surrounded by curly braces. Just like our data object inside the view instance. If you've used react. JS before, this way of an inline styles will look familiar to you. So if we go over to our CSS file for the row, and then click the margin top of 25 pixels. When I want to take this outside the CSS and place it into our HTML. So in the index page, if we locate the div with the class of row, which is just above the level one heading of guest list. I'm going to bind style attributes to this row and then also set the value inside an object, and then paste in margin top. It will just copy it from the CSS. So let's save that and give us a go and see what happens. So if we refresh the browser, we can see there's a blank page. So this doesn't appear to be working. If we right-click and go to inspect to open up the dev tools, we can see inside the "Console" that there's a red error message. So we get this error because this is JavaScripts, In between the braces and we need to name the CSS properties using camel case. This means that the first word is lowercase, and then each following word begins with a capital letter like this. So margin is lower case, followed by top with a T. Then also note that the value of 25 pixels is a string. So we can wrap this inside our quotations and remove the semicolon. Let's see how this is looking now. So save and then go over to the browser. So everything looks as it should, which is great. There's also another way of adding styles to our app. We can also declare our styling inside of the view instance as a data property. So back over in the app. j s, underneath the form submitted class that we created in the last video. I'm going to add a new date property called "appStyles". This is going to be set to an object. Then inside this object I'm going to add the same class of margin top, again using the camel case and set to 25 pixels. Now as we mentioned, we cannot inject this reactive data into our HTML with the double curly braces. We could not use double curly braces at all with any attributes. This includes the style attributes. So instead, over in the HTML, we can include it inside the quotations. We'll remove the existing object and add our new app styles inside of there. This HTML references a data inside of our app styles object. Of course we can also add more styles inside these objects if we want to. Or you can use this object multiple times within our app. This particular style applies to all of our free div's with the class of row. So let's reuse this on all of our free div's to get the correct styling. So I'm going to copy the style property. I paste it in the second row. Then do the same for the third row. So let's test that. Hit save and then go over to the browser. We can see the app looks back to normal. So just to double check, this is all working okay. I'm going to go over to the appStyles object once again and add a color of red. As you can see, any changes you make to the style object is changed throughout the app. So this is a few different ways of adding CSS to our app. We'll also use this again in the next project. But for now, we'll move on to the next video. We will take look at shorthand syntax.
15. Vue shorthand syntax: As it begins to build bigger projects both later on in this course and hopefully on your own in the future. It's worth knowing a few ways to make our code a little more compact. Even in the small app so far, we've used the V on and V binds quite a few times already. For this reason, view provides us with a little shortcut to make the syntax more compact. For the V by underactive, all we actually need to do is to remove V-binds, leaving only the colon and the attribute we are binding. Let's open up our index.html and let's go ahead and replace all of our binding attributes with the shorthand syntax. I'll show you the first one. If we go to the first row, we find it the style of app styles. We just need to remove V bind, leaving only the colon and style, and of course, this is something you could go ahead and do yourself if you want to pause the video and go for the index page and give us a go, and then of course come back when completed. I'm going to keep moving down the, up and changing this. We also have the second row just below with the app styles too. Let's change this. We don't have the "card header" with the class of form "submit class." Let's change that, and then scrolling down. We also have the class on the input side, and then a little further down, it looks like the last one is the final row with the class of "app styles." Let's change this. But is also a shorthand for when using v-on. We used v-on inside of the form elements to trigger a method every time the form has been submitted. Instead of using v-on, we can simply replace this with the at symbol. Let's go ahead and replace this now. Let's say this and just double-check it still working in the app. Our style seem to be working too. It looks like the classes is still bind it, and now if we add a name to the form input, we see that the name is still added to the guest list, which means that the submit button is still working. The shorthand syntax is optional and evil way is totally fine. As view JS deals with always in the background. But for the rest of this course, we'll be using the shortest syntax just to keep our code more compact.
16. Outputting text & HTML : So far in this course, we've outputted reactive data using interpolation or the double curly brace syntax. Now I want to introduce you to a few more directives which you may come across a lot of useful when outputting data. First is a simple one called v-text. V-text is used to obtain the elements text content. Text content, sets or returns the text content of an element. We can use it as an alternative to double curly braces to run the text just like this if we go over to our index page and locate the card block, which has the event information. Inside the level for heading, we can add the v-text as attributes and also set this equal to event.event title. You may notice we have event.event title twice; one is using v-text and one is using the original text interpolation. However, if we go to the browser and refresh, we can only see this title displayed once. This is because the original title use need double curly braces is replaced by setting the text content attributes. We can prove this by going over to v-text and changing this to event.eventTitle2. Then if we go over to app.js, we can add our eventTitle2, just below the original event title and want to set this to a string of v-text output so we can clearly see the difference. Once you've added up, let's go over to the browser and then refresh. We can still see that the v-text will take priority even though the double curly braces is still in place. The next directive I want to look at is v-html. V-texts, which we've just looked at, updates the elements text content. Whereas using v-html, we obtain the elements in HTML. You may be familiar with certain in HTML if you've used JavaScript before. v-html if you've used to output real HTML. If we tried to add HTML code inside the double curly braces, it will be interpreted as plain text. Let's take a look at this in action, if we go back to the index page with our event information. If we cut out the text or add name to the guest list for exclusive offers. So could this. Then if we go over to the app.js, we can add a new dates property of sign-up texts and then paste this in as a string, so save that and then if you add some content, such as adding the m tags around the word exclusive. Now we go and make show text and HTML. Let's try and render this over in the index page. If we go back to where we just cut out the text and we'll try to output this with the double curly braces, so event.signUpText and then save that. If we refresh the browser, the HTML is outputted as text, so we can see the HTML tags. This isn't what we want. Instead to display this correctly, we need to add the sign up text to the v-html directive. Let's add v html as an attribute and then remove the curly braces and now I hit "Save". Now if we refresh the data is rendered as HTML and we now have the word exclusive emphasized as we intended. We do need to be cautious, however, when using v-html for security reasons. Anywhere where HTML is dynamically added to our website, we should only use v-html on trusted content. We must not allow it to be used when content is provided by an end-user, as this can lead to potential cross-site scripting attacks, so just be aware of this. Also if we're working with just text, using v-text to obtain the text content can be safer and also help against these attacks. It can also have better performance for plain text 2, as a text is not passed as HTML. Finally, the last directive I want to show you in this video is v-once. This can be used to render data only once. Once the data is rendered using view, if the data is unchanged, the elements or components will not be updated or re-rendered. This can be used to optimize performance for our app to avoid unnecessary re-rendering. Our event title may be a good use case for this, as we can expect that once an event is created, the name will remain the same. All we need to do to enable this one's only rendering is to add the v-once directive to the elements. Let's remove this v-text attribute and then replace it with v-once. This now means that data will only be loaded once and not for any data changes in the future. We can't currently demonstrate since we're not using a web server to serve our page at the moments so the data will not be updated anyway from the view instance. We've just simply open up the index page to view in the browser. We can see this in action in a later video, where we'll use a development server. But for now you can see that this is available if needed. This is how we can use the v-text, v-HTML and v-once directives. Next up, let's look at an alternative to v-if, which we looked at early on in this section.
17. V-if vs v-show: We looked at the v-if directive earlier on in this section. This allowed us to show guest names in the div at the bottom of the page if any names exist. Otherwise, we display the text of no names added yet. There is also an alternative syntax which Vue.js makes available to us called v-show. This is also a directive which conditionally renders some content, just like when using v-if. However, there are some differences which we will look at now. First if we go to our index page and look for the v-if statements, that changes to v-show. If we save that and then go over to our app and then hit refresh, the first thing we'll see is the text inside the else condition is gone. This behavior is expected. As of course, a v-else statement can only follow a v-if statement. If we go to the console, we can see that this error is highlighted inside there. There is also another difference going on behind the scenes, which relates to how the element is rendered. When using v-if, the element it is linked to is added to the DOM when the condition becomes true, then it is destroyed or completely removed from the DOM when the condition becomes false. So because v-if is only rendered when needed, it can save on render time if this is a concern. V-show works a little differently. The element v-show is attached to is always rendered, regardless if the condition is true or false to begin with. It is then toggled on or off by changing the CSS display property. Let's take a look at this in action. If we open up the Developer tools and go to Inspect, we can see this in action by selecting the div inside the card-block div, that the display property is set to none, which has the effect of hiding the elements. If we then add a name to the input field, we see that the display property of none is then removed and we now see that the div tags with the name is added. For the case of this particular app, we also need to use the v-else directive. So I'm going to stick with using v-if and v-else. However, using v-show is a good alternative if you want to keep your elements inside of the DOM and just hide them, rather than completely destroying and re-render into the DOM when required. The performance difference between toggling the display property versus rendering using v-if may never be an issue for you, but it is worth knowing the difference, especially on larger scale apps.
18. Using Javascript expressions: Inside of our app, we have displayed some interactive data by adding dates properties into our view instance. Then I'll put in them using the double curly braces. When using these curly braces, we can do more than just add the name of the date property which you want to display inside of our templates. We can actually make use of JavaScript expressions or even combine our view data with regular JavaScript. First, let's go over to our app.js and add some names into our guest name array. Just to initially display, you can use any names that you want. I'm going to add the names of James, Chris, and Sam. If you're using different names, make sure these names and mixed up. They're not in alphabetical order. We'll see why soon. Save that. If we go over to the browser, we can see these names are initially added. Now let's go over to our index page and take a look at how we can use JavaScript expressions inside of our double curly braces. Currently inside the full loop we're outputting the name. We can combine this with JavaScript, such as using two lowercase. This will make sure that any capsule as inside of the name is changed to lowercase. Let's take a look at this inside the browser. Now we can see that the first letter of each name is now lowercase. This is a mixture of using vue.js and regular JavaScript. We can also go even further and add a string until the end of this. Name dot two lowercase, then plus a string of is awesome. Give that a go. Then over in Chrome, let's refresh. Now we've got the string added onto the end of the name. There is a limitation, however, that we can only use a single JavaScript expression. We can't use things like a if-else statement inside of here. It's also not the way to go if we're using the same code over and over again. Restricting the amount of JavaScript we can use inside of our templates makes our code more manageable. As then we need to move all complex logic inside of the view instance. This makes our code more reusable. We can reuse it in different areas of our app when needed. We will look at how to handle more complex conditions in the next section. But this is useful for performing simple tasks. We also have access to the full power of JavaScript's, even when not using vue.js data. Add small curly braces just below. For example, we can add a math calculation. Five divided by two. Let's see it on the screen. Okay, and also blow this, if we go back to the index page, we can add a math dot random for example. Math dot random between the curly braces and then save. Now we can also see the random number on the screen too, well, not just restricted to output and this JavaScript using double curly braces. You can also use it anywhere we have access to our view instance. For example, we can also use it inside our V HTML directive within the quotations. Let's go up to the V HTML directive. Then inside the quotations, we can add math dot random and save that. Now if we refresh the page and check, we see a random number now on screen. I'm just going to quickly changes back to name and save that. This is how we can use the full power of JavaScript inside of our view templates.
19. Section Outro: Vue Basics : Congratulations on reaching the end of this section. Hopefully already you can see how fun and easy is to get started with view JS. You've already learned a lot of new concepts, such as how to set up the view instance, two-way data binding, event handling, lists handling and much more. In the next section we'll step things up a little by covering even more essential view topics, along with completing our guest list application.
20. Section Intro: A Deeper Look At Vue : Welcome to this new section. We will begin to take a deeper look into what Vue.js has to offer. We'll continue to build our guest list up by adding new features and learning more about Vue.js, such as computed properties, watches, and filters. By the end of this section, you will have a good understanding of a lot of the Vue.js essentials and how it all fits together after completing your first project. Let's begin right away with improved note up by adding a progress bar.
21. Adding a progress bar: In this video, we're going to add a progress bar to our application. We also going to restrict the number of names we can add to our events on the guest list. This progress bar will then increase as a percentage as the guest name array fills up. This will give us a chance to get more practice by adding reactive data to our app, and also bind in style attributes which we covered in the last section. Let's begin by removing the green color, when the form is submitted as we will now have a visual indication with the progress bar. Over in the index.html, let's remove the binding classes that were added in the last section. Select remove formSubmitClass from all the locations. Also let's remove this from the data object in app.js. Let's go over and remove this from the data object. Then further down let's remove the formSubmitClass reference from our method. Then finally, we don't need the submitted styles over in app.css, you can also remove them too. Now that's taken care of we can go back over to the Index page and we can start to add our progress bar. I'm going to add this near the bottom of the page. If we look for the attending text, which displays how many names are on the list. Just below that, I'm going to add a break tag and then add a HTML5 progress bar. Which comes to be a plain progress bar for now. We can save and just check that's appearing on the screen. Great, we want this progress bar to increase every time a name is added to the guest list. To do that we need to work out a percentage. Over in the app.js I'm going to add two new data properties to the data objects. The first one is going to be the event capacity so you can set how many names you want as a maximum. I'm going to say, event capacity to initially be 25. Then just below that, I'm also going to set the eventCapacityPercentage. This is just going to be set as zero initially. We use this to work out how full the event is as a percentage. We're going to calculate this inside of the form submitted method. If we scroll down to this method and then just below this.newNameText. We're going to set this.eventCapacityPercentage, and we going to calculate the percentage here. This is going to be equal to this.guestName.length. The number of names on the guest list divided by this.eventCapacity, we'll divide that by 100 to turn it into a percentage. Now we have the percentage as a value between zero and 100. We can take our knowledge of binding styles from the last section and use it set the width of the progress bar. Let's go back over to the progress bar and then add a style attribute. Again, we know we need to use the colon because this is dynamic data. We're going to start the styles inside the braces as an object. The only style we need to add is the width. The width is going to be set to the eventCapacityPercentage that we just created before. Of course this will go up as the capacity changes. Then on to the end we're going to add a string, which is just the percentage symbol. All we're doing here is setting the CSS width property, by making the percentage value reactive rather than just hand coding in a set number. Let's save that and with this in place, let's go over to the browser and test its working. We can add some names and often the progress bar increases with each one. Great. It starts increasing, so it all appears to be working fine. At the moment we've got the attending text which shows how many people are currently coming to the events. I want to now also adds the capacity so we can see how many people are also allowed to attend. We already have all the data we need to complete this, back in the Index page next to the attending text. We already have the guestName.length being outputted. After this I'm going to add a forward slash and then simply output the eventCapacity. Now when we go to the app, we should see one of 25 and two of 25, and this is increasing every time we add a new name. This is working and also the progress bar seems to work in final. But there is one problem. We can still go over the total number of names we set, we can go over 25. This causes a progress bar to go off the screen and also the number in the attending section to keep going over the maximum allowed. Just add lots more names and get up to the maximum. We can see that we can clearly go over that. This can be easily fixed by adding another combination to test inside of our form submitted method. Back over in the app.js. We know we already have an [inaudible] statement check if there is a name entered. We can also just add a second check to determine if the eventCapacityPercentage is less than 100 percent. If it doesn't want to continue to add names. After this.newNameText.length is greater than zero, this.eventCapacityPercentage is less than 100. If the capacity is less than 100 percent, we can still continue to add names to the array. If the percentage is over 100 or equal to 100, then no new names will be pushed to the array. Let's give this a go if we go back over to the app and then refresh, we can still add names to the guest list, no problem. Once we get to 25, we should see that no new names can be added. There we go, we now hit the capacity and no new names are being accepted onto the array. Now let's move on to take a look at how we can handle more complex logic by using computed properties.
22. Computed properties: Far in this course, inside of the few instance, we've looked at how we can work with data, using a data objects. We've also looked at how we can add a message object to, which you can use to add functionality to our application. Now I want to show you a third property which we cannot all view instance called computed properties. We mentioned in the last video that in too many JavaScript expressions inside of our template, can make the code less reusable and harder to maintain. We also limited using one JavaScript expression. This is where computed properties come in. We add them to our view instance just like the data and methods objects to add more complex logic. There is also another big difference which we'll look at soon. Let's add our computed section, followed by the colon, and this is also an object. We can add our properties inside of the computed object, just like we've done inside of the methods object. I'm going to use a computed property to sort the case names, in our array and then return them in alphabetical order. It needs type in the name. In this case I'm going to call this sort names, and this is a function. Then inside the body we are going to return some data, and the data we want to return is this dot case name dot sort. Using salt is normal JavaScript array method, just like when we use the push method in forms submitted above. For this to work, we need to change one thing inside our index dot HTML. We now need to look through the sort names rather than guest name. Go over to the index page, and change case name to be our computer property of sort names. Then let's take a look at this inside the browser and we should now see them sorted in alphabetical order. We use a computed property when our code within relies on interval property, or any of the data from our view instance, few JS watches contents and is aware of the computer code and any of its dependencies. In this example, we use the guest name data, which means will be aware that it is there. It will cache the data or the only re-render when the guest name dependency has changed. This is where the difference lies between computed properties and methods. Methods on the other hand, will always re render when anything changes, even if there is no change to the data that it displays. Let's take a look at this in action by logging to the console. First name are the console log to the form submitted method and just simply console log the text of method. In the new computed property that we just created. We want to log to the console the texts of computed. If we go over to the browser and then right-click and open up the console. If we then add a name to our guest list and hit submit, we can see that both method uncomputed above logged to the console. This is expected because we've added to the guest name array inside the computer property. It's watching the guest name property as a dependency. So view is aware that the changes occurred and then re-renders a content. We have the method log because as we mentioned before, methods always re render, when anything changes, even if the data inside has not changed. Let's see this behavior in action by adding a new method. I'm going to go over to the index page and add a button. Just blow the input bone, at the normal HTML button with the text or call a method. Then we can add a click listener using the short hand. So on click, I'm going set this to a method call. Now we can go and create this method call inside of the app.js Make sure this is below the form submitted method and separated with a comma. We set up this method call, just before all this function, and then inside of the body, we're going to set the styles. All we're going do is set this up styles and then change the margin top to be 50 pixels. This is a method which has nothing to do with the guest name data. Let's see what happens when we call this new method. Let's go back over to the App, type in a new name into the input field and then click submit. We see both the methods and computed first, which is a behavior we have seen before, this is what we expect. However, when we call the new method by pressing the new button, we only see the method logged, this is because our new method call only effects the margin top data property and have a computed property is only watching for changes to the guest name property. This means that, computed will not be logged because no changes has been made. However, we still get a method call because all methods are always re-rendered, even if the data inside them has not changed. This means unless you have a specific reason to re-render method each time, then computed properties will be a more efficient way of doing things. For a lot of cases. Using a computed property, auto method will achieve the same results.Just bear in mind this difference in the behavior behind the scenes. Before we wrap up this video is a few key points I want to show you. First of all, let's add a test to our methods objects, to simply do a console log. Let's go back of the methods and creates our test method, satisfying the same way as a function which does a console log and simply outputs the console, the texts of method text. Over in the index page, I'm going to go below the button which is created and call this method inside of our double curly braces. At the method name of test, save that and let's go over to the browser. We can see that we'll get an error. This is because when calling a method inside the triple curly braces as a JavaScript expression, we need to call it use the parenthesis. So are the parenthesis just after text. Let's save and take a look at that and we can see in our works. However, when colonists as a computed property, the parenthesis is not used. The series action, we can move our method over in after JS and setup a computed property in place. Let's put this and then paste it below as a computed property, and then save that. If we remove the parentheses over in the index page, and then say if we can go over to the browser and we can see that this now works, will now get the console log to. One drawback when using computed properties is that, we are unable to perform asynchronous tasks. We can however do this by using a watch option, which is provided by VGS. This is also an alternative computed properties, and we'll take a look at this in the next video.
23. Watchers: In the last video, we looked at using computed properties, which are a great way to add functionality to our app. Computed properties watch the code and will only react if any of the data changes. As an alternative Vue.js also provides us with a watch property, which we can use when we want to watch a data property and react to any changes. Using Watch also allows us to perform asynchronous tasks which we are unable to use with computed properties. We set up the watch objects on the vue instance, just like we did with computed methods and data. To begin, I'm going to start by deleting the examples from the last video. So in app.js, we can delete the test method. We can also remove method call. So remove those two and then back in index.html, we can also remove the Example button that we added too. Once this is done, let's go back over to the app.js and that set up our Watch object. This of course is added just like the other objects that we've looked at. So add a comma just after the computed section, and then add our watch object. Inside of the watch object, we can set a data property which you want to observe. This name must match an existing data name. So for example, we need to use guestName or something such as eventDate, which we already have inside of our data property. I'm going to watch our guestName property. We then specify a function which we want to run when there is a change to guestName. Upon change Vue.js will pass the value of this change to the function.Inside of the function parentheses, we can pass in a name we want to give to the data vue will pass in. This name can be anything it wants, but I'm going to call it data, and then inside of the function, I'm going to log to the console a message when guestName, which is being observed by the watcher, is changed. Then let's add the console log of watch triggered. Then let's open up the console in the browser, and then add some names to the guest list. So one thing you'll notice is watch triggered is printed twice per name added. This is because we are observing the data property of guestName. GuestName is changed twice. It's changed once inside of the form submitted method, and then once again inside of the computed property, to sort the names into alphabetical order. So we can see this data is being observed and the function runs on each change.Of course, this is a basic example, but it gives you an idea of how they can be used. We'll use a more later as we go through the course projects. For performance reasons, usually it's better to use a computed property wherever possible because of this efficient rendering due to caching. But watchers, as we've discussed, are useful for observing changes in data properties and also useful for asynchronous tasks, such as accessing API data.
24. Key events & modifiers: Earlier in the course, we looked at event handlers, using the V on Directive, we then change V on to a shorter syntax by using the @ symbol. This triggered the form submitted method, when the submit event was detected. We also mentioned that we're not limited to using just submit. We do also have access to the full range of HTML events, such as on-click, on-change, and on-mode to name a few. A long way to trigger events, we can also use the V on Directive, the shorthand @ symbol to do something when a keyboard key is pressed. Inside of our inputs, I'm going to add a keyboard event to our name input. We can use standard keyboard events, such as key-down. In this example, I'm going to use key-up, followed by the key code we want to watch for. Once the key number 32, which is the space bar, is released, we trigger a method called key pressed. We have not yet setup the key pressed method, so let's do that now. Head over to the Up.js, and then let's add a new method. This method of course is called key pressed. All it want us to do is to add a console log, and inside this console log, we just go to print the text of key pressed. This will simply log to the console key pressed once the space key is being released. So let's save this and open this up inside of the console. If we press the space bar inside of the name input field, we can see our key events have been detected. So for this example, we use key number 32, which is the space bar. We can Google JavaScript key codes for a full list of numbers for all keys if we want to. However, Vue.js too also provide us with some aliases for common keys. We can replace key number 32 with the word space, and then give us a try if we refresh. This works just the same, but it's more readable and easier to remember. Vue.js also allows us to use enter, tab, delete, escape, up-down, and also left and rights in the place of any of the key codes. Let's just try one more. We can change space to the escape key, so say that and press the escape key, and it works just as before. This is how we can use keys to trigger events, and how we can use key modifiers, or aliases in our Vue projects.
25. Filters: Vue JS also provides us with a property called filters, which we can also add to our view instance. Filters are designed to apply common text formatting or transformation, such as changing strings to upper or lowercase. They not intended to be used for complex tasks. If you have something more complex then it is bad to use a computed property instead. Adding filters is made really simple. We can add them even when using v-bind, which we looked at earlier, or using the double curly brace syntax. To see this in action, I'm going to go over to our for loop in the index.html. Then inside the double curly braces will have name. We keep in place the name expression and then add our filter name after, separated by a pipe symbol. If we add a filter using v-bind, we can do exactly the same. We simply add the JavaScript expression first, then the name of the filter separated by the pipe. Then over in our view instance, we add our filters property. This is of course where we add all our filters. Let's add our two upper filter that we've just added. The syntax is just the same as the watchers that we looked at before. This is a function which takes in the value of the data passed to it. For our example, it will be the value of name. Just like when we looked at using watchers, we can name this value anything we like. We'll then return the value transformed to uppercase. See our uppercase. It's just plain JavaScript and is not provided to us by Vue JS. Again, this is a good example of how we can make Vue JS's data with plain JavaScript. Let's save this and test in the browser. Go to the input field, and if we type a name inside of there with lowercase and then press "Enter", we can see that the name is now transformed to uppercase. We can also use multiple filters and chain them together. All we need to do is go back over to the double curly braces where we added the first filter. Again, you separate it by a pipe we add the name of our second filter, which we want to apply. This works from left to right. In this case, "name" will be then passed to, "toUpper" filter. Then the value of the toUpper filter will then be passed to "formatName". So the order is important. We can see this order in action if we add the "formatName" filter over in the app.js. Just below the "toUpper" filter separated by a comma. We can add a "formatName". Again, this function takes in the value which is passed to it from "toUpper". Then if we simply console log the value passed to it, then go to the browser and open up the console. We can see that the value is in capital letters. This shows that we are getting the name value after it's been through the first filter. This is just an example, so we can remove the two upper filter and also remove it from our index page. Now we can add some formatting to our name and then go back over to our filter and remove the console log. The format in which we are going to apply is going to take the name that the user types in, is going to slice the first letter and then transform these to be uppercase. All the remaining characters afterwards will transform to lowercase. To do this, we're going to return the "value.slice". We're going to slice our position zero, which is the first letter. We only want the slice this first letter, so this is only going to be for one position. This first letter, then we are going to transform to uppercase. Then we're going to add to the end of this uppercase letter, again, the "value.slice". This is going to be the rest of the characters from position one onwards. All the rest is characters are going to be set to lowercase. Let's add this onto the end and then save that. Now if I go over to the browser. Let's add a name with a mixture of upper and lowercase and then press "Enter", and we can see the name is correctly formatted now. Of course, more complex formatting such as if the user adds a name with a surname or even free names, we needs to do a little bit more work to get around this. This may be a good case to switch to a computed value rather than the filter. Both for simple text formatting, using filters is an ideal way to do this.
26. More on looping: keys & index numbers: In this video, we're going to take a little bit of a deeper look into using fore-loops. We're going to show you how to add keys and also how to add index numbers to each item. Sometimes when we loop through an array, just like when we loop through all our guests names and display them to the screen, we may have a need to grab the index number for each item inside of the array. The index number is the position of each item. For example, the first name added is position zero because arrays always begin at position zero. The second name added will be at position one, and so on. We have access to this index number in VUGS when using a v-for loop. All we need to do is add a second argument to the v-for loop like this. Make sure you're in the index.html. If we scroll down to the bottom, we have the v-for loop to loop through the guest names. The inside this v-for loop, we can add our second argument. We need to rap them inside the brackets. The first argument is still the name which we give to each value inside of the loop. Then the second is a name we want to give to the index number. Both of these names are totally up to us. We can choose whatever we want, but it's best to keep them more descriptive if possible. Now the name for the index is set. We can add this using the double curly braces. Just after our formative name, we're going to output inside the brackets the value of our index. Now if we save and go over to the browser, we can see the index position of each name. We learned early that we can also add JavaScript inside of this double curly brace syntax. Let's take advantage of this by going back to the index and adding plus one to the index number. This means our index now begins at position one rather than zero. We add index plus one, and save that. Now if we go back to our application and add some names, we now have the index number matching the number of guests. Next, I want to take a look at adding keys to our loops. We can also allow view to better track our array values by providing a unique key to each of the items. It's recommended to use a unique key with v-for wherever possible. The default behavior view uses when updating a list of elements, such as an array, is the patch and element in place at a particular index number. If [inaudible] adds an array, it patches this extra item in place at the designated index position rather than move [inaudible] elements around to the correct order. This makes for an efficient way of doing things, but we can go one better. We can make sure each item in the array has a unique identifier, which we can reference if we need to make a change. View can then track each item and can move things about when updating, and even reuse items when needed. At any unique key means view is now aware of the items, rather than just knowing which index position it needs to patch in a new value. This makes for safer and more predictable behavior when changing values in an array. We can add key by going over to our for-loop. We use colon for dynamic binding, and the name we give to this key is important too. It must link up to some existing reactive data. If we try to add a random name which is not declared in the view instance, we will get an error. Let's just type in random name and then save that. Then if we go to the app and add a name to the guest list, open up the console, we'll see an error. We can use an existing data such as our guest name. Let's type a name inside the key. Now if we save that and go over to the browser. If we hit refresh, we can now see that the error message is being removed. Now view recognizes this name as a date property. Now this may not be ideal because we may have more than one person with the same name. We could set up an object to hold a unique ID with each guest name. Also open new date property to hold a unique value, and then use it as a key. For now, I'm just going to leave and come back to this in a few videos time. The main thing to understand is that when creating a for-loop, it really is best practice to add a key to a list of values wherever possible.
27. Using multiple Vue instances: In our guest list app, currently, we only use one Vue js instance to control the whole of our application. This is fine and small up like this one. But in large apps, we may find it more convenient to split certain functionality or certain data into multiple instances. Using multiple instances is perfectly fine to do, may even make sense in some cases, where we want the code to be contained into sections. We do this just as before. We create a new Vue instance and also a new HTML section, such as the div to bind to our data. Let's get started with this now. If we go over to the index.html, we currently have the first view instance linked to this div with the id of app. The first thing I want to do is to cut the opening container div and then move this to the top. This is so it contains our existing content and also the new navigation div, which now I'm going to add. Let's create a new div with an id of navigation. This id will link to our Vue instance using the el property and we'll create this soon. Then I'm going to cut the first row from our app and then paste this inside of the navigation section that we just create. Now, we've got this new navigation section. I'm going to go over to app.js and we can create a new Vue instance just below the last one. If you go to the bottom, we can now type "New View," and then again just enter the object inside of the parentheses. The first property again, we need to add is el. This is an ID of navigation. Let's add this in at the top. Then we can add our data objects. We're going to add some reactive data into here, such as the app name. I'm going to set the app name to be equal to guest list, which is what we currently have. Then if we go back over to our navigation div, we can then use a double curly braces to replace the guest list text with our app name. Save that and if we test this in the browser, we shouldn't see any difference. which means it's all working okay. There is one drawback to doing this however, the data contained in each Vue instance is separated from each other. This means we can only use this keyword to access data inside of the view instance it is used in. If go back to the first Vue instance and then add a console log. I'm going to add this inside of the form submitted method and I want to log this.app name. Remember the app name is a data property from our second instance. Let's save this and see what happens. If we go over to the browser, open up the console, and click on the "Form Submit" button, we get a red warning message saying the property of app styles is not defined. This is because of the same problem. The app styles object is a data property inside of the first instance. Here, we also trying to access this inside of the index.html within the section control by the second instance of navigation. We know now how to bind styles. Let's move back the styles into the stylesheet so can access a everywhere. We can go over to the Vue instance and delete the app styles object. Now, these are deleted. We can go back over to the app.css and then re-introduced the margin top of 25 pixels. This margin is added to all the rows, so use the row as the selector and then add in the margin top of 25 pixels, and then save that. Then if we go back over to the index.html page, we can delete the app styles style property in all the locations. That's the first one and then a second one. Then finally, let's remove the third and final one. Then we can also remove the console log from the method. Let's go back over to the app.js and down to the forms submitted method and then remove this. Now, if we save this and go back over to the browser and refresh, we should see that everything is working fine again. Splitting up sections into multiple Vue instances is perfectly fine to do and it's also practical if the code contained in each instance is not related or there is no reason to require data from other instances. There is waste accesses data from over instances with other methods. But we'll cover this later in this section. We'll continue next by adding some navigation links to our new instance and also using these links to see how we can loop through objects.
28. Looping with objects: We have already covered looping through arrays during this project. In this video, I want to continue with our new vue instance, by adding a new array objects of navigation links, which we can also loop through. The values in this object also contains AID. So you can also use this to add a unique key. So view can keep track of the items listed inside of our app.js. Let's begin creating our array of objects, toward our navigation links. Underneath the app name. I'm going to start with the name of navLinks. This is going to be an array. Each array item is an object which has a key value pair of name and ID. Let's open the curly braces for the first link. I'm going to set the name as the key, and home as the value. Then separate by a comma. We're also going to add an ID. So I'm going to keep it simple and start with ID of one, and then separate it by a comma, we can start our second link. So I'm going to copy and paste the first item. Change the name to upcoming events, and then also change the ID to number 2. Then once more, paste the same, and we'll call this one guest benefits. Give us an ID of three, and then the final link, we're going to add latest news, and then cause it to be ID number 4. Then let's go also to our index.html web page, and look at how we can loop through this array of objects. I'm going to create a new div for this, just underneath the closing div tag for the app name. Create the surrounding div, and then inside here I'm going to create a unordered list, to display all the links from navigation. Then within this, we want to add a HTML template tag. This template tag can be used with V4 and also VF2. To render a block of multiple elements. Template is just a container, just like an ordinary div. But this template element will not be rendered to the DOM. Then we'd inside this template we can create the V4 loop. So I'm going to call this navLink in navLinks. Of course, navLinks is the name of the date property that we've created. Then we didn't align items, we're going to create our list items. We use this with the double curly braces. The first one is going to be navLink.name. I'll create one more list item below, which is going to be navLink.id. This will select the name and id for each individual object. So now we have the content inside the template. If we go over to the div tools, we can select the div that we've created. We select the unordered list. We can see that the ul tags is there, and then it's followed by the content within the template tags. So we don't actually see the template element rendered to the screen. But we do see on the screen the name and also the id for each object inside of our array. We can also display the key value pairs of each object tool. Key in both the name and also the id from the object. Being the value after the key, such as home and one. We can simplify what we already have into one list item. So if we delete the second list item, and then we can add a second V4 loop. This one is going to be value in navLink. The name value is optional. This can be anything we want, but the name navLink is also optional, but he must match the name inside the outer loop. We'll also add a horizontal rule, so can separate each list item. Now if we add value into the double curly braces, you can see this output to the screen. So go over to the browser, and it prints out the keys and the values of the objects as a pair. We can also separate them to work with them independently. If we surround value inside the brackets. We can also add a key, which means we have both the key and the value available to use independently. So after value, add a comma and then key. Now instead of just outputting the value, will also output the key separate with the pipe, and then back over to the browser. We can see this in action. We have the key and value printed for each object. We can also add a third argument is key and value. Remember we added a index number to the V4 loop to print the names in our guest list. Well, we can also do the same here with the third arguments. I'm going to call it index again, because it makes sense to name this. So separated by comma add index as the third argument. Then as a third argument inside the double curly braces, we're also going to print out the index. So save and then go over to our project and then refresh. Now we can also see the index printed next to each item. Now we know how to loop through objects. Let's put his technique into practice in the next video. By our navigation links, how we want them to look inside our app.
29. Adding our navigation links & keys: Now we know how to work with looping through objects, let's structure this so it's more suited to our application. We'll also add a unique key to each item and make sure each navigation item has a URL to link to. To begin, I'm going to remove the full list item from the last video. Then replace this with a standard list item, which outputs the navLink dot name. This will simply show the names from our links, and because this is a nav bar, we also want to make these links. Let's go ahead and surround the nav link with a tags. Add them inside the list items. At the a tag with the href, and just leave this empty for now and then close off the a tag. Now let's add some links to our object to link to, back over in the nav links in the App dot js. After the ID most you want to add a URL to link to. This is just going to be a dummy link just to test its working, after the comma we'll add the URL and add a link, I'm just going to use Google for this example. Type in H-T-T-P-S colon forward slash, forward slash, and then www dot google dot com. Then we can copy this and paste this in, in the four links. I'll set the second one to go to Amazon dot com, the third one to go to eBay, and then the forth form we will add as Facebook. Now we have a URL to add to our a tags in HTML. Remember from the last section we said that we can not use the double curly braces to add reactive data to HTML attributes like this. It could add the double curly braces, and then add navlink dot URL. For this to work, we need to use the V bind directive to add to our URL, or I'm going to use the shorthand technique of just the colon. We also need to remove the double curly braces for this to work inside of an attribute. Let's save this, and if we go over to our navigation links in the browser, we can click on the links and test the work. They all appear to be working fine. We'll just try one more. Great. Now the links work as we want. It's time to now add some styling to the links. Since already we have Bootstrap linked to our project. We can add some Bootstrap classes to our navigation. First of all, if we open up the URL tag, we can add a Bootstrap class of nav, and then in the list items we can also add a cluster too. Again, this is a Bootstrap class of nav hyphen item. Then inside the links will add a class of navLink, and then if you want to add some horizontal lines in place just to break up our app. The first one I'm going to add just underneath the level one heading of our app name, so add hr inside there. The second one is just before the closing div with the ID of navigation and this will add a line above and also below our navigation links. The final thing I want to do to our navigation is to add a unique key to each list item. We touched on this a few videos ago. But this time we now have access to an ID inside of our nav links object. This makes for an ideal key because we have each value set to be unique. Now let's go back over to our HTML. Now let's add this key inside the template element just after the for loop. Bind the key and set this equal to navLink dot ID. In theory they should work. But however, there will be a small problem, which we'll see if we go over to the developer tools. Right-click and inspect. We see the red warning saying template cannot be keyed. Places key on real elements instead. We get the warning that we need to use this on a real element because template is used as a container for its templated contents. It acts as a wrapper rather than a HTML element. To fix this, we can change the template tags to something else, such as a div and save that. Now if we go back to the console and refresh, there now goes away and we have a unique key working on our navigation. That's now our navigation completed and also our second view instance. We'll build on this in the next video, where we'll look at how we can access a view instance externally from another view instance.
30. Accessing Vue instances externally: We now know that we can use multiple Vue instances to control a particular sections of our application. We discussed how may be useful to do this, to group-related functionality together, such as grouping all the Navbar functionality, as in our example, or even a sidebar maybe could use case. We can't directly access things such as our data and methods from an instance, from inside of a different instance using this keyword; however, there is another way to get around this. If you want to access data from an instance externally, we can give each instance a variable name. If go over to our app.js and this one make this a little bit more readable by clicking on the collapse button on the left. We'll do that for our first instance. On second instance. Just before we call New Vue, and we want to add a variable name of vm1 and set this equal to our new view instance; and then do the same for the second one; So variable vm2. You'll often see these variables called vm. Distance for vue model, as Vue was inspired by the MVVM design pattern. You can read more about this with the link at the end of the section if you like. This variable name is totally up to you though. It can be named anything you like. Then I can reference our instance outside the instance using normal JavaScript. So if we wanted to change from data in the first instance of vm1, such as the event capacity. We can do it like this. If we make sure the outside both vm1 and vm2, we can select vm1. eventCapacity'. Then I'm gonna set this to be 15. Now if we go over to the app, we can see the change. We can see Attending is now 0 or 15, rather than o of 25. Its changes being done with normal JavaScript and from outside of the view instance. We can also do the same, but from within our second instance. Let's add a method to our vm2 instance. This method I'm going to call 'capacity changed. Then within here we can cut the JavaScript that we used before. So cut 'vm1.eventCapacity. Now paste this inside of the function. Then over in HTML, we can call this method by adding a new button. Let's add a new button inside of the navigation section. Just after the horizontal line, I'm going to add a button with a click handler. This is going to trigger the capacity change method. So when this method is called, the method is run inside of the vm2 instance. However, it is changing the event capacity data from our vm1 instance. Save that. If we refresh the browser and then click the button, the capacity should change again to 15. This is a really simple example of how we can access instances, both would using JavaScript externally and also from within of instances. It's important to know how to do this, if we ever need to have access to our instances from external sources. We'll leave this video there and I'll see you next time.
31. Vue instance properties & methods: During building this project, we've added our own properties and our own methods to the Vue instance along with these, which we should now have a better understanding of how to work with them. Vue also provides us with some properties and methods which we have access to. If we go over to vuejs.org, which takes us to the Vue Homepage. Then if you click on the API link at the top, we can see the API documentation. If we scroll down using the navigation on the left, we can see some familiar looking things, such as our options of data, computed on methods. Further down there's what we call instance properties and instance methods. All of these properties are methods, also have a $ sign prefix, so we can easily distinguish them from others. If we go over to our app, we can see these as part of our instances. Let's go over to app.js. You have to go right down to the bottom we can create a console log. I'm just going to console log the contents of vm1 which is our first Vue instance. Now let's go over to the browser and open this up in the console. We can see we've got the contents of the Vue instance. Some of this you will already recognize, such as the 'el' property, which you can see is managing our div with the idea of app, which we set earlier. We can use these properties and methods, prefix with a $ symbol, to access data that we need. For example, we can change our console log to display the 'el' property by adding a $el after vm1. Then inside of the console, we can see the div with the class of app, which our instance is managing. Let's just remove this el property and take a look at the full instance again. There is a lot going on here and we'll take a look at more of these as we go through the course. One thing I want to draw your attention to is down near the bottom, you can see there is lot of getters and setters. These are used to get values and set values and means that Vue can watch and react to changes. These getters and setters are added upon creation of the Vue instance. You can see that these all of our data properties, which Vue proxies for us and also our computed methods. We have forms submitted and keyPressed above them, which does not have any getters or setters. This is because they are our methods. As we know, methods do not watch and react to changes, they simply re-render when there is change to the app. Also, if we add a new property to a Vue instance after it's created, it's not proxied by Vue.js, so it's not reactive. Therefore, not watch for any changes. We can see this in action by adding a new property to vm1. Back over in app.js, if we add vm1.title, which doesn't yet exist, and we'll set that to a text string of new title. Now, if we go to the vm1 instance in the console, we can see we have added a new property called title for the Arnold getters or setters. The property is not reactive. Therefore, if you have any data in our application which you want to react to changes, it must be there upon creation rather than added afterwards. We don't need this code for the project so I'm going to remove the button and also the capacity change method. Let's go ahead and do that now. In the index we should move the button and then in the methods in app.js, we can remove the method of capacity changed. As we go through the course, we'll look at more of these Vue instance properties and methods in more detail. Starting in the next video, we will take a look at using refs.
32. Referencing elements with ref: In the last video, we looked at some properties and methods which are available to us in the Vue instance. One of these properties which can see is called refs. We can use refs register a reference to an element. We can place a ref on any element we want. I'm going to go over to the index to HTML page. If we look for the page title, I'm going to begin by removing a double curly braces. Then simply replacing this with guest list. Then in h1 opening tag, I'm going to add a ref attribute. Answer is to a name. This is not a standard HTML attribute, it's provided to us by Vue.js. We also free to choose any ref name which will like. Now have this reference to the elements. We can work with it in our Vue instance. I'm going to add a click handler to this level on heading, which you can hook up to this reference. I'd add click. I'm going to set this to be a method name of change title. All this element is not important, we can still retrigger this method when it's clicked. Then let's add our method in app.js. We need to add this in vm2. Let's add our methods and we use a name or change title. We then select the ref with this title assign refs. Then from before the all of the native view properties have the dollar sign prefix. Then we add the name. Then dot in a text which is just JavaScript. This is not something provided by Vue.js. Hopefully you can now begin to see the Vue.js and normal vanilla JavaScript works together almost seamlessly. We can mix in JavaScript with Vue properties and methods where we need to. Now if we save that and we go over to the browser, if we click the title, we should see the title is now being changed. Along with using dollar sign refs to set data, we can also access data using it. If we add a console log to show this dot dollar sign refs, we can see what it returned. Inside the change title method at a console log and this dollar sign refs. Then go over to the browser. We can see that an object is returned. We can also see that it's a h1 we have selected. If we open up this objects, we have access to all the associated data within it. We can see the inner HTML which you've reset and also all the other properties which we can access. For example, if we look at hidden, we see there is set to false by default. We can use dollar sign refs accesses and change it inside of our method. Inside the changeTitle method, we can select this dot refs, dot name. Inside the method we can remove the inner text and replace this with dot hidden. That we can set this to be true. Now if we save this and go back to our app, if we click on the title. Hidden is set to true, so the elements disappears. This is how we can use the dollar sign refs property to reference and elements and the set or access data. It's worth mentioning too that we can use this refs property both inside and outside of the view instance tool. There is something to be aware of though when using refs, that is refs and not reactive. They're not created on the initial render. They are created as a result of the render function. We are changing the element in the DOM, but not in the Vue.js template. Therefore, we changing something which may be overridden by Vue.js at a later day whenever there is a re-render, such as something to be careful of. However, using refs can be useful at times and maybe best used to get data rather than set data because of the lack of reactivity.
33. Using string templates: During this project, we have created our view instances and then mounted them to HTML elements by using the L property. There is also an alternative way which is create a string template inside of the view instance. Let's go ahead and create a new view instance to store the title of our app inside. Inside here we can use the template property, so I'm going to go down to the bottom and create a new variable, this time called vm3. Then this is going to contain our new view instance, and as always, it takes in our options object. Inside here, we're going to add a new template property. This property will take in a string, so we need to surround the mark up we provide inside the quotations. We're going to create the title here. Just like our existing title, we're going to open up the h1 tags and then other title of Guest List, and then closes off. Now, if we go back over to the index page, we could remove the title from our HTML, in order to come for our new view instance. Now, if we save that, if we refresh the browser, we can see the title is now removed from page. This is because we've created a new view instance, but we have no L property, so the template is currently unmounted. We can manually mount the instance using $ sign mounts. This is a new instance method which we have not yet looked at, because we have our template is stored inside a variable called a vm3. If we go back over to the app.js, we can mount it like this. Let's type vm3.$mount, and then inside the bracket we can add the elements that we want to mount to. I'm going to use the div with the ID of navigation. As a string going to pass in the # and then navigation, this mounts our templates to the navigation div, which we already have in our HTML. Let's save that and see what effect this has. If we go back over to the browser and then refresh, we now have the h1 title back, which you setup inside of the template, but you can see we've lost the navigation links and also the styling. Let's open up the developer tools by right-clicking and going to inspect, let's take a look at what's going on. We have our container at the top, which is fine, then immediately after that is our h1 title, followed by the div with the ID of app. You can see there's no Bootstrap rows or any of the Bootstrap 12-column grid divs, which you have inside of our HTML. Also, our unordered list for the navigation links is not there either, so why is that? Well, the reason is because when we mount a template to an element, this template will replace any existing markup. This means all of our nav links and Bootstrap classes, it will simply use the contents of our template as a new markup. We can add these extra divs and classes inside of the template string. If we go back over to our templates inside of the app, and then inside of the string, we can begin to add our Bootstrap classes surrounding the level 1 heading. Before this, we can add a div with a class of col-sm-12, and we can also add text-center to align this in the middle of the page. After the level 1 heading, we want to close off this div and then save that. If we go back over to the browser, we can see that this is re-introduced the Bootstrap styling, which we had before. But as you can see, things will soon begin to look quite messy inside of the template. Also, there is another limitation. We can not split this up into multiple lines to make it even more readable. If we move the level 1 heading onto its own line and then just after day we'll add the closing div also onto its own line. Save that and go back over to the browser. We can see that this doesn't work. There is a way around this, if we go over to the templates, we can place each line into its own string. Add the quotation at the beginning and the end of each line, and then we can add these together with the plus symbol. Save that and refresh, so we can see it's all in our working again. This solution still looks a little messy though, so we can be the best to own uses with simple code. Also, since view JS provides us with this L property to integrate our template syntax inside of the HTML. This is often seen as a better alternative. I'm going to go back over to our app.view and then once you remove this new instance of vm3, just to return the project back to how it was. Remove this vm3 variable, remove the mount, and finally, if we go back over to the index page, we can reintroduce the Guest List title back into the HTML. Save that and now our app is back to how it was before using the L property. That's how to create a screen template. It is important to know this as you may come across it in applications and also when going through the documentation, you may also see when working with components. Next we'll finish this section off by looking at the view instance lifecycle.
34. The Vue lifecycle: We should now have a better understanding of how Vue.js creates a template and manage it to the DOM. When creating Vue instances though, there is something important going on behind the scenes, which we have not yet looked at and this is a Vue instance lifecycle. We can hook into various stages of the lifecycle, such as before the instance is created or before there is an update, for example and we can tell Vue what code to run on each one of these specific points in the lifecycle. There are a number of these lifecycle hooks which we can use, so let's take a look at them now. We should now be familiar with creating a new Vue instance using new Vue, which we can see is at the top of this drawing. This is the lifecycle starting point before observing data and initializing any events. The stage should also make sense now because we know from previous videos that upon creation of the Vue instance, Vue.js is aware of the data inside of it and creates the watcher effect. Between these first two stages, we can call the first of our life cycle hooks, which is called beforeCreate. beforeCreate, as the name implies, is a method which we can use to define any code we want to run before any of our data is observed or any methods have been initialized. If we want to run the code after the data and methods are initialized, we then need to use the created hook. This means our instance is being created, all data's being setup such as watchers, computed properties, and any methods, although it has yet to be mounted to the DOM at this stage. The next lifecycle stage is related to templates. We've used both the template property and also created templates within our HTML code in this section, this is where Vue.js will look for these options and then compile these templates when required. After the templates have been compiled by using the template property or by looking up the templates in HTML with the el property, our next lifecycle hook is run. This hook is called beforeMount. beforeMount is called just before the mounting of the instance begins, and just before the render function will be called for the first time. Next up is replace el with template, now Vue.js has our templates ready. It has all HTML prepared which can be read by the browser. The curly braces or the interpolation we see in the editor will be replaced with the correspondent data values. This is why we can't see the double curly braces when we take a look inside the developer tools. This means the elements which we specify using el will be replaced with our compiled template. Now everything is in place to mount our template to the DOM. We're not done though once our instance mounting stage is been reached. We've discussed reactivity during this course and how Vue watches for changes and then reacts to these changes by obtaining the DOM. This is the effect we can see over on the far left, which is the virtual DOM re-render and patch. This is an ongoing cycle and the virtual DOM re-render and patch is triggered when some reactive or so much data is changed. Next, we have beforeUpdate. This cycle of updating provides us with two new life cycle hooks. First is beforeUpdate, and this as it sounds, is called before any data changes. Second of all, there is the updated hook. This is where we can add any code we want to run when there has been a data change detected, which causes the virtual DOM to be re-rendered. Vue.js recommends avoiding this hook in most cases, as we are provided with the computer property and also watchers which should be referred wherever possible. Next up there is the beforeDestroy hook. This is called right before a Vue instance is destroyed. At the moment it is called, the incidence is still fully functional, nothing has begun yet for the destroy phase. Then Vue prepares the instance to be destroyed by removing all watches, event listeners, and also any child components. We've not covered components yet, but we'll do soon. Finally, we have destroyed, so this is all the stages of the Vue instance lifecycle and in the instance being destroyed. When this happens, the final destroyed hook is called. There is nothing magic going on behind the scenes, just a series of stages of the Vue instance, which you can now see that we can tap into using these hooks. There are actually two more hooks called activated and deactivated. These are not typically available in this regular instance, but rather made available when using a kept-alive component. We will cover kept-alive components in the component section later, but for now, let's move to the last video. In this section, we will put into practice these life cycle hooks to see them in action.
35. Vue lifecycle hooks in action: Now, we know how the Vue life-cycle works and how we can tap into each of these life-cycle phases using Hooke's provided to us by Vue js. These hooks are pretty straightforward to add to our app. I'm now going to show you a basic example of these in action. All we're going to do is create each of these hooks we looked at in the last video and then simply do a console log once each one of these hooks is called. This is useful as we can see, the order in which they're logged to the console. During the instance life-cycle, these hooks are added to the root of the view instance rather than inside any of the methods or data properties. Let's go over to our app.js. Then if we scroll down to the bottom of vm1 and then add a comma just after filters, here, we can add our first hook, which is going to be beforeCreates. The syntax is pretty similar to the methods. This is a function. Then inside the function body, we can ask our console log. I'm just going to simply console log the text of beforeCreates. Although this is a simple example with a console log, inside this function body, we can add any code that we want to run before the instance has been created. I'm going to add a comma at the end and then just copy this before I create hook. Then I'm going to paste this in seven more times so you can see all of the eight hooks in action, so 1, 2, 3, 4, 5, 6, 7. Now, I'm going to remove the comma from the last one. The second one is the creative hook. Then change the text to created inside the console log. We then have beforeMount. Then of course, next job is mounted, so change the name to the mounted hook and then add the text inside the console log. Then we move on to the updated phases. First, we have beforeUpdate, followed by updated. Then finally, the last two is a destroyed phase, so the second to last is beforeDestroy. Then finally, the last hook is the destroyed phase. Save that. If we now go to the browser and then right-click and "Inspect" to open up the developer tools. Select the console and we can see that the first four hooks are called, we have beforeCreates, created, beforeMount and also mounted. This makes sense because the instance has been created and also mounted. But we have not caused any data changes to update or cause the instance yet to be destroyed. If we go up to the input field and type something inside of there, we can see now we have the before updates and updates fired for each keystroke we make. We have this behavior because we have the data property of new name text setup inside our data objects. Also, we added this to the input field with two-way data binding using V model. Remember too that any data property setup, chose in the creation of the view instance is then watched by Vue js and updates trigger a re-render. This only leaves a beforeDestroy and destroyed life-cycle hooks to be triggered. If you remember from the using string templates video, we used the Vue instance method provided tools called $Mounts to mount the template to the selected div in the place of the el property. Vue js also provides us with another instance method called $Destroy. This as it sounds, destroys a Vue instance and does all of the clean-up work, such as removing all event listeners and on binding all the directives which we setup. If we go back to the index page and locate the form, we already have an event handler on submit. We can easily use it to call the destroy method, so if we just add $Destroy inside of there. Now, if we refresh the browser and then type in some text to trigger an update. Then finally, press the button that's called the "Destroy Method," we can now see all of the life-cycle hooks are now triggered inside the console. Now, our vm1 instance has been destroyed. Vue is no longer in control of our sign up section. We can see this by trying to add a new name to our guest list. You will know it's inside the console as we type, no updates are triggered. Our Vue instance has been disconnected and now has no control over the outputs. The HTML is still in place. It just will not be updated anymore. Let's finish off by going back over to the index page and back to the submit method. We can remove the destroy method and then reinstate the app to work in order by adding our form submitted method. This is how the Vue js life-cycle works in practice and how we can hook into each stage. Obviously, each life-cycle hook can be used to perform more complex tasks than a simple console log. But I just wanted to show you what stage each hook is called and also show them in action.
36. Section Outro: A Deeper Look At Vue: I hope you've enjoyed this section and building your first project. By now, we should be getting a lot more familiar with how Vue.js works and what it can do. If you still feel a little overwhelmed, don't worry. This is completely normal and you'll get lots more practice of what you've learned so far. We are now going to move on to a new section where not only will we begin a new project, but we'll also look at how we can use build tools and how they can improve our project setup along with our workflow. I'll see you there.
37. Section intro: Build tools & Workflow: This section is focused and how we can use build tools to improve our projects. Also, how we can improve our workflow, making it more suitable for mobility larger scale applications. We're going to use these new build tools to setup our next project, which is called Creative Cards. In this project, we'll build a greeting card application where the user can create their own custom greeting card with their own custom texts and images. Hope you're looking forward to getting underway with the new project. Let's begin by installing both Node and NPM.
38. Installing Node & NPM: During this section, we'll be setting up our next up in a slightly different way to last time. We'll be using a tool called the View CLI. We'll look at the view CLI and what it can do for us in the next video. But for now we need to install Node JS and NPM, which we both required for the view CLIT to run. I'm going to go over to my web browser. Then I'm going to go over to nodejs.org, and it will take you to the node J-s homepage. Node JS basically allows us to use JavaScript on the server rather than only inside of the browser where it has been historically used. It can be used to create a web server photos, but instead will blend in the view CLI handles this photos. Node JS download also includes NPM. NPM is a Node package manager. We'll go over to npmjs.org. This is the website for the NPM package manager. This allows us to have access to thousands of JavaScript packages of code which we can add to our project. Among the what's due in this project will be using packages such as web pack and bubble, which we'll look at in more detail soon. Also we using Firebase for our photo storage, which has an NPM package to install. Even view itself is installed as a package. First let's go back over to Node JS, I'll begin the installation. I'm going to go over to the Downloads, and then if you choose a download for your particular system, if you're not sure which one to go for, the homepage will usually automatically detect which system you're using, so we should have the correct download available. I'm going to install the latest version. I'm going to click on Currents. It gives a few seconds to download. Once that's done and just open up and install in the usual way. I'm using a Mac but it might be slightly different on Windows. But you shouldn't have any problems. I'm just going to continue through and agree the licensing and then hit Install. Just give them a moment to finish off the installation. Then we'll have Node and NPM installed on our machine. Lets check this has been successfully installed, I'm going to head over to the terminal. I'm using a Mac for this course but if you're using a Windows machine, you will also have access to a command line program, such as the Windows PowerShell. Head over to that if you're using a Windows machine. All the commands which we use in this course should be applicable to both. Lets make that a little bit bigger, and when we check we have Node and NPM installed, with some simple commands. First I'm going to type in Node and then -v. If you see the version number display just underneath, that means that Node a successfully installed, the same with NPM. NPM -v currently it's 5.0.3. If like me you have the version numbers displayed like this, you've successfully installed Node and NPM and you are now ready to move on to the next video, where we'll look at the view CLI and how to use it to setup our project.
39. Scaffolding projects with the vue-cli: In the last video we successfully installed node.js and the node package manager. In this video, we're going to use a tool called the Vue CLI to scaffold out our projects. CLI stands for command line interface and it allows us to create a new project with most of the common setup already taken care for us. JavaScript projects can get pretty complex when setting up all these build tools ourselves along with all the NPM packages we often see. Let's go over to Google and we are going to search for the Vue CLI and we need the first one which is the GitHub link for the Vue CLI. Select this and then we're taken to the official GitHub page. If we scroll down, first of all we can see the installation but we will go for that in just a moment. If we go down to the official templates, we can see the current available templates which include the most complex ones which is a fully featured webpack version which includes all the hot reloading and testing that we will commonly need for projects. There is a more simple version of this webpack 1 and we'll be using this for these project. If you prefer browserify over webpack, there is also a standard and a simple version for these two too. But I'm going to stick with webpack for the rest of this course. There is also a simple version which is just a single HTML file which is more like the guest list application that we created before. These templates save us a lot of time when creating new projects because otherwise we would have to install and configure everything we need manually. For the next project we'll be using the webpack simple template as we don't need the more complex webpack setup with the testing. To install this, let's go back over to the terminal and then we install the Vue CLI with the node package manager and this is done with NPM install and then dash G to install this package globally and then the name of the package is the Vue CLI and then hit ''Enter.'' If you're on a Mac and this does not work you may have to use the pseudo keyword before. This installs with the administrator privileges and you also need to add a password. Add pseudo NPM install dash G Vue CLI. Alternatively, if you want to change your privileges without using pseudo, I will also add a link at the end of this section. This will allow you to configure your machine as the administrator without needing to type in pseudo every time you install a new package. This installs the Vue CLI globally, so we can can use it for all our projects rather than it only being available for the project which we're currently creating. Once that's installed, the last thing I want to do is to navigate to the area where we want to create the project. I'm going to add mine to the desktop. To get back to the home directory, we type in CD. We use LS to display the contents of the current directory. We can see we have the desktop available, so to change into this we can use CD again, followed by desktop. Then we can see we're now inside the desktop. Now, when we setup the project it will be installed in this location. Now let's initialize the project inside the terminal. To set up a new Vue CLI project, we use Vue in it followed by the name of the template we want to use. I'm going to be using webpack simple. Then we give the project a name, so this name of this project is going to be creative cards. Once that's done hit ''Enter." Then once that's installed and once the template is downloaded, we'll then have to answer some simple set of questions. The first one is the name of the project. It's currently set to creative cards which we've already typed. So if we want this we could just hit ''Enter.'' We can also add a project description but I'm just going to enter on for this. Add the name of the author, so I add my name in there. Use SASS? I'm not going to use any SASS for these projects, so I'm going to hit ''Enter.'' As you can see it's already set to no. Now it gives us a list of the steps we need to take just to finish this off. First of all, we need to CD to change the directory into the creative cards project which we just setup. I will hit ''Enter.'' Once you've done that the next step is to run NPM install and this downloads all of the NPM packages which are required. All these packages are listed inside of a file called the package.json and we will explore the contents of this file soon. This may take a little bit of time depending on how many NPM modules you have. The final step is NPM run dev and this is to run the development server inside of the browser. I'm not going to run this just yet because I'm going to run this inside of Visual Studio code. Let's just close these Windows down and we should now see that our creative cards project is now on the desktop. I'm going to open this up inside a Visual Studio, so let's open that and then drag over the creative cards projects into that. Then now if we go over to view and then go down to the integrated terminal, we can then start our development server. NPM run dev and then hit ''Enter.'' Then hopefully this should open up in the browser and should take a moment to open up. If you see this then we're good to go. Our development server is now setup. Over in the terminal we can see where the project is running, so we can see this is running at port 8080. You may need to copy this link and paste it in the browser if it doesn't open up automatically. A development server is not always required but it makes sense to use one as it allows us to create our app and testing conditions similar to a real server environment. It also has additional benefits such as live reloading. The browser will update changes without us needing to refresh the page. Now we have the project created and our web server up and running. Let's explore these files and folders which have been provided to us with the Vue CLI.
40. Exploring our project layout and build tools: In the last video, we successfully created our new creative cards projects using the Vue CLI. I've now got the project opened up in Visual Studio, and the development server up and running. Now I just want to take a few moments to look at the project structure, which we've actually created. If we look at the files and folders on the left-hand side, we can see that the first folder is the node modules. This folder is where all of the MPM modules are installed when we run the MPM install command in the last video. This is where things such as the View Call Library is located, and now we have that as a package, we don't need to use the CDN links, like we did in the first projects. Next, we have the source folder. The source folder will be where we do most of our work. This is where we'll be adding most of our code for the projects. This contains all our projects source files, and these are all stored on the server rather than being available for the public to see. Next, we have the dot babelrc file. This is the configuration file for a tool which we've installed called babel. As we go through the course, we'll take advantage of some of the new JavaScript features from the latest version of JavaScript, which is called ES6 or ES2015. Both ES6 and ES2015 are the same thing. ES6 is the version, ES2015 is the year of the release. The ES, which is in both, stands for ECMAScripts. ECMAScript is a standard or specification for scripting languages, whereas JavaScript is the actual scripting language, which is based on the standard. When we talk about ES6 or ES2015, we're talking about the same thing. However, the browser cannot understand this new code. This is where a babel comes in. It takes our code and compiles it to be converted back to ES5, which can then be read by the browser. We'll come back to this later on. Gitignore is for the git version control system. Here is where we can list any files or folders which you don't want to be tracked by git. Then we have our familiar index.html file. This works like in the last project, where we still have our main app container. We also have a script tag down at the bottom. In the first project, we only had one JavaScript file, which is our app.js file, which had all of our view js code inside. This project will work differently because we'll have many files, mainly because we'll be spitting up our call base into separate modules called components. We'll then use webpack, which is installed with the Vue CLI, where pack is a module bundler, which basically takes all of our code which you write, along with any dependencies such as babel, and then bundles it all together into one file. This bundle file, which we'll have at the bottom here, is isn't read by the browser. The output of his compiled file is the build.js file, which you can see here. You may also notice that there is no dist folder in the project tree. Dist folder is only created when we build for production, and we have not yet done this. We're just working with the development server for now. We also have the package.json file, which you may recognize if you've worked with node in the past. This file contains information about our app, and also includes any module dependencies which you may have. I'll just close this terminal down just so you can see some more. The Vue CLI is already populated, the name and the description, and also some information about these projects. This is the information which we provided during the installation process. The ASM scripts provided such as dev and built. We used dev before when running the development server, by using npm run dev, running npm rebuilt, will build our app production. It will also create the distribution folder for our bundle. This production build also minifies our core 2. Then we have a list of any dependencies, the projects, such as view js. We can also specify any dependencies which we only want to use for developments in the dev dependencies objects such as babel because we only want to use this during development to then convert our code ready for production. We'll then have a README file too with the instructions for running and building our app and then a webpack.config file, this as the name suggests is where we can configure webpack. I won't go into everything here in detail as webpack can be a course topic by itself but one of the main things is the entry and output file paths, which you can see just here. The entry point is our source file, which is main.js, which is inside of our source folder. Although we have many source files when creating components, they are all still rendered through this main.js file and we'll look at this in more detail soon. The output is our build.js file and this is the final file which is run inside of the browser with all of our compile code. Then we can add things such as loaders. As I mentioned before, we're using babel to convert any ES6 code into regular JavaScripts and here is the babel loader, which looks for any files with the.js extension. Often here we'll also see a list of what is called presets 2 but because we have the babel.rc file, we have all of our presets active in there instead. Presets are a bit like adding plugins. They're presets available to not only convert ES6 code, but also things such as jsx code and the react library. If we head over to our source folder and then click on main.js, this is a main file for webpack to use. This file imports both the view Library and also the main app file called App.vue. You can think of update App.vue as the main wrapper or the parent file to all of the components in which we create. This is why the webpack entry point is main.js, because it renders App.vue and then this App.vue file contains all the rest follow code in the application. You will also see the familiar el property, which is the ID inside the index page where we want to render our content to. If we explore App.vue, this is what is called a single file components. It has a.v extension and the contents are split into three sections. First of all, we have the template section. A template is the main content of the component. Here we can create our html markup that we'll want to use inside of the components. We can also mix in our view data with the double curly braces just like we've done previously. Below that, we then have our script section. So a lot this will look familiar from the last section. The script tags where we wants to include our vuejs dates properties, our methods, computed properties and all the rest which we've looked at so far and also any plain JavaScript too. We'll look at this in more detail during the projects. Further down, we have the third and final section of our component, which is the Style section. We can also add styles to this template. We have the options to make these styles applied to the whole of our App. I'll just contain them to this particular template. Split up our code like this into a single file templates is made possible by using a bill tools such as webpack, which bundles everything together for us into one bundled output file in the end. So this is an overview of the structure of our new app, which was set up using the Vue CLI. Now I know things may look a little complicated at the moment if this kind of setup is unfamiliar to you but we will be using this structure for the rest of the course. So by the end, you should be a lot more comfortable after a bit more practice.
41. Using the data object with single file templates: In the last video, began to look at the single file view templates. Now I want to take a look at the way scripts work, particularly using the data property which you've already used during this course. First, let's make sure our new app is running. If your server is to run, great, you can just head over to your browser, and see the app running like this. If you come back after a break and the serve is not running, we need to restart the development server. Go over to Visual Studio Code and then go to the integrated terminal. If using the standard terminal, is not using their one inside of Visual Studio or your text editor. You may need to use Cd to change into the current directory, and run mpm, run dev from there. Inside the terminal, my development server is still running. I'm launch closes term, we have control and then c, and then we're taken back to the project directory. To get to the front and again, we need to run mpm run dev, and then hit enter. Then once you get the browser reopening, if the server is running fine but doesn't open in the browser, you can open up by typing localhost : 8080 inside the browser there, and then it should run. The homepage you see is made up of the logo, the essential links, and also the ecosystem links. We can see these if you go over to the project and then open up the app.vue file. Always code should be contained inside of the template tags, which is the top section, so that we have the image link up the very top. We then have the ecosystem heading followed by the links which we've seen before. This is all just normal html, and you can even mix in view data just like we've previously done. In the script below, if we go to our view instance, we have the message data property, which says, welcome to your vue.js app. We can see if we go over to the browser, we don't have these displaying on the page. We can easily add this into our template. I'm going to add this just about the top, just by open up the double curly braces. Then we can add the message dates property into there, and save that. Then now if we go over to the browser, we can see it says welcome to your vue. Js app. You may have noticed that we didn't need to do a page refresh this time. This is the hot reloading, which is provided by web pack. If we go to the package.js on file, when we run the mpm run def. We can see that also runs the dash hot command, and this is where the hot reloading is coming from. Back over in the app. vue, if we only have a small app, we can create our whole application inside of this single template. We will be breaking this app into smaller components in the next section. To make things more self-contained and manageable, you'll know is the inside of our script tags, our view instance looks a little different from what we've used in the last projects. We can still include all the same methods, computed properties, and watches, for example. However, the data property works a little differently. The scripts and also even the style section is not required to run. We can even delete it and then refresh the browser. You can see that the absolute runs, but without the message data displaying, of course. Let's add it back in and we can take a look at the differences. First of all, we need to create our script tags. The first thing we need to do is to do an export, default, and then surroundings in the code raises. This is part of the ES6 module system. Exporting the module basically means it will now be available to use as an import, inside of files. We can see this import inside of the main js. The app.vue file is imported by specifying a file path, and also given the file name, in this case of app. We will export all the modules or components during this project and import them where required, so you get lots of practice of doing this. Let's go back over to the app.vue. Now if we try to add our message property back in, if we try to add our data, just like we did in the last video, by creating our data objects, and then set the message equal to a string, I'll just add welcome to that. If we save this and go over to the browser, let's take a look. We don't have the message property of welcome displayed on the screen. Let's open up the developer tools and then go into the console. We have some errors. First we see that the data option needs to be a function. Then this also causes the second warning telling us that the message property is not defined. To fix this, we need to include the data property as a function which then returns some data. To do this, return the data property into a function just like this. Then just inside of that, we need to return some data. Open up the double curly braces and then inside this return statement, we can add our data property, just like that. Now if we save this and go over to the browser, we now lose the error messages, which is great, and we now have the welcome message displayed. There is a good reason why we need to return the data inside of a function, when using components. This is because components are meant to be reusable. If you have more than one component sharing the exact same data property, all components will I need to share the same value of the data, they will also all be updated together, when there is a change. Adding data as a function allows all components to keep their own internal states. Using our example, we could have multiple components which all need a message property, but using a function, the message can now be different for each component. This allows components to share a common template which still keep track of its own data or internal states if required.
42. Section outro: Build tools & Workflow: This is the end of a pretty sure, but nonetheless, important section. We now have new project setup, which is more scalable and allows us to work with new features such as components. These component structure will be the topic of our next section, so I look forward to seeing you there.
43. Section intro: Introduction to Components: As our apps grow larger and more complex, a setup like our guest list app may not be ideal. Our single app dot view file can quickly grow and become bloated, making it difficult to maintain and test. Using a setup like we have now, using Webpack, we can now break up our code into smaller modules or components. This makes our file smaller, easier to maintain and test, and also allows us to reuse components more than once. We have a lot to cover in this section, so let's jump straight in to learning components.
44. What are components?: One of the great features of vue.Js is the ability to use components. You can think of a component like a building block for our application. We use them to break up our code into smaller, more maintainable pieces. A component can also be reused multiple times, from your application to avoid code repetition. Keeping sections of code into self-contained components also helps with debugging and keeping our code more organized and maintainable. Let's take a look at how components can be applied to our project. This is our finished card application. We can see there is some areas which are repeated. We have the text input fields on the left side, and all three are exactly the same. The same applies on a card itself where the text is displayed. This is an ideal use case for using components. We already know from exploring the files in our app that there is a main wrapper called the app.vue file. We know that we can use this wrapper to contain the rest of our application, which can all be nested inside. Within this app.vue wrapper, we can begin creating more components, such as a header. This header will be placed inside its own single file template, like the app.vue file. When naming component files, it's best to be as descriptive as possible. This helps on building larger scale apps with many components. We can clearly see where the components will fit in. In this project I've called this file the header.vue. Also I have placed the footer into a footer.vue file. Both the header and footer files are called from within the main wrapper. In the case of this app, it is not essential to have the header and footer in separate components. We could have hand-coded it inside of our app.vue template, as we'll only use them once. However, it gives us more practice at creating components. Still inside the main app.vue , we have the main body section controlled by a wrapper component. For each side of the card we have the card front. Card inside left, card inside right, and the card back. We switch between these components using the navigation links, inside of the header. These components will act as a parent container for all of the child components within them, such as a text and image components. As a parent component, this will be used to pass data between components which we will cover soon. This now leaves us with the reusable components. On the left is area for editing the card, and this particular section, the front of the card has free text input areas, inside of a file called text-input.vue. The nature of components means we only have to create this component once and then we can add this as many times as we like. Text inputted into these text areas, is then displayed inside of the text output areas on the right-hand side. Remember how we talked about when using data properties in components, that the data property must be a function. Well, this is where the importance of this comes in. If we never had data as a function, like we did in the first project, when any of the text inputs were edited. All three of these texts outputs on the right will be updated with the same text. Of course, this would not work well throughout because we want the free text areas to be independent. They can share the same template visually, but we want the data to not be shared with others. Having data-sets work as of function, allows a components to maintain their own state, so they can work independently. We also do the same for the images too, there are two components. One for the image upload area then one on the right to display the image. Moving on to the back of the card which simply has the same two image components because they are now reusable. Then just the copyright text below. This is how components work and how we can reuse them multiple times. Splitting up our application like this is made possible with tools such as webpack, which bundles all these modules, the files, and all their dependencies together into a single bill file for production. Hopefully you can now see the benefits of using components. Now let's move on to putting them into practice.
45. Registering global components: Now we have a better understanding of what components are and how we're going to break up our application into these components. Let's get to work on actually creating them. If your project is not already running, you will need to go down to the terminal and run npm, run dev and they should open up the development server in the browser. We see in this page and everything is working fine. To begin, let's clean up the sample code from over in the app.vue file. Head over to app.vue. The first thing we want to do is remove all the code from between the template tags. So everything from the div with the id of app, all the way down, up to the closing template tag. So remove that. The same for the script contents and also for the styles, well other own styles and script in when we need them. This is our empty single file template. Then I'm going to add some simple HTML structure for the app. Remember this app.vue file will end up being the main wrapper for our app. So make sense to add our bootstrap containers and rows inside here. Templates also need to have one main outer elements, so all bootstrap container will cover this. For example, this will not work, if we add some HTML such as an image tag and then a second elements such as API tag. If we save this and then go over to the browser, we see we've got a blank screen. If we go into the developer tools and then open up the console, we see we get a message saying components template should contain exactly one root element. To fix this, we can use a div, for example, as a root element to surround our code. Let's add a div inside here and paste the closing tag down at the bottom and then "Save" and now when we refresh, we see the error messages have gone and now we have our hello message. Let's continue to add our bootstrap rows. We can remove the texts and also the image tag and then carry on by creating a class, a bootstrap class of container. Then here we can create our row. So bootstrap class of row which will surround all the content that we're going to add inside. Finally, a third and final div for the section, which is going to have a class of col-sm-12. Would you make the app vue full 12 columns wide. For this to work, we need to grab the bootstrap for CDN link. If we go over to the browser, then once you Google and then do search for bootstrap for CDN and then scroll on down. We can see under the download title we have the jump to bootstrap CDN section. We don't need the JavaScript just now, so I'm just going to copy the CSS link, which is the top line. Copy that and then we can add this in our index page just underneath the title. So give that a "Save" and then we can take a look at using global components. This is the first component type I'm going to show you and this means the component is not restricted to be used only in a particular instance or components. We can basically have access to anywhere where we need it. If we go over to the main.js file, we can begin to work on our first component just above the vue instance. Make sure the component is above this as we need to register it before the vue instance is instantiated, for it to work correctly. We register this global component by calling vue.components inside here, we then give the components a tag name inside of a string. This is a name which used to refer to the components. I'm going to call this the text input. The name formats of lowercase separated by hyphens is considered good practice, although not essential, then separated by a comma and within curly braces, we pass in the options, just like a normal vue instance. We're going to begin by creating a template and this template within a string is going to contain a single text area. Let's out our HTML inside here. The text area opening and closing tag. For this to work correctly, we need to make sure craft the vue JS library imported correctly, which we already do at the top of the page with the import view from view. If we import module from the node modules folder just over here, we can just refer to it by the module name, such as vue. If were import anything else which is not in the node modules folder, we need to specify the file path for the file, like you can see with the up import on line two and then save that. Then all the in the index.html file, we can now add the component to our main app div, just like a HTML elements. To locate our div with the id of app and then inside here, I'm going to add it just like a normal element, so text, inputs, opening tag and then our closing tag. Note this element name must march the components tag name, which will only before inside of the vue components. These are reusable components and we can add them as many times as we like, so if we were to copy and paste this in a few more times, we should be able to see three components. If we save that and then move over to the browser, we should see three text area components but we just see a blank screen. This is because of main.js. Our vue instance is overriding the content by rendering the contents of our app.vue file. This behavior is normally what we want but for this example, I'm going to comment out the render function so we can see our components. So there's comments out the section and then now if we refresh, we see our three text areas appear on the screen. Also because they are registered globally, we can add them into the vue templates inside of our app. In the same way with our HTML elements, our options object inside of the vue component, is not just limited to adding a string template like we're currently using, we can in fact use other options which we have available to us in the vue instance, such as adding data and methods. We know from the last section using the data property in components, is a little different. We need to add it as a function. Let's add some data to change the placeholder text of the text area. First of all, let's bind the placeholder, to a date property or text value. Then at a [inaudible] onto the end of our templates to add our data property. This is a function as we know, which then takes in a object and then we return an object containing our data. Let's create our text value, date property and set this to a string, just simply of type here. Save that and now we should see the value of type here inside of the three text areas. Also, we can add methods to changes placeholder text when we click on it. So just underneath the data section, add a comma and then we can add our methods. Methods added just the same as we already know. I'm going to add a method called change text and then all I want this method to do is to select this.text value, which is this data that we set here and we're just going to set it to a new string of texts changed. To trigger this method, we need to add a click listener onto the text area, so any opening tag, we can add the shorthand of at click and then use it to trigger the function of change text. Let's save that. If we check this out in the browser, you'll notice the three components will act independently, so if we click on the first one, we see the text changed. For the text inside the second and third component is just as it was before. This is how we can add components to our app globally and now we can move on to the next video and take a look at registering components locally.
46. Registering local components: In the last video, we learned how to create a component which you want to make available globally across the whole of our app. Now, we're going to look at how we can register a local component, which is only available in the scope of instances or components. First, I'm going to remove the global component from the last video. So if you go over to the main.js and this component we registered, I'm going to remove this full section and we can also remove the free tax input components from inside the index.html. So remove all three of the text input elements and then save that. I'm going to replace this global component with two separate simple components, which will just display some text of component 1 and also component 2. Back in the main.js, local components are created differently to global components. We still need to create our options object but this time, we need to store it inside of a variable just like this. Let's add our variable called component1 and set this to an object, and then then once I add a simple template, which is going to be some p tags to output some text of component1 and then close the p tag off and then I'm going to do the same with a second component. Again, this needs to be a variable as we call component2 with eight templates and this string is also going to be p tags with the text of component2 just like that. Down at the bottom, we can still leave the render function commented Alpha now, as we're not working with the App.vue file just yet. Over in the index.html, then in-between the app we can add our component1, the closing tag, and then we can also do the same for our component2. Let's copy this and add this below. Change that to be the second components and then save. Now, if we go over to the browser and then refresh, we see there is a problem. Let's open up the console and see what's going on. On the console tab, and we see two red warning messages, which has a message of unknown custom elements for component1 and also component2. It gives us a hint into what we've done wrong. It says, "did you register the component correctly?" This is because as the local components, we need to register them where we want them to be available. Let's go to the view instance in the main.js file and then register the components which you want to use. Let's do this just below the L property. We can add our components option and this is an object. So we can start with the string name of component1. This is the name we give to the component and then separated by the colon. We are the real name of the components. So it's component1. If we go over to the browser and then refresh, we still see the error messages. This is because we've given this name component-1 an alias with a hyphen in between. So let's add this hyphen for the first components and now we should see the first component is displayed on the screen. The warning is over and the console now only show that component2 is unknown. Now, let's do the same component2. In the main.js, we can add a comma and then add our name and this is going to be component2 and this can be any name that we want to use. The second one was match the real name of the component though, which is it's variable name that we gave to it. Component2 will add the hyphen inside the index page and then now we should give a refresh and we see both components on the screen. So this is how to use components locally and how to make them available in a particular scope. Next, we're going to begin to build our app with single file components. These are the components contained in their own file, like the App.vue and we'll take a look at these next.
47. Creating single file components: In the last few videos we've looked are registering components both globally and locally. Here we're going to look at a different way to use components by creating them in their own single file. In fact, to recreate in the full project this way. Single file components allows to have everything related to the components in one place. It's a great [inaudible] to create a component by using Vue.component. The App of Vue file is a single file component too. Just like this, we have a section to create our template in HTML. Makes with any view data such as a double curly braces, or an event. This template is also much easier to work with than using a single string template. Like we've looked at so far. We also have the script section above any Vue GIS related logic, such as data and methods, along with any Vanilla JavaScript that we may want to add. Then down at the bottom, we also have our styles. We can also specify if the styles are global, or if they only apply to this component. We have this flexibility, so before getting started, we can delete the component from the last video. Let's leave the component 1 and component 2. Then we couldn't remove the component section from the vue instance. We are going to be using the app.vue file as our main wrapper. That's own comments out the render function. Then finally in the index page, let's remove the elements of component 1 and 2. To begin, I want to add a components folder inside of the source folder. Select a new folder called components. Make sure this is just underneath the source folder. Inside of the components folder, I'm going to create a new file. This file is going to be called Header.vue. We can also create sub folders for our components, which is a good idea for large apps to keep things more organized. This header file will be a simple component. We will get used to building them inside of our app. Let's get started. If you open up the Header.vue file, we can add the basic structure. Just like in our app.vue file. Let's begin by creating the template. This needs the opening,and closing tag. Then we can add our script tags, and then finally down at the bottom, we can ask the style tags. Now inside the template section at the top, I'm going to begin by adding a menu for our app. If you remember from before that we need to have a surrounding div, or a surrounding elements for our templates. Then inside of here I'm going to add a level 1 heading, which're going to be the title of creative cards. We'll add a bootstrap class of text-center. Then under this heading, we can begin to create our ul order list, which will be our menu.or a surrounding elements for our templates. Then inside of here I'm going to add a level 1 heading, which're going to be the title of creative cards. We'll add a bootstrap class of text-center. Then under this heading, we can begin to create our ul order list, which will be our menu, or a surrounding elements for our templates. Then inside of here I'm going to add a level 1 heading, which're going to be the title of creative cards. We'll add a bootstrap class of text-center. Then under this heading, we can begin to create our ul order list, which will be our menu. [inaudible] Well can also have a Bootstrap class, and this one is going to be nav, then justify-content-center. Then assign ul order list items. List items have a Bootstrap class also of nav item. The first link I'm going to add is for the front of the card. Then display the [inaudible] going to copy this list item, and then paste in three more times. The second link is inside left. This is the inside left of our card. Then inside right, and then finally the fourth link is for the back of the card. This will work perfectly fine without any of the scripts, or any of the style sections added. No consent from these is required for the components to function. If we go over to the browser, and then refresh, we can still see that no header is visible. This is because we need to take a few steps first. We know that the app.vue file is a main wrapper. We need to tell this App file that we want to use the header components. Inside of the script tags of app.vue, we can begin by adding a impulse statement. What we want to do is import the header, and this is the alias which we give to the component. This name is up to us. Then we want to import it from the file path, so we use./, and then go inside of the components folder. The file is called Header.vue. This is our header file imported. Then as we looked at in the local components video, we need to register the component so it's available to use inside of this template. Then we add our export defaults, which is going to contain all of our vue data. Then we can register our components just like we did in the local components video. We add navHeader, is the header.There are a few things to know here inside of the components property. The first name on the left is the tag name. This can be named anything you want, and it's how reference our components. The name on the right, most much the given name from the import statements just above. We can then add the components into our template using the tag name we gave all of navHeader. As we talked about early on in this section. Even though the name we gave to the component is CamelCase, it's best practice to add the element name as lowercase inside of the template. If we go up to our template,we can add our navHeader in lowercase separated by hyphens, and then close this off. Now we can test this in the browser. If your app is not running, make sure which run npm run dev in the terminal first. Then if we go over to the browser,we now see we have the main title of creative cards, and also the navigation links. The title is tied up against the top of the page. We could fix this with a little bit of simple CSS. If we go back to the header.vue file, and then go down to the style tags. All we need to do is add our style for the H1,and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.Now we can see it's pushed off the top just enough.This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top. We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos, and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top. We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.. This is our header file imported. Then as we looked at in the local components video, we need to register the component so it's available to use inside of this template. Then we add our export defaults, which is going to contain all of our vue data. Then we can register our components just like we did in the local components video. We add navHeader, is the header.There are a few things to know here inside of the components property. The first name on the left is the tag name. This can be named anything you want, and it's how reference our components. The name on the right, most much the given name from the import statements just above. We can then add the components into our template using the tag name we gave all of navHeader. As we talked about early on in this section. Even though the name we gave to the component is CamelCase, it's best practice to add the element name as lowercase inside of the template. If we go up to our template,we can add our navHeader in lowercase separated by hyphens, and then close this off. Now we can test this in the browser. If your app is not running, make sure which run npm run dev in the terminal first. Then if we go over to the browser,we now see we have the main title of creative cards, and also the navigation links. The title is tied up against the top of the page. We could fix this with a little bit of simple CSS. If we go back to the header.vue file, and then go down to the style tags. All we need to do is add our style for the H1, and just add a little bit of margin-top. We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos, and just add a little bit of margin-top.We'll add 10 pixels to there. Now we can see it's pushed off the top just enough. This is how we can use single-page components. The header is fairly simple. We'll add more to this in the next few videos.
48. Adding the card front component: Now we know how to create and display single file components. We can now move on and really get our project moving. I'm going to go over to our project and organize the components folder by adding a sub-folder called card. Then inside of this card folder, I'm going to create a new file called CardFront with the view extension. If you remember from the slides at the start of this section, we're going to have a single file component for each side of the card. It'll be the CardFront, CardBack, and both the inside, left and right. These components will act like rappers where you can drop in the text and image components wherever we want them. They're also the sections which will swap to change views when a menu link is clicked. But more on that in a few videos though. Just change the spelling there. If we go back over to the CardFront.vue, this is setup just like before with a template, so the opening and closing tags there, and then followed by the script tags and then finally the style tags. Inside of the template, remember we'll need a surrounding div. Let's add this inside there. You can also make this div a bootstrap row by adding the class of row inside there. Then we need to add some bootstrap columns, six on the left and also six on the right. We'll create the left section to begin with. We can add the bootstrap classes of col sm 6. This will be half the width of the page. We'll also add a bootstrap class of card, and then a custom CSS class of edits area. We'll use this in just a moment to style the sections. Copy this left div and then paste it just below, but still would inside this row. All we need to do is add our custom class this time of card display. Once you have that in place, we can go down to the style tags and then again, change these custom styles. Begin with the edits area, which is a left-hand side of the card. We're going to give this a background color, a custom color of d2f9f9, and then also some padding of 20 pixels. Then to give the card some height, we'll add the CSS high property of 800 pixels. That's the editory on the left. The right hand side is the card display section. Let's add some styles for this section. All we're going to do here is match the height of 800 pixels, and then also keep the padding consistent with 20 pixels there. As always, this component will not display just yet. For this to work, we need to register and also import it inside of the file which you want to use it in. All of our components who are the children of App.vue, so we register and import it inside of there, just like we did with the header. If you feel confident giving this a go, go ahead and pause the video and give this a go yourself. If you need a clue, just follow along with the same steps as we did to register the Header.vue file. Otherwise, don't worry, and follow along with me. Inside the app.vue, let's go ahead and add the import statements. This time, we need to import the CardFront. However, this is a name up to us, but I'm going to call it CardFront to keep it descriptive. CardFront from and then the file path is dot slash, goes to the components folder. Remember, this time, we have the cards folder inside of the components. Be sure to add that in there. The name of the file is CardFront. With that registered, we can now scroll down and then add this to our components section. I'm going to call it the cardFront. Remember, this name is also optional for the one on the right of CardFront must match the import statement above. The last thing to do is to add this file inside of our template, so just underneath the nav header. Let's add the card front components. This means that App.vue is a parent of both the header and also the card from components. This is all we need to do now to go over to the browser and hopefully see our component displayed. We have the edits area on the left-hand side with the blue backgrounds. We also have the card display section on the right-hand side. If you don't see this running, and you just have a blank page, you may have an error, so check inside the console. You also may need to restart the development server. If you need to do that, I'm going to press Control C to close it down and then run npm run dev, and then it should be back up and running. Finally, just to finish this section off, I have a few basic styles to apply to the app inside of the App.vue file. Head back over to App.vue and scroll down to the style section. The first thing we want to do is add some styles to the body. I'm going to change the font family to be Verdana Geneva, and then finally, a generic sans-serif as the fall back. Add a text color to be the value of 333. Then if we refresh, we should now see that the custom fonts have now taken effect. Then finally, I want to change these menu items into links. If we go over to the header, and then inside of the list item, we can just add our a-tags inside of there, with a bootstrap class of nav link, and then close off the a-tag. I'm just going to copy this, and paste it in front of the second, third, and fourth item. Do the same for the closing tag, paste those in and save, and then refresh. Then we can change the cursor to be a pointer as it hovers over. The final styles is for the a-tags. This is going to be the cursor, this is going to be the type of pointer, and then save that. Now, we see if we go over the nav links, we now have the pointer. Now that looks a little bit better. Hopefully, now you should be getting the hang of adding components. If not, don't worry, we still have plenty more to create for is app. We got a lot more practice as you go through the course. Next up, we'll take a look at how we can pass data from a child to a parent component.
49. Emit data to parent components: Now we're going to take a look at passing data between components, more specifically data from a child to a parent components. First, we need to understand the parent-child relationship with components. App.vue is the main wrapper, and all the content is contained within it. It's effectively at the top level. This means all the components we add inside here, such as the nav-header and the card-fronts. They're all child components of this app.vue file. Also soon in this project we'll create a text-input components, and when we do this inside of the card from file, we'll also add a component just like this. Once you've created it, we'll also add the text inputs just like we've done before. Our card from dot-vue components, is now apparent to this text inputs. A text input is the child components. We're now going to pass data from our header file to the app.vue. With this knowledge, we now know that this is passing data from the child to the parent components. We can do this with what we call custom events. If we go over to the header dot vue file, we want to pass to the parent file, which is app.vue which page from the menu has been selected. We want to do this, so app.vue knows which component to display, such as the front of the card or the back. The first thing we want to do is to create a data property to keep track of the selected page. Let's add our export default, and I want to create the data property which remember, this is a function when use swayed components. I'm going to return the data property name of page selected. To begin, this is going to be an empty string. Now we can set up a click listener on each of the links in the menu to change the value of page selected. Go back up to the templates and inside the links, go to add a new attributes of art click. When this is clicked, we're going to set page, select it to be equal to a string of card fronts. Once this is clicked, spade selected will no longer be an empty string. It will be replaced with this text value of card fronts, and then we need to do the same for the over free links. Copy the click listener and then paste in. This time, this is going to be card inside left. The third one is for the card inside right. Then the final one is going to be for the back of the card. The component we're going to be calling this is card back. So far we've only created the card front components, but we'll create the over soon. Also the names we add here, most much the component names we gave to them when we register them for this to work correctly, such as the card fronts which you've added in app.vue. Back over in the header, I'm going to now create a watcher. This is going to watch for any changes to the page selected data, i.e, when we select a new manually. Go back down to the script, and just underneath the data property, you can add a comma, and then create our watch section and then create our watch properties. So we want to watch the page selected data. When page selected is changed, it will then trigger a function. Inside of this function, we're going to emit a custom event to the parents. This is actually simpler than it sounds, we just need to use this dot dollar sign emit. Early in the course we looked at refs, and we access them using the native view property of dollar sign refs. Well, using dollar sign emit is also native to the view instance. It is a native instance method, meaning it's built into the view instance. Then we pass in two arguments. The first one is the name of the event, which is chosen bios, so I'm going to call it, page was changed, and separate it by comma. The second is what data we want to pass to the parents. We want to send the page name which was clicked, and we can access this with this dot page selected, which is the value of this data property. This is the first part of sending the data. The second is over in the parents, which is app.vue. Save that and head over to app.vue. If we go back to our template and look for the nav header section, which is a char component. Here we need to listen for the events which we've created inside of the components elements, so just like this, we can add a V on. Then we'll listen for the event which you gave a name of page was changed, or we can even use the shorthand, which was the at symbol. Now we're listening for events to be passed then we need to tell view what to do with this event. We obtain the selected page, select create new data property to store this event valuing when there is a change, scrolling down to the script just under the export default. I'm also going to add the data property inside of here, don't forget to add the comma. I'm going to create a new property of current page. I'm going to set this equal to card fronts. So far we only have the card front component graded. This is fine because it makes sense to have the front of the card displayed by default anyway. This now allows us to set current page to the value of the events just like this. So that the current page equal to the dollar sign event. Now each time the navigation link is clicked, this is then passed to the parent components with the events called page was changed. We then change the current page from the card front to the value of the events. We can test this is working okay by outputting the value of the current page with the double curly braces. Just after the nav header. I'm going to open up the double curly braces and output the value of current page, so save that. Now we can go over to the browser. First, we want to stop the development server with npm run dev. Now we see the value of card fronts, which is what we expect because this is a default value. If we select a different nav link, we now see that the value is changed each time we select a new menu item. If you see the value of page select the change, when you click on a menu link, this means you are now successfully emitting data from a child to parent components. If not, just check all the code until it gets to the stage, and then we're ready to move on to creating the rest of the card components. Also using dynamic components to switch between each view.
50. Dynamic components: In this application, we want to create components to display the different sides of our greeting card, such as the front and the back. We also want to switch between these components. When a user clicks on the menu links. Using Dynamic Components allows us to achieve this effect. We can switch between Multiple Components and place them in the same mounting points. All we need to do is to use the Reserve Component Elements. It can go in place of the Card Front Components. So if we go over to the app.vue, you will continue this current page output, so lets begin. Then if we delete the card front and replace it with components, make sure this is in the opening and closing tags. So now instead of rendering the card front, component elements will render whichever section we click on. So already keeping track of the selected page using the Column Page Data. Now we can use the ease attributes to dynamically bind the current page data to this new component elements. So inside of the opening tag, we can use the v-bind directive and then binds the attributes of is. Inside here we can add the data property of Current Page. Remember we can also use the shorthand syntax, which is just the colon. Now each time a page is clicked in the menu, the data is passed to the parents app.vue file components and listens to this amazing event, and then updates the current page data. The component elements then changes the component it displays. Based on this. We can see this in action in the browser. If we save that and then refresh. Now if we click on the front, this is fine because we do have the card front component available. However, if we select any of the other three sections, would you see a blank page. So this is fine this means that everything is working. The rest of these links will work from a create, the rest of the card components. We'll do this in the next video.
51. Creating the additional card components: We're making good progress with our knowledge of how components work. In this video, I want to create the additional card components. We already have the card from components, but we still need to create the CardInsideLeft, inside right, and also the CardBack files. If you feel confident doing this, feel free to go ahead and create these single file components by yourself. For now the content just needs to be the same as the CardFront.vue file. You can copy this over to get started with. Also, you will need to import these into the App.vue file, and then also register them as components. Make sure when we register the components, we name them the same as we have given them in the menu navigation or in the Header.vue file. Otherwise, they won't link to the correct page. To get started, I'm going to go over to the CardFront.vue file, select all, and then copy, and then if we go over to our menu, on the left, and then inside the card folder, I'm going to create a new file, and this one is going to be called CardInsideLeft, with the dot vue extension, and then paste it in the contents here, save that. We don't need to worry too much about the content for now, we'll build these up with child components as we need to, just so we can see which page was selected. I'm just going to add some text inside the first section just saying CardInsideLeft, and this is so we know which section we run when we click on the dynamic components. Now, we can import the components inside the App.vue and then register it. If you go down to the script, and then we can import the CardInsideLeft, and then we pull this from the components folder. Inside here, we have a card folder and the file name is CardInsideLeft, and then of course down in the component section, separated by a comma, we add the CardInsideLeft and set this to the same name that we've called it here, of CardInsideLeft. Remember we don't need to add these elements inside of the template, like we've done with the nav header. Because this component is going to switch between all these pages follows when we select them inside of the menu. Now, all we need to do is repeat the same process and create two more sections or two more single file components. I'm going to begin with the CardInsideRight component. Inside the card folder we'll create CardInsideRight, again with the dot vue extension. This can also have the same contents of the inside left, so let's select all, copy, and then paste it in the contents. Just so you can tell the difference, I'm going to change the text to inside right and then save that, and then finally we also have the CardBack, which we need to add. CardBack.vue, and then paste in the same contents and change the text to CardBack. Back over to the App.vue, and I'm just going to copy this import statement and then paste this in twice. The second one is inside right. Changing inside the name and also inside the file path, and then finally we have CardBack, and then down inside of the instance we can add inside the component section our new components. CardInsideRight, and then finally the CardBack components. That should be is now done. With the four card components now in place, we can make sure our dev server is running, and then go over to the browser. If everything is working correctly, we should now be able to click on each one of the menu links and see our new components displayed. We can see this is working with the texts that we added inside of each. Great, so now with that in place, we're making good progress with our application. Now, it's time to move on and begin creating the text input components.
52. Creating the text input component: We have our card sections completed now, and we can switch between the different views by clicking on the menu links. Now it's time to create the text input components. These components will be our first reusable components. So we can create them once and then use a multiple times in the app, as you can see here. The components itself is pretty simple. It basically consists of a text area inputs. It uses two-way data binding with V-model to update a data property when a user types. This data property is animated to the parent component's foolish to venues. When we get to the text, I'll put component. Everything we do for this component we already know and we've covered so far in this course. Let's begin by creating the components called text inputs.view. If you go over to the count section. We can add our new components inside here. So text input, with the.view extension. Then we need to add our usual templates. So add these at the top with the opening and closing tags. You can also add our script tags below, and we use these very soon. We don't need the style tags in this particular components. As the Bootstrap classes will take care of all styling photos. Our template you straightforward. All you need to do is add some Bootstrap divs for layout, a heading, and then a text area. So let's begin by creating our first div, which is going to have the class of row. Then inside this row, we going to add our 12-column grid. So add a nested div inside of there, and then we can add some further Bootstrap classes of coal, SM 12 to make it the full width of the page, and then inside here we can add our container for the text area. So let's add a Bootstrap div with the class of form group. This will just give you some nice style in. At the top of this component, we want to add a h for heading, and this is going to add the text of edit text. This is how we use, can clearly see that this is the edit area while the needs type in some text, and then we can add our text area. So I'm just going to remove the name and the ID replace this with a Bootstrap class of form control. So columns are going to make this a little bit bigger and make this 50 columns, and we only need four rows. I'm then going to add a placeholder, and the text we going to add is just, adds text here. Just to give the user some instructions. We then need a data property to store the text inputted from the user. So we can then emit it to the parent components this data, we'll use two-way data binding to be updated from this text area. Down in our script, we can create our objects. Export defaults, and let's create our data property in the usual way, and I'm going to return the data property of text box inputs. Initially I'm going to set this to an empty string. Since no text being added inside here yet. Now have these text box inputs as a data property. We can add it to our text area using the model to bind it. So just after the placeholder attribute we want to add this on a new line. So V model, and this is going to be text box input. So now we'll have the two-way data binding setup. We can now emit the value of this text area to the parents. This can be achieved by adding a method which is called On Each Keyboard Events. Still within this text area, I'm going to add an event listener to trigger a new method called Text Changed. Each time a key has been released. So then we add the @ symbol and then the events of key-up. So each time a key is being released, we can trigger an event called text changed. Then we can create our method below to trigger the custom emit events. So down inside the script, underneath the data objects add a comma, and then we can add our methods. This method of course needs to be the same in, what we have here of text changed, and then inside the function body we want to emit this data. So this.$ sign emits. Then remember from before, we need to pass in two arguments. The first one is a string value, and this is the name of our events. I'm going to call this display text changed. You can use a different name if you prefer. Well, I think this name describes what we do in fine, and then the second parameter is the value which you want to send. So this starts text box input, which we have here. So at the end as the second argument. So now we have the custom events called display text changed. We can add the component to the conference dot v file as a child components and listen for the event. But we'll go back over to the slides as we can see here. We use the same component three times. If we open up the card fronts, the view file, we can add these components inside of here. First, we need to import the components inside of the script. So just like we've done before, we can impulse the text input components and then add the file path which is dot slash. This one is just going to be text inputs. So this is because text input is in the same folder as card fronts. We don't need to go into the card or components folder because we're already there. Then we need to create our components, dates property. So export, default, then add our components. So I'm going to add a CC prefix, which stands for creative cards. This is to make sure the name is a little less generic, more tailored to our app. So CC text inputs, which is alias for text input. The CC may also avoid any naming conflicts with any view JS Plugins or libraries, which we could add to in the future. So let's save that and then move up to the template section. Then inside of the edit area, we're going to add our components. So CC text input. Then if you make sure your development server is up and running, save, and then go over and go to the front. We should now see that the text area component is now added to our app. We'll leave this video there and we'll come back and continue with these text inputs in the next video.
53. Receiving data from the text input: In the last video, we successfully created and registered our new text input components. Now we're going to continue by adding this component to the front of the card two more times. Let's go over to the card front door view and here where we created the CC text inputs, let's copy this and paste it in two more times. You should be seeing a bit of a pattern in my [inaudible] to display the components we add it like HTML elements. All we need to do is add this three times, and then you can see we how they displayed three times inside the front of the card. Now we have our three components, we also need to add the event listener which we added inside of the text input. We're currently emitting the event called Display Text Changed. From [inaudible] to this inside of the components using @ display text changed and then we also need to add this to our second and third components. Just copy and paste those over. Here we have three components added which all listen for the display text change event to be passed to it. We now need to add free data properties to store the text value received so that's one for each components. Let's go down to our script and we can add our data property. The first one we want to add is going to be a name of text-box value 1 which is going to be initially an empty string. Because you got three separate components, I'm also going to add the same for number 2 and 3. Text-box value 2, again set to be an empty string for now and then text-box value 3. With this now in place, we can now update them with the value of the events passed from the [inaudible] components. We'll do this just as we looked at previously inside of the event listener. We can begin by adding text-box value 1 into the first component and certainly is equal to the value of the event and then we do exactly the same for the second and third components. Text-box value 2 and then text-box 3. With this now in place, all we need to do is check if the data is being received from each of our components, is to simply output values using the text interpolation. Let's begin by outputting a text-box value 1 and then text-box value 2, then the same for value 3, save that. Make sure that the development server is up and running and then if we go over to the browser. Now if we start by adding some text into the first one, we can see that the text is displayed down at the bottom, that's our text area 2. Now we have text area 2 displayed also. Let's try the third one. Text area 3 is also appearing there too. We can now see that we've got three of the same components displayed on the screen. Now we'll reuse our component three times. However, the data is stored independently so each when we type in has their own corresponding data value. If you manage to get this all working, congratulations. You should be getting the hang of components now and you are now ready to move on to the next video. We'll begin to create the text output areas.
54. Creating the text output component: We now have the text input components created and also display into the screen too, now I'm going to create the text output file. This is going to be the component which displays the text onto the card. Again, just like the inputs, we'll be using three of these components to display the text onto the card. First, we can delete the textbox value fields from the card front file. Let's remove textBoxValue1, 2 and 3. We've already tested these and we know it's not working. As we did with the input components, let's create a new component file, this time called TextOutput. Go over to the card folder, create a new file called TextOutput, with the.veu extension. Now we can add our template. For now this template is going to be pretty simple, all I'm going to do is create a div as a wrapper, and then inside the div, just add some text, just of sample text so we can see the components on the screen. Just below the template, we can add our script tags too, and I'm just going to create a empty export default for now, followed by the style tags. Once you do that, we'll then need to import and register the component inside of the CardFront.vue. We're down to the script section and then I'm going to just copy these import statement, and then paste it below. But this time change it to TextOutput. The same for the file path. Down in the component section, add a coma. I'm looking at our ccTextOutput. Give that a safe. Now we have access to the component in this file. It's times now add it to the card display area inside of the template. Go over to the card display section, and then we can add ccTextOutput and, the closing tag. As mentioned, we are going to be displaying this three times. Eventually these output sections will display the text from these three text input sections. Save that, and then start up the servers with npm run dev. If you need to, then we can go over to the browser, and we see the component in action, but we will pass the text to user types to the component in the next video, we'll take our first look at using props.
55. Passing data with props: So this is how our structure looks so far. We have Text Input and Output components inside of a parent component called CardFront. Data can be passed between two sibling components. So we can't move the text from the Input to the Output components directly. Instead, we have to communicate through the parent component, which is Card Front. We already know how to pass data from a child to a parent component. We do this by emitting a custom event and we're already doing this in our app, so we have this part covered. Next, we need a way to do this all the way round. The parent component needs to pass this data back down to a child component. In our case, to the Text Output component. We can do this with props, which is short for properties. Props are custom attributes for passing data down to child components. If you come from a react.js background, it works in the same way. The first thing to do is to declare inside of the child component the props we expect to receive. So if we go over to the TextOutput.vue file, and then down to the Script. We can then add our Props inside here. The props option is an array of prop names, which we expect to be passed as a string. I've called this prop the Display Text to reflect the data which will pass down to it. We can go back up to our templates and remove the sample text. Then in the place of this we can add the name of the prop, which is Display Text. So once this data is passed down, this will be displayed inside of our template. We can now add this prop over in the parent component, which is CardFront.vue. So to begin, we add a custom attributes inside the Output component, which is the name of the prop. So I'm going to add, Display Text inside here. So this test is just going to add a string of, Hello. So now make sure the development server is running. Now if we go over, we should now see the value of the prop on the screen. So this value is being passed down to the child component of Text Output. We then tell vue.js which props we expect to receive, and then we can output them inside our templates. However, in this case, this only works because we've used a string. If we try to use dynamic data, such as our textBoxValue1. So we copy that and paste that in. We see that this won't work. We just get the string value rather than the dynamic data. If the data is dynamic, we need to use v-binds or the shorthand syntax. So just before Display Text, we can add the short syntax of the colon, now save that. Now if we go over to the browser, and we start typing text inside of the first text input box. We can see the changes are now reflected over in the right-hand side. We try this with the second one. We see nothing happens because we haven't added any props to the second or third component yet. So let's go over to the CardFront and we can do this now for the second and third components. So copy the props and add this in the second and third components. To make these unique we need to add to the date property or textBoxValue2 and textBoxValue3. So save that. Now we should have three independent components. So box1, box2, and finally box3. So these are all working independently with their own data. All three of these text areas work independently because they have a different data source. This is how we can use props to pass data down to child components. It's important that we understand the props form a one-way down binding, meaning that if the parent data updates. The data will automatically pass down to the child. However, it must not work the other way around. We should not change the value of the prop inside of the child component, we should treat them as read-only. If we need to change the value of a prop which is being passed down, we should not do it directly. If we want to use a prop and then change the value, we should first setup a data property inside of the child components. We should then assign the dates property as the initial value of the prop and then change your data rather than changing the prop value directly.
56. Keeping components alive: When using dynamic components and switching between them like we are here, there is a small problem created which we may need to address. If we type something into one of the text input boxes like this, we see the result on the right-hand side. The problem occurs when we switch the active component using the manual links. If we select a different components, such as Inside Left, then return back to the Front. We see the text we added is lost. Also late in the project when we add text and image inputs to all pages. The same thing will happen to all these components too. Why does this happen? Well, early in the course, we looked at the view lifecycle, which is the stages of view instance goes through from curation right through to being destroyed. When we change the dynamic components, component or move away from, is then destroyed and removed from memory. View jazz providers with a simple solution to this. All we need to do is to wrap our dynamic components with ANOVA reserved elements called keep life. If we go back over to our text editor and then go over to the app dot view, we have a component which is registering the current active page. Let's wrap this inside of the Keep-Alive wrapper to add the opening tag, and after the component, we can add the close tag too. I didn't save that. Now if we go over to the browser, we can start by adding some data inside the first text area, and a now if we move away and then go back over to the front, we'll see that the data is now being preserved. This is a really simple solution which view GS providers to keep dynamic component data inside of the memory.
57. Scoping CSS styles: Early in this section, we created all of the cards' components. We created the my copy card from file. This file already had some styling inside the style tags. If we go down to the bottom of Card Front, we can see in between style tags, we have the edit area and card display styles. Duplicating this file also added the same styles to all of the card files. For example, if you go to Card Back and scroll down to the style, we can see we have duplicate code. If we're to delete the styles out of this CardBack.vue file, let's save that and see what happens. We go to the browser and then if we go to the "Back", we can still see that the styling still applies because we have the background color, the padding, and also the height of 800 pixels applying. This is because any style in which we add inside the component file will still apply everywhere in our app. To reduce the code inside of our app, we can delete all the styles from the Card Back, which we've already done. The CardInsideLeft, so move these to styling sections. Then finally from the CardInsideRight. This now just leaves our styling inside of the original CardFront area. Leaving the styles only in the CardFront file because they will apply to all the rest. But what if we had a case where we want to contain the CSS to a single particular component? For this case, we can add "scoped" to the opening style tag just like this. Add the scoped attributes and save that. Now we go over to the browser. If you go to the Front, we can see that the styling applies inside the Card Front. Let's try InsideLeft, InsideRight, and also the Back. Now we can see that the styling is restricted to a single file component. I'm going to go back over to the Card Front and remove "scoped". This is because you want it to apply it to all of the other pages. However, we do have some uses for using scoped inside our app. For example, over in the TextOutput file, we can output the text inside of the HTML p tags. We can then style this text and have the styling only apply to the text displaying on the actual card, which is this area inside our templates. Let's go down to the style and add "scoped" inside here. This only applies to the TextOutput. Then I'm going to set a new font family to apply only to the card section. I'm going to go over to Google and select a Google Font. I'm going to search for Google Fonts Tangerine and then select that. This is the font that I'm going to use for this project. You can of course change it if you prefer. Once you've selected your font, click on the plus symbol at the top, and then we can expand. Here we're given some instructions on how to add the Google Fonts. The first thing you want to do is copy the link at the top. This is the link for the style sheets. Then go over to the index.html, and then we'll add this just below the bootstrap link. Paste that in there and give that a save and back over to Google Fonts. We can then copy the line of CSS. Copy this and then we can add this into our TextOutput file inside the CSS for the P elements and then paste in the code which you just copied. Save that, make sure the development server is up and running then go back over to the project. We'll start typing inside the input components. We can see that the text is applying, although it's really small for now but it is working, and we can see the fonts are applying. To fix this, I'm going to go back over to the file and add some more styling. I'm going to set the default font size to be 42 pixels. I'm also going to match the line height of 42 pixels. Just to give it a little bit of a better look, I'm going to add the text-shadow of two pixels, two pixels, two pixels for the three sides; and then the color of aaa. The color of the text, I'm going to add mine as 4d4d4d. Going to also add some margin, five pixels on the top and bottom, and zero on the left and right, just to give it a little bit of spacing. I'm also going to add a border and we'll see why soon. Just a one pixel dotted and a gray color. Then the white-space property of pre-line. Pre-line preserves the line breaks, which stops all the texts appearing on the same line. If the user hits "Enter" and starts typing in a text box on the line below, the same will apply on the output side so everything's not on the same line. Then finally we're going to overflow of hidden, just in case the user types in too much text which can't fit on the area. We save that and see how that looks. Now we see the text is a little bit bigger, and we also have some font shadows. I don't seem to see the dotted, I will change that to be dotted and there we go. You notice that we have some pretty, ugly-looking dotted lines. This is because without the text, the dotted line border has no height. We can ignore these for now because we'll pass down props to these components in the next video, which will set the height of the components. Then we'll have a nice dotted border around each section. The main thing is a text for the card is style now. These styles are scoped to apply only to these components.
58. Prop validation: When passing data to child components via props, sometimes you want to make sure we send in the correct type of data to be used. For example, if the child components expects a number to pass to it or instead receives a string, then this can cause problems. Using prop validation is a way to set the requirements for the prop to be received. If the validation fails and VGS will send out a console error during development. First we're going to go over to the card front v file and add a new prompt to pass down to the text output components probably used to set the height of the tax containers on the card. Latent cause we'll do the same with the image display. We can rearrange the heights of the components, to fit the card correctly. We need to and this probe inside of the CC text output components. I'm going to call this prop the container heights and set this to a value of 130. So this value of 130 will be used as a CSS property. Let's do the same for the second, third component, copy this and then paste it in twice. Then once this is done over in the text output.file, we can add the proper name to the array. We already have our props setup. We can separate them with a comma and also add our second prop, container height at props to the array, like this works fine. But we want to add some validations tele component. What type of data we expect to receive? To do this when it's sad props to be an object. We can set the dates type we want to receive inside of an array. Note more than one data type can be used, such as a string number, Boolean function, an object, or even an array. So let's add in our prop of display text. Let's add this back in. Add this is a type of string to the array. We can test this validation by passing a new motorway and see what happens. Over in the card front, instead of sending the text box value worn, going send a string value. Let's say 12. Now if you open up the console, we can see that there is an error. It says expected string book got a number. So that means validation is working. So now let's change this back to text box volume. This is how we can add basic data validation. There is also more things we can do, separated by a comma. Let's now add the second prop of container height. Because this will have more than one type of validation, we need to set this to be a object and then add this as a type of number. We can also declare if we want this prop to be required. This is a Boolean value which I'm going to set to true. This tells VGS this prop mostly presence otherwise will receive a console warning. We can test by removing any container high prop from the parents of cartoons, and then head over to the console. Inside here we get the warning message saying missing required prop of container height. Now let's add this back in and then save. So back over in our prompts in the text output. Also, we can add a default value if no value is passed. Obviously this would not make sense to be added with required, sludge replace required with default, and want to sell it to a value of 200, which of course is a number.So now if no prop is passed through a component, the default value of 200 will be used instead. Now we have this validated data being passed as validated prop. We use in the next video to set a container heights by adding it to style object.
59. Passing prop data to a style object: Our app is now being passed a validated prop, which is a number. We can use this number to set from the outside the height we want the text box on the right-hand side to be, which is this area over here. This prop is called contain heights, and we're going to pass the value to a style object to set the container height using CSS. To do this, let's set up a computed property inside of the text output file. We will only re-render when there is a change to the container height prop. Let's add our computed section just underneath the props, separated by a comma. I'm going to call it a computed property our styleObject and then we're going to return the height. I'm going to set the heights to be equal to this.containerHeight, which is our prop which is being passed to. Then because of being passed a number and wanted to be a CSS value, we can also add px for pixels onto the end. This style object will add a CSS high property, sets out the value of the prop, which is currently 130, which you set here. Then inside the object, we add px to declare this is a pixel size. Now our style object is created We can add it to our opening p-tag as a style attribute. Scroll back up to our templates and inside the opening tag, use the colon to bind the styles as these are dynamic. This is going to be equal to our computed property, which is StyleObject. Let's add this to a separate line. Save them. If we go back over to the card, we can see we have the free text output boxes set to a height of 130 pixel, and this is why we earlier set the dotted border. We can clearly see which section is which. Let's go over to the developer tools and we should also be able to see this CSS property. If we select the text output box, we can see inside of the p-elements, we have the style set to a CSS height of 130 pixels. This is how we can work with our props, which are passed down to the component. Note that this is okay to do as we're not modifying the value of the prop directly. We are only using the prop value and then adding it to a CSS object.
60. Introduction to slots: We now know how to parse data from the parent to the child component using Props. We can also pass data to the child component using a method called Slots. Slots are used for what is called content distribution. Often we need to mix the parent's and child component contently ever. In our app so far, if you go over to the App.vue, we can see we have the header at the top and then below it will have the dynamic components elements. We do not always have our components neatly stacked on top of each other, like we do so far in this app. Components can be nested inside of each other, or we can even nest HTML content between the components opening and closing tag. For example, let's say we wanted our component elements to be nested inside of the header component. Let's open up the nav-header and then if we cut the content of the component, including the keep-alive tags and then paste it in there. We now have a situation where things get a little bit messy. The nav-header component has its own template file as does the dynamic component such as conference. We need a way of telling Vue js where inside of the nav-header our dynamic components will be added. This header file has its own templates. So will the dynamic component be rendered before or after this template? Well, this is actually up to us. This is where Slot come in. Slot allow us to control the distribution of this content. We declare a slot inside of the template to place the content inside. Currently, if we over to the browser now, we only see the header at the top and no sign of the content which we have nested inside the app. Just here. You only actually see this header section and nothing else. To display the nested content, over in the Header.vue file, we can add the special slot element inside of the parent template. Just underneath the div-wrapper, I want to add the slot, opening and closing tag. Save that. Then now we can see that the content is now placed inside. This is the dynamic component which is at the top and then below we have the header. This is because we've placed a slot above the header section, which is here. We can also add the slot anywhere we like. We can cut that out with the template and then add it underneath the menu links and now we see our app has returned back to normal. We're not just limited to nesting only components. We can also nest HTML elements inside of components. First, let's return our app back to how it was. If we remove these slots, then over in App.vue, if we move the components outside of the header section. I'm going to create a new footer component, and then pass the content to this via nesting HTML elements. Let's take a look at this in action. Over in the components, we're going to add a new file. This time we're going to add outside of the current section. So make sure this is alongside the Header.vue. This is the Footer.vue file. I've kept this outside of the card sub-folder to keep only card related components organized inside there. Let's add our familiar template. We need a root element to surround our content. We can use the HTML file footer element rather than a div. As we already know, we need to import and register the component to make sure this is available. In the App.vue file, let's do that now. I'm just going to copy an import statement and paste same and then change it to be the Footer, also same for the file path. Make sure that this is just components/Footer, we don't need the card folder. Down in the components, we can register it separated by a comma. I'm going to call mine ccFooter, which is a Footer file. Now this is registered, we can go up to the template still within App.vue. Just underneath the kept-alive component, going to add these elements of ccFooter. Our Footer component currently has no content inside the template, so we'll not see any changes to the app. This is because we're going to add the Footer content as nested HTML elements within this Footer component. Rather than having our content inside the Footer file, we can add it between these two tags. I'm going to start by adding some text of Creative Cards. I'm going to add the HTML entity for the copyright symbol, which is the ampersand and a copy with a semicolon at the end. Then I want to add a bootstrap class for some styling of text-center. There we get to work by adding some nav links. Open up the nav-elements and there we can create our unordered list. I'm going to add some classes to the unordered list of nav and then justify content-center. Then we can add some list items. I'm just going to go over to the header and grab one of these list items, just so we can keep the classes consistent and then paste this inside of the ul. We've got the class of nav-item. We have the link, which is shown by this click this now. The first one I'm going to add as Home and then when I add a couple of more links, copy that and paste in two more times. Now we've got our three links. The first one is Home. The second one I'm going to change to About Us and then the third and final link, I'm going to change to Contact Us and then give that a save. If we go over to the browser and refresh, we see that no changes have applied. We know from our earlier example that nested content will not show. We need to add our slot element to the parent component, which is Footer.vue, so let's add this inside here. With the slot element added, Vue js now knows where we want to distribute content that we've added in between the footer tags. Make sure that's saved and then go over to the browser, and then down at the bottom we have our footer content. This is how we can use Slots to distribute content to where we want it to appear. This is a basic look at using Slots. There are a few more things to cover when using these, and we'll continue to look at these in the next video.
61. Slot scope & fallback content: We now going to continue to look deeper a slots and understand more about them. In the last example, we used a single slot elements in our footer components. If there is only a single slot elements, like we have here, all of the content which were add between the component tags, which is all this, will be inserted inside of this slot. Over in the footer we can also add content between the slot elements just like this. So let's add some text inside of here. All footer text, and this is what we call fallback content. If we go over to the browser and scroll down to the footer, we can see the text is not displayed down in the footer section. This is because the content between the slot tags is considered fallback content. This means it will only be displayed if there is no content to insert. So for comments out the nested elements in the parent components, which is app.vue. Comment on this section, up to the closing nav tag. It's now go back over to the footer and we can see we have the fallback content of footer text slashes to long comment. This section back out. This is just something to consider if the content is not immediately available. Maybe we want to use it with visual for example, and we could show the fallback content until visual becomes true. Another consideration is the scope of the content. At present we have a nav section inside of the footer which is nested. So is all the code inside of here compiled in the parents or within the child scope? Well, let's take a look and find out. So let's say our creative cards texts in the footer, which is just on the top here, was dynamic. So instead of having this section here, if this was dynamic we had some data property, such as appName, would this appName data property restored in the script section of the parent or the child components? Well, the answer is within the parent components. If we go down to the script section, and within the data section, let's add our appName. I set this to be, Creative Cards. Go to the browser, we see the creative cards has appeared down at the bottom, and which got an extra calibration there so let's remove that. We're now seeing the browser that the text appears at the footer. We can now see that the appName works within the parent section. However, if we try to move this data property over to the footer. Let's remove appName and then we want to copy just this data section and then add this inside of the footer. So add the script tags, the export defaults, and then paste in our data section. Here we can add our appName as a string of, "Creative Cards." So save that and let's go back over to the app, and we can see we don't have the text appearing anymore. We can see the scope is within the parents app.vue file. Let's just remove the script tag from the footer, and add this back into the app.vue. So everything inside of the parents simply is within the parent scope. Everything inside of the child components is within the child scope. Such just a few things to think about when using slots. Next up, we'll take a look at using name slots.
62. Named slots: So far, we've only used a single slot elements. This single slot as it is will be used to receive the entire contents section, which we pass to it. Such as all the section between the footer here. As a side note, if there was no slot element presence. If we comment it out or move the slot section and save it up, if we go over to the browser, we see the all the content which is being passed to it. Next inside the parent components is discarded. Let's just undo this slot section and add those back in. Rather than just using a single slot to accept the full contents. We could also use one or more slot elements with a special name attributes. Inside the footer.vue, we can add a name attribute to our slot. This is the name of our choice, someone's name, this app name. Now we can go over to the parent components and match it's name with the content we want to pass to it using the slot attribute. The app name section, which is up at the top here. I'm going to add an attributes inside the opening piece. At the slot attributes and will come matches to the output slot with the name which you just gave it all "app-name." Let's see how this looks. Now down at the bottom, only the app name is displayed inside the footer because we've only distributed this content. I am going to add the copyright symbol just before a dynamic data, so and sign copy and the semicolon, and then we'll see the copyright symbol back on the screen. As you can see, the rest of the elements disappear. We no longer have the enough links. To get the rest of this to display, we have a few options. First, we can continue to add more slots. Also with the name attributes, like we've done here. Or we can catch all the rest of the own name content and distribute it to invert slot element, this time with no name attribute. If you remove the footer text. I'm bringing this up there, and we can also add a second slot element, just like were previously done, but with no name attributes, and now if we go to the browser, we should see the rest of the footer content appear. Now we have our text, which is the name slots. Then all the additional content, which is the navigation links, is now rendered through our unnamed slot elements. This is a simple case of distributing content with slots. If our footer had allow more HTML code, uses slots to place content exactly where we wanted, is really useful tool to have.
63. Section outro: Introduction to Components: Hi. It is Chris again. I just want to take a quick breather at this stage. We've already covered a lot of grounds and learned a lot about components, and how they can communicate with each other. Our project is also coming along nicely now, too, but we still have lots of features and improvements to add in the next section, such as using Firebase to store our images, and also allowing users to set the style of the text. I will see you in the next section, where by the end, you will have a completed fully-functional greeting card application.
64. Section intro: Components Continued & Firebase Storage: Welcome to this brand new section, where we're going to continue working with components. We're also going to be integrating with Firebase, To store our uploaded images. There is also lots of improvements to make to our app, such as allowing users to style texts on the card, and also making the images draggable to them and reposition. We will also learn some new things, such as using the eventbus and also adding mixins too. There is a lot to get through in this section. So let's begin.
65. Setting up Firebase: In this section, we're going to continue with our app and allow users to upload images to display on the card. These images need somewhere to be stored. For this, I'm going to be using Firebase, which is part of Google. We'll use one of the Firebase features, which is storage. Although it can be used for much more, including databases and authentication for platforms such as iOS, Android, and web. If you head over to the web browser and head over to Google, let's do a search for Firebase. Current access Firebase at firebase.google.com, which is the top result. Firebase is free to use and has generous usage limits to test with. There are pricing plans to, but you'll only need these if you app grows to require these. If you want to find out more about Firebase, feel free to look over this website, and then I'm going to begin by going over to the console. You may need to sign in to Google first to get to this stage, so I've signed in with your Google account. If you have one, if not, it's straightforward to set one up. Just follow along with the instructions, and then click on Go to console. So then once you're taken to the screen, we can click on Add projects, and then add a project name, I'm going to call mine Creative Cards App, and then select your country, click Create Project, and just give them a moment to set up. Then we're taken to a welcome screen, and just as a side note, websites like these have a habit of changing layouts over time, so if your version looks a little bit different to mine, don't worry, it just usually means a button or menu link has been moved, both things generally work the same. Then to get started, we can either add our project to iOS, Android, or web, so we're going to click on Add Firebase to your web app. We kind of copy the full set of code, but I'm not going to, because this includes a script tag for Firebase, and I'm going to be adding Firebase as an npm package, so we don't need this section. All we need is the initialized section from within the second script, so we copy this section without the script tags, and then if we go back over to our app. We're going to create a new file inside our projects, and this file will contain all this Firebase setup code. I'm going to call this firebase Config, and this is going to be created in the root of our source. So open up a new file called firebaseConfig.js, inside it's empty file we can paste in the initialization that we just copied from Firebase and save that. So these are the sections that we need to use Firebase, it contains our unique API key. So Firebase knows who is accessing the information, along with links to the location of our projects. Then we need to add the Firebase package to our project with the Node Package Manager. If you open up the terminal, make sure you're in the project folder if using a separate console. If using Visual Studio Code, just head down to the bottom, and make sure that the server is closed by pressing Control C, then we can install Firebase by using npm install dash, dash, save, to save is as a dependency, and the name of the package is simply Firebase, and hit Enter. Then just give that a few moments to install, it shouldn't take too long. Once it's done, we can go over to the package.json file, and we now see within the dependencies object, we have Firebase alongside view. So the first thing we now need to do is to import Firebase inside the firebase.config file. So at the top, we can import Firebase from Firebase, and remember, we don't need to add the full file path to Firebase when it's a Node module. I like to use a capital letter for the module name, so I'm going to change this one just at the bottom to match. Now we have our settings file also, open it to add this to the root of our project, which is App.vue. Scroll down to the script tags, and then we can import this section, so import FirebaseConfig, so this is./firebaseConfig.js. To make sure everything is set-up okay, it'll probably make sense now to start up the service, so go down to the terminal and run npm, run dev. Then we can go into the project, and we can open up the console. So right-click and inspect. If you go into the console and you have no red arrows, this is a good sign that everything is working okay, if you do have any red arrows, make sure you go back and fix those before moving on. This is all we need now to add Firebase to our app. It doesn't do anything at the moment, but in the next video, we'll look at creating the image, upload components to push images back to Firebase.
66. Creating the ImageUpload component: Hopefully, now you should have Firebase initialized in your app with no console errors. If you do, then you're ready to create the image with flow components. This component will be responsible for doing a few things. You will have a HTML file inputs to allow users to select an image from a system. You will also push the selected image to Firebase. You will have a progress bar to show the progress of the upload to Firebase. They'll be an image preview thumbnail. Also have a bone to then confirm we want to use this selected image. Then finally, it will emit the name of the image selected to the parent components. Later on, this image name will be passed to the image output component to download the file from Firebase. Lets begin by creating the components. So go back over to the projects. Then inside of the card folder, let's create a new file called image upload. With the dot view extension, the component will first use the card from the file. Let's go over to card front and import and register it. Down in the script, we're going to copy the import statements then changes to image upload. The same with the file path. Then registered this down at the bottom as a components. Somewhere combine ccImageUpload. Now we can insert the components as an element's wherever we want to. I want to place mine just after the first text box. Scroll back up to the templates. Just after this first cc text inputs, I'm going to add ccImageUpload and the closing tag. I'm also going to add a horizontal line just to keep these separate. Then save that. Now we can add some HTML content inside of the component file. Let's go back over to the image upload.view, and we can add our templates. Again, with our surrounding container, which is our div, and let's add some bootstrap classes for the styling. This is going to be a row, and let's inside of this div we can add a second div, which is going to have the class of col-sm-12 to make this the full width. Then we want to add h4 with a text of upload image. This is going to be displayed at the top of the upload section. You can see exactly which section they are in. Then we want to add another div, which is going to be for the form. This div is going to have a bootstrap class of form group. Then inside here we can add our file inputs. This is the area which we can select a file from all system to upload to Firebase. The input type is of file, we'll add some styles of form, control file, will also need the ID which we'll use later of file upload. After this section, we're going to add a break tag. Just add some space in. Then we can add to add our image elements. I'm going to give this an ID of image. What is the image source empty? Because we had this later with JavaScript and we'll do that in the next video. This is effectively a empty elements until a image has been selected using the input. Then finally we can add a button at the bottom. This button is going to be used to set the image. Once the user can see the preview, this button will then push the image of the Firebase. Let's add a type, a button type of button and also an ID which we'll use later of set image button. Then we can add up the script tags. Now no export defaults. Nucleus was empty just for now. Then finally, our style tags to finish off these templates. Now if we save that and go to the browser, if we see no errors, we should now see the new components on the screen. We have the edge for title, we have the image upload section, which we can click on and choose an image from a machine. We also have the set image button. This is all working fine. If you don't see the components or have a blank screen, check over you call for any errors, and also check the terminal and the console for any clues to where the error may lie. This is now the basic components setup. Next up, we'll continue with this components to display the image thumbnail and also allow the selected image to be pushed to Firebase.
67. Uploading images to firebase: We have now set up the Component button, which allows the user to select a file from their system. We also need to push this image to Firebase for storage. This functionality can be added to a method which is called when the file input is triggered. We can detect this with a onchange event handler. Let's add this over in our template for the image upload. If you locate the file inputs, we're going to add a onchange event handler. So use the at change and I'm going to set this to a method called uploadFile. Now we can go down to the script and set up our data and required methods. Within the Export Default, we can add our data property just in the usual way, and in data property what I'm going to set up is for the Filename. Initially this will be an empty string until the user uploads a image. Then below this data section, we can set up our methods which we just called uploadFile. So setup the methods and then add our method name of uploadFile. Because this is an event, we have access to the event data by passing in a name inside of the parentheses. This can be a name of your choice, but I'm going to call this name event. To begin, we want to grab the selected file and pass it to our file data property. Let's do a console log, and then we can log the value of the events and see how we can grab this file data from this event. Save that, and then if we go over to the Console, right-click Inspect and then go to the Console. I'm going to upload a file with our file upload section. To follow along with this part, you'll need to find an image, if you don't already have one stored on your computer, there's plenty of free sites available where you can download a image to use. I've got one saved on the desktop, so I'm going to go over to desktop and click on Beach.JPEG, and then click on "Open". Nothing happens yet inside of the app, which is fine. But over in the console we have the value of the event. Inside here you can see we have the targets, which we can open up, and then if we scroll down, we need to look for our list of files, then open this up. If you click on zero, which is the first item, we can see the details of the file which we just uploaded. We can see things such as the name, the size, and also the type of image. We're only uploading one image at a time so we can always use position zero. Now we know where the file data is stored, we can pass it to our file data property. Let's go over to the method and remove the Console log. Now we can select this dot file, which is our data, and we're going to set this equal to the event.target.files, and then as we've just seen, we need to select position zero. To push this to Firebase, we need to add a Firebase storage reference. This reference is the location inside the Firebase where want to add our files. We set up the storage reference like this. Let's select Firebase.storage.ref. Since we're referring to the storage and ref methods which are parts of the Firebase module, we'll also need to import Firebase into the file. Let's do this at the top of the script. So import Firebase from Firebase. Down in the ref, we're going to do two things. First, we tell Firebase the folder name to store the images in. If the folder doesn't currently exist, it will be created. This is the first argument which is passed in as a string. Let's create a new file called user_uploads, followed by the forward slash. We can then add the file path after it. We add onto the end of this the Filename, which we currently have as a data property. We're going to add onto the end this.file.name. This folder name plus this Filename will create the file path to store the image inside a Firebase. We can then install this line of code inside a variable called storageRef. Now we have the storage reference. We can call the Firebase put method, to actually upload the image to Firebase. So the image you want to add is this.file. Now this is setup, we can go ahead and test this out. If we go back over to the Firebase Console. Go over to Firebase and then click on the Console to be taken to this page. Select the Creative Cards app, and then on the left-hand side we should see the storage option, click on that. This is the contents of our storage. Currently there is no images listed here, so let's give this a go. If we go over to our app, we can attempt to push an image to this folder. Select the Image Upload, and then choose the image and click open. Then let's go back over to Firebase and refresh. We can see after the refresh that nothing happens. We still don't have any images listed in the storage. If we go back over to the app and open up the Console, and let's see what happens here. We can see that we have a error in the console. The reason we get this error is because by default, Firebase security requires authentication. For the purposes of this demonstration, I'm going to disable this just for our example so we can focus on view js. Of course, for production level apps, we should not do this. To set the rules to public, we need to go to the Rules tab and change this. Select rules from within the storage section, and then what we need to do is to change the write section, and then we need to change this to allow read and also write. Delete this and just leave allow read, write, and then click on "Publish". Okay, so now let's go over to our app and then refresh, and then choose New File. I'm going to select the beach image again and click on "Open". That's a good sign, we don't see any error messages in the console. Let's go over and then go to the files. Okay, great. Now we can see a new folder has been added called useruploads. This is the file that we added inside of our storage reference, and then we can go over to Firebase again and open up this folder. Now we also see we have the file of Beach.JPEG added. If this didn't work instantly for you, you may need to just give it a few moments just for the new settings to take effect. Congratulations if you've managed to get to the stage. This is a big part of our app taken care of. Now we'll move on to the next video, we will add a image preview thumbnail so the user can see which image they've selected.
68. Image preview thumbnail: We're making good progress with our greeting card up. The next step we want to take is take the image file data, which we now receive, stored in the file data property, which is just here, and display it inside an image preview on the screen. To do this, we're going to take advantage of the JavaScript file reader object. We'll use File Reader to read the contents of the image file, which we provided. We'll then pass the results of the events to our image tag as a source attribute inside here. So let's take a look at how we can use it. We're going to add this inside of our upload file method. So make sure that this is within the code basis. So this means that this will be triggered each time a file has been uploaded. To be able to create a newly constructed file read object, install it inside a variable called reader. So this is a new FileReader. Then inside this variable we can access a new method called readAsDataURL. This method reads contents of the file in which we pass to it. So the file we want to read is this date object here, which you can access with this dot file. The A's and onload event handler, which could also use. So reader.onload. This onload event triggers a function. Each time reading operation has successfully completed, this function will take in the event as a parameter which holds the file data. This time I called the event E. Just not confuse it with the event name we've used before. So here will be good places at the image source where we want to display the thumbnail. We already have the image tag inside of our templates, which you just here, which has no source attributes. At moments. We can select it by the ID of the image and set the image stores to be equal to the events target results. So back down, we can select this image using JavaScript. So documents.getElementByID, and ID we gave the image or simply image, and we can use dot source to set the source equal to these events. So do that with e.target.result. To finish things off, we can add a max-width to this image to make sure large images don't mess with our layout. So within the same file, I'm going to go down to the startups, and this time it's going to be scoped, so only applies to this final. We can then target the image and then set the maximum width of the image to be 200 pixels. So this should be all we need to now do. Select start up the server if it's not already running with npm, run dev. Once it opens, we should be able to select a file image and see appearing as a preview. Someone's choose my beach image once again and open it up. Okay, great. So now the file reader is all working and we can see the image preview displayed on the screen by setting the image source. So next we'll add a image upload progress bar, and also make this file data to the parents.
69. Upload progress bar & $emit file data: We can now select an image from the users computer and successfully upload this to Firebase. Also, we have a small image preview underneath the file reader just here. I want to do two things in this video. First, create a HTML progress bar to display to the user the progress of the image upload to Firebase. Keeping track of this upload progress will be important later. Then second, we want to emit the name of the file to the parent component. This is also important because when we create the components to display the image on the card over there, we need to pass the name of the image to it via props. We can download the correct image from Firebase. We begin inside the image upload file by adding the HML progress elements inside the templates. I'm going to add it just above the break tag. Add a progress bar. Then inside here, we're going to set the initial value to zero. This is the starting point for the progress bar. Because we want to work in as a percentage, we're going to set the maximum value to be 100. You can also add an ID of progress bar. This will allow us to select these elements later on with JavaScript. To get this to work we then need to create a state changed event handler on the put method, which we already have. We scroll back down to the upload file method. We have a [inaudible] method just here, which I'm going to store inside a variable so we can access this with the name of Upload. We're going to use this variable to monitor the state changed events using a state change observer provided by Firebase. Still within this upload file method, we're going to add this observer. I'm just going to add this underneath the reader.onload function. We can access it with this upload variable name, which you just gave it, so on. Then the first parameter is state changed alarm. This is provided by Firebase. This will be triggered each time a change of state has occurred. This calls a function. This function takes in the task snapshots. This is an object provided by Firebase. The snapshot contains properties which we can use to monitor the upload. In our case, we're going to use the bytes transferred and total bytes properties to create the percentage of the progress. Then we can store this percentage inside a variable. I'm going to call this variable Progress. We're going to access the snapshots. The property is bytes transferred. This is the number of bytes which are currently being transferred divided by the snapshots.totalBytes. This is the total number of bytes from the file. Let's make this into a percentage. We multiply this by 100. This will give us a value between zero and 100 and store it inside a variable called Progress. Now we have this upload value as a percentage. We can then send this information to the progress bar to update it. To do that, just know it's variable, I'm going to access the progress bar with a document.getElementById. We get the progress bar or an id or progress bar at this end of the string. Then all I want to do is set the value to be equal to this progress variable, etc. Now let's go over to the browser and check if this is working. We can see all progress elements. Now let's choose a file from the uploader and select Open. So appeased, we're working fine. We see the upload state change is caused in a progress bar to increase. That all looks good for now. Great. This is the first part completed. We just now need such of the emit method, just like we've done previously with the text components. This will send the name of the selected image up to the parent components. Let's do them now. Actually, first I'll just add a comment. This was the laid down response to, section is off with comments just so let's create for later. This can be [inaudible]. This is for the progress bar. Now scroll down below this progress bar section. We're going to add this $emits to send the name of the image to the parents. I'm going to call this custom event Display Image Changed. The data we want to send, again is this.file, which is this data here. Then we can access the name of a file with.name. This filename is now sent to the parent file, which is carfront.view. Needs now go to this file and add a new data property to store the name of this image into. Down inside the data section, separated by comma, we can add our image name. This is going to be initially an empty string. When I need to listen for the events on the actual component in which it's passed from, so I need to look for the cc image upload image upload and then listen for the events. The event was called Display Image Changed. We can now set the image name to the value of the events. Image name equals $events. This is all something which we've done before. It's pretty much the same of what we've done with the text inputs. All we're doing is passing the name of the image rather than the value of the text. Let's test this is working. We need to output the image name data using the double curly braces. I'm going to do that over in the card display side for now. Open up the double curly braces and we can now put the value of this image name and say that. Let's go over to the browser. Now if we choose a file, select the image. Great. If everything went right, we will see the name of the image we selected outputting on the card. This is a big step. We now have the image being pushed Firebase. We now have the image preview appearing on the screen. We also have the name of the image being passed to the parent components. Now, we're ready to move on to creating the image output components, which will display the image of only card display section. We'll start with this in the next video.
70. Image output component: We now have all we need to enable us to create the image output components. Let's actually display the image over on the card. We begin in the usual way by creating the image output components. I'll go over to Visual Studio and I'm going to add these components inside the current section. This is going to be called ImageOutput.vue. So let's begin by creating our templates at the top and then our script tags, we use for now an empty export default. Then finally the style tags and then save that. Then once this is done we need to import and register inside of the CardFront.vue. Remember the CardFront is going to be the container, which contains all the image and the text components. So scrolling down to the script section, I'm going to import our ImageOutput from./ImageOutput.vue. So we should able to see a little bit of a pattern emerging here. If you look at the front of the card, we have the TextInput and TextOutput, followed by the ImageUpload or the ImageInput and then also the ImageOutput. So putting data in, passing it to the parent components and then passing this data down to this child as props. Now let's register this in the component section. So I'm going to call this ccImageOutput, which of course is the ImageOutput which we just imported. This now means you can place the components inside of our selected location, inside the card display. So inside of this card display section, I'm going to remove the double curly braces from before and then adding our ImageOutput. Just like the editor area, I'm going to add this as the second component. So cc-image-output and the closing tag. Next we need to pass in some props. First the name of the image to download, which you store in the image name dates property, which is just here. Let's add the first prop into the opening tag. So use the colon to bind this and we're going to call this prop the displayImage. Then pass down the value of imageName. Then the second prop we're going to add is also this container heights, which is just the same as the textsOutput. So this time I want the image to be a little bit bigger than the text, so I'm going to set this to be 350, so save that. Now we can go over to the imageOutput and begin working inside there. The template is pretty simple. At the moment, we will just need an image element to display this image. So let's create the div as the wrapper. Then inside of that we're going to create our image and then we don't need a source for now. All we want to do is add an ID and set this equal to outputImage. So remember this component is receiving props, so we need to have prop validation. Down in the export default, we can add our props inside here. Then this is going to be an objects. So the first one is for the display image, which is the first prop which you pass to it. Inside here we're going to set this to a type of string, then separated by comma. We can also add the container high prop. This would be a type of number. By default we'll also set this to be a value of 200. Now what I am placed test, we are actually receiving these props looking output the display image up inside the template. So open up the double curly braces and then output the display image, which is a prop which we're receiving from the parent, which is just here. Give that a save and let's check this out in the browser. Choose a file and upload the image. So we can see the name has been downloaded and this is a probe which is being passed to the components from the parents. Then let's add some styles to match the textbox dialing. So scroll down to the start section at the bottom. In fact, we want to add a class to the surrounding do first of image container. We can use this target inside of the style section, so.image-container. Then inside here we're going to add our border which is going to one pixel and dotted. Just like the textbox, the overflow can be hidden. Also a margin of five pixels on the top and bottom and zero on the left and right. So at the moment we're receiving the container high prop, which we've been passed. But we're not actually using it to set the height of the container. If we go over to the textOutput.vue file, we set to obey computed property to use this prop as a style objects. The code inside the image output will be exactly the same, so I could just copy and paste this computed section. Then go back over to the imageOutputs.vue. Then we can paste this inside of our objects. So locate the closing props tag and add a comma and then paste this in. Now all that's left to do is to bind the styleObject to the container-div. So go up to the surrounding container using the column we combined the dynamic styles and set this to our styleObject, which is the computed value that we just added so save that. Start the div server and let's load this up inside the browser. The first thing you will see if it's all working correctly is there is a image container which is larger than the textOutput container. This is because we set the image to be 350 pixels. Whereas we only set the container for the textBox to be 130. Then we can also see if we upload our image. The image name should be passed to the card via props. We have this working correctly, well-done. You are now ready to use the image name to download and display the image onto the card.
71. Downloading images from Firebase: Well done for reaching this stage of the course. We've covered a lot so far, and I hope it makes sense. If you're still struggling to understand certain parts, don't worry too much. As you keep going on with this course, you'll get lots more chance to practice. You've already covered most of the core concepts of UGS already. In this video, we're going to download and display the image onto the card. Already, we've been passed the image name finally display image prop, which is just here. Inside of our image, our profile. We can setup a watch property to detect changes caused when the user uploads a new image. Scrolling down, I'm just going to add this just below the props. I'm going to add the watch property. We're going to watch this display image property. Add that inside there. Inside here we want to communicate with Firebase to download the image. First we need to import Firebase into this file. Just underneath the opening script tag, going to import Firebase from Firebase. Then next we need to add a storage reference, just like we did inside the image input components. Go over to the image upload. If you remember, inside this upload file section, we added a storage reference which pushes the name of the file up to Firebase. I'm going to copy this line of code and then go back over to the image outputs and add this inside of the watch property. This is going to create a variable called storage reference, which refers to a file inside the database. This time instead of pushing this top file, we want to refer to it with this dot display image, which is a name of the image which we passed. We can then use the storage reference with the get download URL method to fetch the URL for this file. Just below, we're going to access the storage reference which we just created and then dot get download URL. Again, this is a method provided by Firebase. This problem is resolved successfully. Then we assign a callback function to run. We also need to pass in the URL into the parenthesis which we have just downloaded. Now we have the image's URL. We can add the code to set the image source. Remember we don't have a image source just above. We can access this image via its id of output image. Inside of this body, will we create our variable of image and set this to the image id with document.getElementById. The image Id was output image. Then we can set the image dot source to be equal to this URL, which will be in past. Give that a save. This is a pretty simple example to download the image. We can go even further by adding error handling too but I don't want to go too deep into Firebase for now. Save that and start up the development server and we can check this is working okay. Go to the projects choose a file. Great. Now, we see the image has been successfully downloaded from Firebase. This means our code is all well confined. There is a small problem however and if you can't see the image displayed on the right-hand side, you may have already experienced this. If you've uploaded an image for the first time, you may not see this appearing inside the card. Let's take a look at the problem. If we go over to choose new file and have a new image on the desktop, which is not yet being pushed to Firebase. If we select this, we see that this doesn't work. When we select an image file to use VUGS passages filename to the parents. This filename is passed to the child component, which then tries to download the image much in this file name. The problem is, this happens a lot faster than the time it takes to actually upload the image to the Firebase server. This means [inaudible] we are trying to download an image before it's even been uploaded to Firebase. If we've already uploaded a certain image like the beach image from before, it will not cause a problem because the image is already available inside the Firebase. This is a problem which we can fix pretty easily. We'll take a look at doing this in the next video.
72. Set image button: Inside of the image upload dot vue file, we have set a "Set Image button" inside of our templates. The purpose of this button is to do two things. First, it allows the user to confirm if they want to use this image from the thumbnail. Also, as we mentioned in the last video, we're trying to download an image before its had the time to be uploaded to the server. This button can also solve this problem too if we use a button to emit the file name. We can hide the button, and make it only visible when the progress bar is at 100 percent. So we can begin by hiding the button until an image is loaded. This can be done with some simple CSS. As an attribute, you're going to add the style property and set this to display none. Now we should see the button is removed. Down in our upload file method, if we locate the on load function, and then just below where we update the progress bar, inside here, we can reintroduce the button when the upload progress reaches 100 percent. Underneath where we obtain the progress bar, we can create an if statements to run if the progress is equal to 100 percent. So if the progress, which is this percentage here, is equal to 100, and now we can use a document.getElementById to select this button by its Id. So back inside the if statement, we can add our documents.getElementById, and then pass in the Set Image button Id, and then we can use this to reintroduce the button by setting the display type equal to inline-block. So remember by default, the button mode will be displayed because we set the display to be none. Then we're watching down below for once the progress hits 100 percent, and then once this happens, we'll then set the display type of the button to be inline-block, which will display on the screen. So now let's save that, and give this a try in the browser. We don't see the button by default. So we choose a file now. Once the progress bar hits 100 percent, we now see the Set Image Button back on the screen. Now this button only appears when the image is fully loaded to Firebase. We can now use this to trigger the emit method when clicked. So let's go back over to the button inside of the templates. Then just after the style property, we are going to add a click listener to trigger a method called Set Image. Then let's set up our Set Image method below. So scrolling down, once you get to the end of the Upload File method, which is just here, add a comma, and then we can add our Set Image method. Then inside here, all we need to do is to cut this line of code which emits the filename, and then move this inside of our method. Remember the button sending this custom events only appears when the upload progress is 100 percent. So it's now safe to send this filename to Firebase. Let's save and test this. If we go over to the browser, the first thing I want to do is go over to the Firebase console. So head over to Firebase, and then click on the console, and then select the creative cards up, and then go over to the storage. I'm going to delete the user uploads file. So click on the button on the left, and then select Delete. So now there's no images stored inside the database. We can now go over to our app, and test by selecting a new image to check that it's held back until we select the Set Image button. So go to Choose File, and select a new file which is not inside the Firebase then Set Image. So now we can see we don't have the problem which we had in the last video because we can't download the image from Firebase until it's fully uploaded now. So this all works fine, both if we use uploads in image just like we just done, and then clicks on the Choose File button once again. We want this Set Image button to disappear again until a new image is fully uploaded. Otherwise we'll have the same problem as before. So we can remove this image immediately after the Choose File button is clicked inside of the upload file method. Let's go to the top for the upload file method, and then inside here right at the very top, I'm going to add a document.getElementById. Once again, we're now going to grab the Set Image button, and all we're going to do is set the style property of style dot display equals none. So give that a save, and now let's test it in the browser. Let's select our first image, then set this. Now if we click on Choose file, we should now see that the Set Image button is temporarily removed. So select an image, and then open. Great, did you see that? We lost the image button until the file was fully uploaded. So this is all working fine. The image over here on the display side, may be a little bit too big or too small, but don't worry about this for now. We'll fix this in the later video.
73. Text options menu: font sizes: We now going to return to our text output components and add an options menu. The menu will appear when the user hovers over the text with the mouse over on the right-hand side to allow us to change the font size, text alignments, and even bold or italic options. In this video, I'm going to begin by setting up the menu to appear on hover and also add a font size option. So let's begin by creating our menu using v-show to show or hide once you hover over this text area. So let's go over to our TextOutput.vue file. So just below the opening div, I'm going to add a form. This menu will be form as it's made up with form inputs. So I'm going to add a class, bootstrap class of small. This makes a form a little bit smaller, so it fits inside the text output better. Then we can add our v-show. So we want to bind this to show options which are not yet created. Then I'm just going to add some simple text within P tags. So we just add test inside there. Now, below inside of our script we can set up this showOptions data property. We scroll down and I'm going to add this just below the props, so add our data. I've got the closing comma there. So this is going to return our showOptions data. So I'm going to set the initial value to be true just to see if this is working okay in the browser. Great. So now we have the text of test appearing at the top of each components. So now we know it works, we can change this back to false. So only shows each time we hover over the area. Now it's removed. So to toggle the showOptions area, we can add some mouse event handlers if the user hovers over the text output div. So open up the opening div. I'm looking at advanced called mouseover. So each time the mouse goes over the text area, we can set showOptions to be equal to true. We can also do the same each time the mouse leaves, but this time we're going to set the options to be equal to false. I'm going to save. Now we see it's hidden by default, but if you hover over the text output area, we can see the text is displaying. So now with this in place, we can add a select box to allow us to choose the font size, which we want to use to the text. So go back over to the form. We can replace this P tag with a select area. I'm going to begin with a label for this select area. So label for selectBox. Then I'm going to a title of font size. Let's make some space. Then we're going to add our selectBox just below this label. So at this select area, I'm going to replace this name with a Bootstrap class of custom select. Give this an ID of selectBox, which matches the label just above. Inside here we can add our options, and each one of these options is going to be a different pixel value for the font size. So the first one we're going to add as 42 pixels with the text of 42 pixels. Then we're going to copy and paste this to add some farther options. So we're going to add four options in there. The second one of 48 pixels, the third one as 56, and finally, the largest of 64 pixels. So save that and let's see how this look in the browser. So now if we hover over the text output, we can now see we have the options to select the font sizes. We now need a way to use this selected value in the plates as a font size. It turns out we already have some of these setup. The P tags, which display the text we want to modify, already has a style object binding to it. So we can simply add to this. First we need to add a data property and I'm going to call this setFontSize. So scroll down to the data and separated by a comma add a new data property of setFontSize and set this to an empty string to begin. We can then add this to the select inputs using V-model. So scroll back up to the opening select tag and just after the ID, I'm going to add V-model and set this to be setFontSize. With this two-way data binding setup, the setFontSize data property will be set to the selected value. Now we can pass the selected value to the style object, which we already have. So scroll down to the style object, which is in the computed section. Then we can set the font size property. Because this is JavaScript, it needs to become a case. I'm going to set this font size to be equal to this. and want the data option of setFontSize. Then because this is just receiving a number when this adds pixels, once again, to this let's make it a CSS value. So now this should be done. So I'm going to save. Now we should be able to try this in the browser and see if it changes the font size. So let's add some text into that and hover over and change the font size. That's looks good. Great. That seems to work and each time I click on a different size, we now see the text is changed. So that's working great for now. So next up we'll continue with this menu by adding the text alignment options.
74. Text options menu: text alignment: Our menu is now appearing when we the hover over the text, and we have also successfully added a select input to change the font size. Now we can continue with the menu and add some more options. Specifically free buttons to set the text alignment. It will follow a similar process to the select box but this time we'll use radio buttons. If you feel confident, I would encourage you to go ahead and give this a go on your own before following along with me. If not, I'm going to go ahead now and do this over inside the text output.vue file. Back up to the templates at the top. If we look for the closing select option, let's create some space and make sure this is still within the form. I'm going to begin by adding a div, then we're going to add some bootstrap classes to make this look a little nicer. The first one is going to be form check then also form check in line. Then we can ask the label also the bootstrap class of the form check label. Then within this, in fact, we can add our input between the label. The input is going to be the type of radio. Some classes for styling or form check inputs and then finally you can add a value. The first one I'm going to set to left, so this is for the left alignment. I'm going to copy this full div section and paste in two more times. The middle one is going to be to align the text into the center and the last one is going to be for the left alignment and just after the input, we're going to add the text. The first one is left, center, and then right. Then just like we did with the select box, we can also set up a data property to pass the selected value to. Back down to the script, just underneath set font size, that we used in the last video, we're going to do the same here but this time set the text line. This is going to be an empty string to begin with and too will pass some data to this. Now we have our data property we can set up two-way data binding using V model, so back up to the inputs. First of all, we're going to add V-model as an attribute to the left section. V-model this is going to be sets text-align. This will be the same for all three of these inputs, so we can add this as an attribute to the center and also to the right. Make sure that the two-way data binding is all set to the same dates property. This sets up, set text align with the value from our radio bone, which you've added here, which you can then pass into our style objects. Scrolling down, let's take a look for the style object inside of the computed section. We'll do the same as we did before with the font size by setting the text-align and this is going to be this.set text-align. This is all we need to do, so we can go over to the browser and check it's all working. Add some texts into here and then hover over center, right, and left. Well done if you've managed to do this on your own, if not, it's completely fine. This is all now working so can now move on to the next video and complete this menu section by adding the bold and italic options.
75. Text options menu: font style & weight: Now it's time to finish off our hover menu by adding options to change the text to be both bold and italic. We can use the radio buttons like we've done in the last video, because we want to be able to select both the bold and italic at the same time. Radio bonds only allow one of these we selected. Instead we can achieve this by using check boxes. Let's head over to the TextOutput.vue file. We can add these just below the text alignment section, which is just above the closing form tag. Let's start by creating our div. Let's add some classes to this surrounding div. The first class is going to be all form-check, and also form-check-inline. We can also add our label. I'm just going to add some classes to this of form-check-label, I'm going to add our input. Remember this is going to be the type of check box, and we'll also add some classes to make it look nice of form-check-inputs, and these all Boucher surfaces. Just after the input we are going to add the name of bolds. This is a text which will appear right next to the checkbox. This is one for bold, we also need one for italic. Copy this full div, and then pace it in just below. We can use the same classes, form-check-inline for the input. This is also a checkbox, but with name of Italic. Checkboxes work a little bit differently to radio bonds. Before with radio bonds, we set our data property with a particular value such as left or right. Checkboxes will return a Boolean value of true or false when checked or unchecked. If we go to our text which has the style object binded, which is just here. We can use this true or false value sets or on-site a CSS class, which will bind. First one setup the date properties for bold, italic. Both these initially will be set to false. The text is standard to begin. Go down to the data, and let's add a comma. The first one is what we called setBold with an initial value of false. Then add a comma at the end, and we can set, setItalic also to the initial value of false. Then we can use the model to link this data with the checkboxes. Back up to the checkboxes. Let's add vue model to the input to setup two-way data binding. This first one is going to be the setBold data. Then of course, the second inputs for italic, we'll set this to be setItalic. We can check if this data is changed when being tracked by outputting the value within the curly braces. Just after the its italic text, I'm going to set up the double curly braces. The second one is set italic. I will do the same for setBold. Now had over the browser, and if you hover over our menu, we see an extra bold and italic, we have the initial values of false. First let's check bold. Good start changes to true and then back false and also the italic work too. That means the data property is being updated with vue model. We can now see the check boxes are setting our data correctly. Start to move curly braces first of all, some of the setBold, and also setItalic. Then we can use this Boolean value to bind to our classes. Just like I mentioned before, if we go down to the P text, which currently has the style bindings, we can also add a second attributes to bind the class. This is also going to be a object. Inside this object, we're going to add the first property of bold. This is going to be our data property of setBold and separated by a comma. We will also do the same for italic. This is our set dates property inside there. When set bold is true, you will apply the bold class. When set italic is set to true, it will set the italic class. Now, we just need to set our bold and italic classes inside of the CSS and then we should be done. Scroll down to styles. We'll start with the bold class. I want to do here is set the font-weight to be bold, and also the same for a italic, was at the form style this time to be italic. Save and then head over to the browser, and then hover over the menu. In fact, first, we'll add some text. You can see the styles applied. Hover over the menu, and let's start with bold. Good. We can see the text is toggling between bold and standard. Let's try italic. Good, the styles are now applying into the text. If you open up the div tools, we right-click and inspect and then select the output text. Now if check bold. We can now see that the class of bold has been applied inside the Developer Tools. Let's do the same for italic, and then we see the class of bold and italic applying and once he is added as an attributes, these bold and italic styles then take effect. All that's left to do is add a little bit more styling. Mainly to make sure that once you hover over the menu, it doesn't push down this text if. We wanted to actually appear over the text if rather than push it down as it probably does. Back over to the styles. I'm going to with the form. We're going to set the position to be absolute. We'll add a border just on the bottom and I want to set this to be one pixel dotted and a gray color. I'm going to add some margin to the top of 10 pixels. A little bit to the bottom of five pixels, and then also some Padian just on the bottom. Also five pixels. Just keep us away from the edge. Just to finish this off, I'm going to add just some styling to the select box. All want to do is set the height to be 40 percent, just to make it fits a little bit better. Give that a save. Now, let's see how does it look in the browser? Good. Now when I hover over the menu, we see that the text container is no longer pushed down. The menu now sits nicely on top of the div. I'm going to see how let's look on with some texts. Good that obviously working fine. Our hover menu is now complete. We can now move on to adding some finishing touches to our image components.
76. Remove image button: In the next few videos, I'm going to add some extra functionality to finish off our image components. To begin, I want to add a button which appears when the user hovers over the image to allow the image to be removed. Once you move this, we'll set a default placeholder image onto the card. Go over to the image output.vue file. We can add a button with some bootstrap styling. Just after the initial opening div, I'm going to add a button inside of here with the text of remove image. Then inside the opening button tag, going to add some attributes, will begin with the type and set this will be button. Then some bootstrap classes to apply some styling. First of all, BTN then BTN outline danger and this adds a red border to the button. Then finally BTN-SM, to make the button a little bit smaller. Also, just like the text options, I'm going to add visual, to only show the menu on hover. Inside here, I'm going to create a date option called show options and then let's go down to our view instance and create this. Just underneath the props, we can add our data section. Don't forget to add the coma just afterwards. Then we can return our data. The data property we created was called show options and that's initially sets show options to be false. Then we can set this to true once the user hovers over the image. We do this by adding some mouse events. Let's go back up to the template and add a mouseover, a mouse leave events. I am going to add this in the opening div, just after the binded style object.. We'll begin with mouseover. When the user adds the mouse over the surrounding image, div, we'll then set show options to be true and this will then trigger V Show and enable button to display. We'll then add mouse leave through the opposite once the mouse is moved away from the image container. This time the show options is set to false. So say that and we can test this works okay in the browser. Now move the mouse over the image section and we see the button has displayed. Then if we move the mouse away, the button is unremoved. Finally, to make sure that the button sits on top of the image rather than behind it. We can also set up some CSS. So back over to the image upper file. We can do this down in the style section at the bottom. We can add some styles to the button. First of all, we'll set the position to be absolute and then the Z index to be a value of one, to enable the button to sit on top of the image. Same, lets just check this in the browser. That still looks okay. With our button now in place, we can use it in the next video to remove the image.
77. Passing data with callbacks: We've already looked at parent-child component communication. We know a parent passes data to a child via props, and also a child passes data to the parent with a custom event. There is an alternative too, which we want to make you aware of, and this is by using callback functions. I'm going to demonstrate this with a button which were added in the last video. It works a little differently to emitting custom events. This time, we need to add the functionality inside of the parent components, so, we need to create a clear image method inside of CardFront.vue, so, let's go over to the CardFront , and then open this up, and then we can go down to the method section. In fact, we need to create this. I'm just going to add this after the data section, so, add this in there with the comma to separate. I'm going to add the method of clearImage, and this of course, will be used to remove the image from the screen. When we get to triggering this method, we want it to replace the current image with a default placeholder image, so, the card doesn't look so bad. You can use an existing image you already have inside a Firebase, or you can add a new one. I'm going to go over to the Firebase console and add a default image, so, open up the Firebase console, then open up our app, select Storage, and there's our user uploads. At the moment, I've just got the beach.jpg image inside there. I'm going to go over to upload file and select the file from my desktop, so, I'm going to select this one with the name of Sea. Now, I'm going to copy the name of this image, so, copy the name of this one over the one you just uploaded, or an existing image which is from your list, and now we can use this name to set our image name date property. To do that, we select this with this.imageName, which is this value just here, and now I'm going to set this to a string value of the name of the image. With this setup, we can now pass it as a prop to the ImageOutput child components. Scrolling back up, we can look for the cc-image-output, which is just here, and now we can add a third prop. Remember to use the colon, and call this clearImageProp, and this is going to be equal to clearImage, which is the name of the method which you just set up just here. Then over in the ImageOutput file, we can now add this to our list of props, so, go to ImageOutput.vue, and then up to the script section, let's locate the props. We're going to set this up as a validated function and we can add this to the end, just after containerHeight. The name of the prop was clearImageProp. We're going to set this to be the type of function, then to trigger this function from this child component, we can call it with a click listener on the button, so, scroll back up to the button inside the templates. Then just after v-show, we're also going to add a click listener, then inside here, we can add the name of clearImageProp and give that a save. Now, if we go over to the browser, and then open up our project. Let's check if it's working. If we upload our beach image then click on open, and then set this. Now, if I hover over and select the button, you should then trigger this callback method to then set the new default image with the name which you passed to it, which was just here. Before we wrap this video up, there is one more thing to consider. We only want to set this default image if the user has already added theirs. If we have a blank screen, we don't want to allow the user to click remove. All we need to do to cover this case, is to add if statements inside of the method, to check if the image name data is not empty. Back over in the CardFront, if you go to the clear image method, just above this, we can add an if statement. So if this.ImageName is not equal to an empty string, so in other words, if there is an image present, then we can go ahead and set this.ImageName to be this default name which we just passed. Let's try that. If we refresh, and now if we click on the remove button, we see that no image is being downloaded. This is an alternative way to communicate between components. We still have the issue of our images not quite fitting into the container properly. We will fix this in the next video and also make the images draggable, so, the user can move them to wherever they want them to appear.
78. Making images draggable: All the image functionality is nearly in place now. One of the problems as we have mentioned, is if you upload an image, which is larger or smaller than the Cal Container, it doesn't look too great. We can add jQuery into our app, to easily make our image draggable, by the user. If you're not familiar with jQuery, it's a JavaScript library which allows us to easily, add features, such as DOM manipulation, animations, and event handling, to name a few. On top of this, there is also the jQuery UI Library, which adds user interface functionality, such as effects and interactions. This will be the library which gives us the draggable feature. Let's begin by linking our project to jQuery. I have gone to Google, gone to search for the jQuery Google CDN. The one we need is these hosted libraries, so I'm going to click on this. Here from the menu on the right, we first need to grab the jQuery recall, we click on the jQuery band. I'm going to copy the latest version free, and add it to the, /index.html. We'll copy the script tags for version three, and then go over to the /index.html, and we can add these just after the Google fonts. Paste I enter. Then we can select the jQuery UI link. Click on the jQuery UI, so emoticons copy the script and not the style sheets. Copy the script section from the opening to the closing tag, and then paste this, just blew the jQuery, recall. This is important, it must be placed below the jQuery recall, for it to work, correct. Give them a save and then if we go over to the image output components, we can set this up. Scroll down to the bottom of the script, locate the closing script tag and make sure this code is outside of the view JS incidence. Under only view JS code, I'm going to add a JavaScript function called, SetDraggable. This is just plain JavaScript. In this function we need to grab the image which we want to drag, by its ID, so the image has an ID of outputs image, which you can see just here. Back down to our function. Within a function body, we can use the $ symbol. We use this $ symbol in jQuery, to select an element, rather than when using vanilla JavaScript, such as document.getElementByID. Inside the brackets, we can add this as a string, so you see '#' because it's an ID, and the ID was output image. We then add /.draggable to the selected elements. All is now left to do is to call the setDraggable function, where we need to. I'm going to add this function call, inside of the display image-watcher, just after the Image Source. If we scroll up to the display image, and this is inside the watch section. Just underneath the Image Source, we can add this call to the function, of setDraggable. This is our draggable functionality now setup. Let's see if it's working okay in the browser. Give that save on it's head over to Chrome, barcodes projects, and then we need to select an image, and then click Set Image. Once it loads up, we try clicking on the Image you can now, drag the image around the section, and lets go to finish this off with one piece of CSS. If we go back to the image upper components, and scroll down just below the button, select the image, and then all want to do, is set the width of the image to be a 130 percent. This makes the image a 130 percent of the container, and I have added this in for two reasons. First, it deals with the problem of images being a lot bigger, or a lot smaller than the container. Second, by making the image a little bit bigger, than the container. It gives the user some extra freedom when dragging the image around. This is now done with the image and text components, we can now go ahead and add these to the rest of the card.
79. Finishing the CardInsideLeft component: The card transaction we've been working on so far is now completed. We can now reuse a text and image components to put together the different sides of the card beginning with the inside left. The inside left is a simple section which has a text inputs and a full height text output so the user can add a block of text in the card inside left file. Inside the current section, all we have so far is the containers and some classes. Because we're using the text input and output components, we can begin by importing them so we can use them inside this file. Down in the script, we can add our import. The first one is the text inputs and file puff is./TextInputs.vue. We can also do the same for the text outputs. Import the text output. The component elements are the same as card front so we can copy and paste this into our inside left hand plates. Head over to the card front and then up to the templates. First of all, I'm going to select the cc-text-inputs and then bring this over to the card inside left. We can now remove the text from the top and then paste in the cc-text-inputs. We can also do the same with the text output, so copy this from the card front. I'm going to copy this first one and then add this inside the card display side. The output components will be the height of the card, which is 800 pixels. I'm going to set the container height of this to be 750. This is all can allow for some podium. Now there is the data to add for our text box values. We only have one text input so the only data property we need to add is text box value 1. Just blow the imports, we can set up our data. Let's add the export default and then our data. We're going to return the text box value 1. Just like we've done previously, we'll set this to an initial value of an empty string. Then finally, we also need to register our components to make them available in this file, so just below the data, add comma and then we can add our components. We need to add the cc text inputs, then add a comma. We can also do the same for the cc text outputs, and save that. Let's now open this up in the browser and see how it's looking. If we go over to the inside left, we can see we have our text components on the left, and we can see we've got the dotted border for the outputs on the right. Some of the stylings are missing so we may need to go over to the card front and then go down to the styles and remove the scope section. This then applies to all the current sections but inside left. Now we can see we've got the same styles as the front. This looks like it's all working okay, we just need to type in some texts. We can see all appearing on the output section. If yours looks like this, we are now ready to move on to the inside right section.
80. Finishing the CardInsideRight component: Now, we're going to move onto the inside right of the card. This should be pretty straightforward as we've already done most of the work. We just need to add the three text inputs and output components to make this open like we can see here. It's pretty much a repeat of the inside left, but we need to add three components and also three date properties too. Let's head over to the card inside right. Currently, we just have the text of card inside right. I'm going to go to the inside left section, which we added in the last video, "Command" or "Control A" to copy all and then go into the inside right and then paste this in place of the current data and then we can duplicate the text input two more times, so copy this and paste it in two more times. The only difference is that we need the textBox to be value2 and then value3. Also, the same for the textOutput, got to "Copy" and then paste this in two more times, changing the textBox value to be one, two and then three. Then I'm going to set the containerHeight to be height of 240, so all three can fit on the card and then now down to the data, we already have our text input and output components. These both in imported, so that's fine, but I need to return a textBoxValue2 and also three. We already have the components set up, so all we need to do is save and see how it's looking in the browser. This is the front. Move over to the inside right, so we've got the three components, so box one, box two, and box three and we can also see once you hover over all three, they will still have the individual menu for each one. Because these have the own dates property, these all work independent, so the menu options only apply to the section. This is now the card front, the inside left and inside right completed, which leaves us with just a back to complete and we'll do this in the next video.
81. Finishing the CardBack component: We're now getting towards the end of the project, so well done for getting this far. The back is the last side of the card we need to finish, and it will look like this. Again, it should be simple because we've already completed the components which make this up. We need to add the image upload and outputs, then just a simple copyright logo to finish things off. This will be a good chance to give this a go by yourself by adding the image upload and then the upper components. Just remember, this one needs a callback method too to clear the image just like we used in the card front components. Let's head over to the card back components. Select that. All we have at the moment is the text of the card back. I'm going to remove all contents and then go to the Card Front, select all and copy, and then add this inside of the card back. Remember, the styles are no longer scoped, so we can remove these, unless it will still apply. We don't have any text in the section, so only the image upload and image output. We can remove the first two components. We are going to make use of this clear image method, so we can leave that in. Then open the data section, we only need the image name because we're not working with any of the textbooks values. We can also remove the imports for the text inputs, and also for the text output, and then get to work on our templates. We need one CC image upload, which we already have, so we can remove the free text inputs, so the one from just above, and then two from below. The same for the outputs, we can move the text outputs from above and the two outputs from below. Now we only have the image upload, and then the image outputs on the right-hand side. We're going to use the container heights, and this time I'm going to set this to be 400. We still need the clear image prop, because we're going to use this to remove the image and then trigger the method to then set the default image, which is here. When all that done, let's hit our save and see how it's looking. Go to the back of the card, choose a file, then set the image. Good, that's working. We also have the ability to drag the image. Then let's try and remove an image. Great. That's our default image working with the card back. Now this is working, this is the last section to be completed. We now have all the sections of our card all working. I'll see you in the next video. We'll take a look at the event boost.
82. Introduction to the event bus: When looking at components in these last few sections, we've looked at how parent-child components can communicate. We know we pass data from the child to the parents with custom events. Also, we know we pass data back from the parents to the child using props. This works well if the components which are to communicate, are only one level apart like so far in our app. For example, the text input and output components are direct children of card front. This makes communication easy to achieve. However, there are often circumstances where components are nested two or more levels apart and need to communicate. This is common as our app grows larger. If you consider an app which has a structure like this, the two components at the bottom, have no direct parent components to pass data between. It is possible to keep passing events up the chain, back to the top level and pass props all the way back down for this can quickly get messy and unmaintainable. To make this communication easier, we can use what is called an event bus. An event bus is nothing more than an empty vue instance, which we use as a central data source. We import this into any component file where we want to use it. This will be useful for the next feature we add to our app. Inside of the four card vues, I'm going to add a checkbox to mark this section as completed, then this will pass data to the header to update a progress bar. Like we've seen in the last slide, these two components don't share a common parent components to pass data between. The progress bar is child to the header, and the checkbox is child to the card sections therefore, the event bus is ideal for it's service. I'm going to add this event bus or this vue instance to our main.js file. Head over to the main.js, and we need to make sure we add this before the render function. Just underneath the imports, we're going to export a constant called event bus, and we'll set this to a new vue instance. This will export a constant called event bus therefore, we can now import these into any file we want to access it using the event bus name we've already gave it. This checkbox will be a new component file so we can add it to the forecast sections. We can go ahead and create this in the usual way. So go over to the components, and then inside the card, I'm going to create a new file called SectionCompleted.vue, then we can add the template section with the checkbox and also the text. Add our templates at the top. To begin, I'm going to add a surrounding bus shop row. So in the opening section we can add the class of row and then a second div nest inside and this is going to be for our form group. Let's add some favorable shop classes of form check, and also form check in line. These are styles which we've used previously. These will match the rest of the app. Then one more div inside here with the class of form check label. This is the surrounding div for our inputs. The inputs will have a type of check box, so we can select once the current section has been edited, and it's complete. Finally, some classes of form check input. After here, we can add our text of mark section as completed. To begin, I'm going to place this inside of the card front section. We can add it to the rest soon. So go over to the CardFront.vue, and then we can go down to the script and we can add our imports or section completed. This is also in the same folder of card, so we're going to choose./SectionCompleted. Then we can register this as a component inside the instance and let's call mine ccSectionCompleted, which is the section completed name which we gave to the import just here. The component is now ready to add to the templates. I will add this at the bottom of the edit section, so scroll back up to the templates, and the edit section is this first div here. Just below the last cc-text-input, we can add our cc-section-completed, and the closing tag. Give that safe and we should now be able to start the div servers and see the components. Mine already running, so I'm going to go over to the browser, and then scroll down to the bottom. We should now see we have the components on the screen. We'll have the checkbox and the text of Mark section as completed. The checkbox is appearing off the screen list let's take a look at the SectionCompleted. Cover this, so form check label so change that. Great, so that was the problem there. We just had a styling issue. Now, we have this component setup. In the next video, we'll use this to emit data to the event bus.
83. Sending events to the event bus: We now have a SectionComplete components and the EventBus setup. In this video, we're going to import the EventBus in today's SectionComplete components, then emit a custom events back to the EventBus. Let's begin by importing the EventBus file. So just blow the templates, I'm going to add the script tags. First of all, let's import the EventBus. So this is ES6 syntax. These coded braces import a single member of a module, which we name the EventBus from the main.JS file. So the file path is../../main.js. So rather than importing the full contents of the main JS, which is not what we want. We only want to import this EventBus, which is this export that we've done here. Now we can create a property called Checked. So blow the impulse. We can create our export defaults and then add our data in the usual way. So let's create a data property called Checked, which is initially an empty string. This will be used to contain a true or false value from the Checkbox. Therefore, we need to use this with V-model as a Checkbox attributes. So let's add V model to the Checkbox. So inside the input we can add V-model and set this to be our data value of checked. This Checkbox will also need a click handler. So let's also add this in. So at Click and want to setup a click handler, which triggers a method called Section Completed. So once clicked, this will trigger a method called Section Completed. I will use this method to communicate with the EventBus. So now let's set up this method below. So go back to our view instance. Then just after the data, you can add a comma, and then setup our methods. So we'll call this Section Completed. So previously we've emitted custom events using this.$emit. To do this with the event both we use EventBus.$emit. Of course, if you name the EventBus something else, you will need to use a name which you created. So the EventBus.$emit. Then as before, we pass in the name we want to give to this custom event inside the quotations. So I'm going to call this custom event Mark As Completed. Then separate it by a comma. We want send the value of checks. So add this.checked. These components also needs to be placed in the overcrowd sections to. Let's go ahead and do this now. We need to import, register and also add the components into the template files, just like we've done in CardFront.view. So let's just copy this import statement of Section Completed. We can add these in the card Inside Left. Then at this as a components separated by comma. So cc Section Completed, which is Section completed. Then we can add this inside the templates, just like we've done with CardFronts. So we've done this at the bottom of the edit area. So let's do the same for Inside Left. So just underneath the text inputs, you can add the cc Section Completed. Same for the Inside Right pacing the import, register the components and then this to the template again underneath all the text inputs. That's the fronts Inside Left and Inside Right, which just leaves the CardBack.vue. So pacing the import and we'll do exactly the same. Register the components of cc Section Completed. Then finally, we'll add this in to the editor area, along with the closing tag, and then hit save. Then let's test this inside of the browser. So let's start with the Card Front. So we have the component displaying on the screen. Inside left, we can also see it. The Inside Right looks fine too. Then finally the back. So this is a component now complete and sending custom events to the EventBus. We'll check this is working in the next video where we'll create our final component for this project, which we'll use to receive the value of this event from the EventBus.
84. Receiving events from the event bus: We've now sent data to the central event bus using a dollar sign emits to send these custom events. Now, we'll begin by creating the final components of this project, which will be the progress section inside the header. This component will also use the event bus, but this time it will listen for the event and use the data passed to it. As always we begin by creating the component file. I'm going to call this file the CardProgress.vue. So within the card folder I'm going to add a new file of CardProgress.vue. So within here we can create our usual templates. I will script tags, and then finally I will style tags. Within the script I'm going create a empty export default for all view instance, which we'll come back to you soon. This component will be nested inside the header component. So we need to register this inside the header.vue file. So let's go through this file and we can begin by importing this new CardProgress file. So at the top of the scripts I'm going to add our import of CardProgress. So the file path is./, this is also within the card folder. So CardProgress.vue, and then within our instance we can register our components. So just underneath the watcher I'm going to add a, and then add our components. So the only component we need to add is this file. So I'm going to call my ccCardProgress. So now with all the file imported and registered, we can now go ahead and add this to our templates. Just underneath the unordered lists for the nav links, we're going to add a horizontal line, and then below this at, the ccCardProgress. So as always, this needs a opening and the closing tag. So it is now imported, registered and a template. We can now go back out to the cardprogress.vue file, and begin to add our templates. I'm going to begin with a surrounding div, which is going to be the div for our row. So we can add bootstrap classes of row inside here. Then a second div, and this div is going to contain our class of col-sm-12. So this is a full width components. So the contents of this template will be pretty straightforward. All we're going to do is add a progress bar, and also complete the text, which says how many sections have been ticked, so for example, 104 and 204. So let's add this text first with the P tags. Within here we are going to add the texts of completed. So by default it will be zero or four. The serial will be dynamic. This needs to be increased every time the user clicks on the checkbox. So to make this dynamic. We can add these span tags before and after the zero, and then so we can change the contents between these tags, I'm going to add an Id of counter. This is just so we can access it with JavaScript later on in this video. This component will access the event bus. So we need to import this inside of the scripts. So down on the top of the script tags, we're going to import the event bus. I'm going to do this with the ES6 syntax which we looked at previously. So this will import the single member of the event bus from the main.js file. So to access this main.js file, the path is../,../, the main.js. So if you remember from early on in this course, we looked at the view life cycle hooks. One of those hooks was the created hook, and we can use this created hook to run a function. Each of the component is created. Inside this hook we can listen for a custom events on the view instance with the dollar sign on method. So let's add this now. Back down to the export default, we can add the created hook. Within this created hook we can access the event bus and then use a dollar sign on, instance method to listen for a custom events. The event we want to listen for is mark as completed. So this mark as completed event is the one which is being passed to the event bus from our section completed file. So we just here, so each time the user clicks on the checkbox, which is Boolean value of true or false, this is then emitted to the event bus, and then we'll have access to this with the card progress file. So anytime there's a change to this event, this will then trigger a function. This function takes in the event data between the parentheses. So I'm going to call this data, and we can then use this data inside of our function body. So as we just mentioned before, the value being passed to the event bus is a checkbox value of true or false. This means that this data being post to us just here, will be either true or false. So can add a if statement to check if the data is true. If it is, we want to increment the counter by one each time. So we can access the counter with the Id of counter, which is the span tag surrounded in zero. So we can access this with documents.getElementsById. The Id of course is counter. So now we've selected this counter. We want to access the inner text. So we want to increase zero by one each time. We can easily do this with dot in a text, plus plus. So if the data inside here is true, the count will be increased by one each time. So let's give that a save and check this out in the browser. So go over to the browser, and then if we select mark section as completed, we now see that we have the value of one or four. To go to a second section and take a now say two or four, and then free, and then finally four to four. So we can see if you keep clicking on the check box, the value keeps going up and up. We then need to make sure if the user uncheck the box, that the value is reduced by one also. So we can easily do this inside an else statements. So just after the if statement, we can also add else, and then I'm just going to copy this.getElementById based in where also are we going to select the counter. But this time, we're going to decrement by one on each click, so save that, and now if we go over and refresh, let's start with the front. So now we see one, the insight left, now we see two, and then click on again, and now it reduces back down to one. Let's just try this with one more component, so two, and then back to one. So that all seems to work in fine. So the final thing to do is now increase and decrease the progress bar to give the user a visual indication. So already have mostly setup with the if-else statements. So inside the if-statements, I'm going to again paste in this documents.getElementById. But this time we want to select the progress bar. So let's add the progress bar just underneath this completed section. So let's begin with 0 percent. So the value is initially set to zero, and then we want the maximum value to be equal to 100. Then so we can increase this value each time we're going to add an Id of CardProgress, so save that. Now we can use this CardProgress Id inside the document.getElementById. So instead of selecting the counter, we'll paste in the cardProgress. But this time we want to increase the value. So that value to be increased by 25 each time. This is because it's a percentage, we have four sections. So each time it's clicked, it will go up by 25 percent, so plus equals 25. So I'm going to copy this, and paste this inside the else-statements. But this time, change the plus to a negative and then save that. Then let's go to the browser and give us a go. So let's try clicking on one of the sections. So mark is as completed, and now we see the progress bar is increasing. That's trying to move that, and it also goes down too. Let's try one more section okay good. So that all looks in place, so as well as the completed text increasing and going down, we also see the value of the progress bar change too. One last thing to do to finish off this components is to make the progress bar the full width of the page. This can be done with some simple CSS over in the CardProgress.vue file. So let's go down to the style tags and make this scoped. So the styles would only apply to this section. We want to target the progress bar and then set the width to be equal to 100 percent. So let's see how this looks now if we refresh the browser, okay good. We see the progress bar spans the full width of the container. So let's test this, so let's click on the checkbox. Let's try a second one, it all looks good, and a third one, okay good. This is all working now, so congratulations. You've now successfully used the event bus for non parent-child communication.
85. Adding mixins: As our app grows bigger, there may sometimes be situations where components will need to reuse the same code. Usually, it's not good practice to repeat the same code more than once. Inside our app, if we look at the CardFront, so go to the CardFront.vue, and then up to the script. Here we have a new method called clearImage. Also if we go to the CardBack components, we also have the same repeated method just here. So do repeat the same clearImage method more than once. To help with this vue.js devices with mixins. Mixins are an easier way to take any of the functionality from our components. This includes anything such as our data, methods, and computed properties and placed in their own separate file. This file can then be imported into each components which needs access to it. Let's create this file in the source folder. I'm going to call this file the clearImageMixin, and it comes after the.js extension. Then we can export it as a constant called clearImageMixin. So export the constants of clearImageMixin, and you can call this anything you want, but I'm going to call this clearImageMixin as it's valid descriptive. Now our clearImage method can be called from inside the CardBack.vue file. So go to the CardBack.vue and then I'm going to call this full methods, not just the clearImage section. So cut the full method up to there. Also make sure to remove the closing comma. Then this method can now be pasted into our mixin file. So go backward to these objects and paste this in. Bare to mind we can also add anything else from our Vue instance here, such as any data and computed properties which may be related. This constant has been exported now. So we can now go back to the card, back components, and important the new mixin. So back to the top of the script, we can add import statements for the first three. Again, just like the Eventbus, we use the curly braces to indicate we want to impose a single member of this module. In our case, the name is clearImageMixin and then we want to import this from the file path of../../clearImageMixin. Now this is imported. We can now mix this in with the rest of our code inside the Vue instance. So within the export defaults, we can also add the mixin's property, and this is an array. I'm sure it's out the comma just afterwards to separate this from the data. So inside here we can add the name of our mixin which was clearImageMixin. So this is the clearImage method added now back into our components. Few just that mixes the contents into our existing data. If there are any conflicting keys inside of the object to be merged in, the components options will take priority. We can split up our code into more mixins too. We're not restricted to only use a morn. The process is the same as we've just done. We move the code into its own file, import module, and then we can also add the name of the mixin to these mixin's array separated by a comma. Now we just need to do the same inside our code from file. We will also add the clearImage method. Save this file and go over to the CardFront.vue. So we'll do exactly the same. We need to remove the full method from the Vue instance. We then need to import the clearImageMixin. So add these onto the bottom of the imports, just as we've done before. So clearImageMixin. The file path is the same, it's../../clearImageMixin. Then we go down to our export defaults and adds our mixin's array. We only have one, so clearImageMixin is the only value inside the array. Now we can head over to our app and test the clearImage method is it working inside both the CardFront and the CardBack components. So save this file and go over to the browser. We can begin inside the CardFront section. Let's choose a file, then insert image, and once it downloads, head over to the image and click on the removal. Good. So that one is still working. We'll also test this inside the CardBack from pressures will find to. So choose an image, open it up, set the image, then hover over and remove the image. Great. So that's all still working. So remember that we can use as many mixins as you want inside of our app. The word bear in mind if we need to use code in more than one place. So mixins are a good way to organize our projects and also avoid any code repetition.
86. Section outro: Components Continued & Firebase Storage: Congratulations for reaching the end of this section. We have covered so much in this section including working with Firebase, adding the text options menu, working with components, and also alternative ways of passing data between them. By now, we should also have a fully functional greeting card application packed with features, and hope you've learned a lot from it, too. You have now learned a lot about building applications with Vue.js. Now, let's continue learning in the next section.
87. Section intro: Transitions & Animations: Welcome to this brand new section. We're going to take a break from adding new features to our app and also components to look at some ways to really make our app a lot nicer to use. This section is all about adding transitions and animations. This is a great way to make your apps look a lot more polished and really improve the user experience. We'll hope you look forward to this new section and I'll see you there.
88. Transition classes: When working with enter leave transitions, there are six classes which are applied during various stages of the transition. We have free for the interface which deals with starting, ending and also the active phase. The same also applies for the leaving phase, where we also have access to the starting, leaving, an active classes. To understand what each one of these do, I've setup a simple transition drawn, which sets the opacity of an elements or components. Here we have the interface and the transition begins in the v-enter class. Inside of this class, we can, for example, add CSS classes to declare how the elements or components will begin to transition. In this example, our elements will begin as transparent. So we could set the opacity to zero here. This only takes effect for the first frame of the transition. So only use it for the initial startup phase. After this first phase, v-enter then removed, and then v-enter-to takes over. v-enter-to sets the ending state for the enter phase. For example, here we could set the opacity to be one, since the element is now inserted. During the full interface, we also have access to another class called v-enter-active. Because this cozy full inter-phase, this is an ideal place to add CSS to set the time duration or delay of the transition. Then we move on to the leave transition. Here, we basically have the same as the first three classes, revised. For the first frame of the leaving transition is triggered, we set the initial state with v-leave. Just like the interface is lasts for one frame, then v-leave-to, is responsible for the ending state. Undecided when v-leave is removed after the first frame. V-leave-to is where we add the ending state for the transition. Just like before, the leaving transition also has a class which covers the full leave in phase called v-leave-active. Also too, this is ideal for certain things such as the duration of the transition. So these are the six classes we have access to during the transition. The class names all begin with the v prefix by default, when used with the transition elements. We can also add a name to this transition, and this name would then replace the v prefix. For example, if our transition had the name of fade, the classes will be called fade-enter, fade-enter-active and so on. But these are some things which we'll take a look at in more detail in the next video. We will begin to put this into practice.
89. Adding CSS transitions: Back in the creative cars projects to begin to put some transitions into practice. Now we've seen the transition classes we can use. The first technique I want to show you is to apply a transition refer to elements or components. I'm going to head over to the TextOutput.vue file. So it's like the TextOutput.vue. I'm going to add this transition wrapper around the form elements. This is the options menu which appears when you over the text. This is ideal for adding a transition because currently it only shows and hides without any type of effects, such as fading in and fading out. So what we need do above the form the transition wrapper. So the opening is like that and then down at the closing form, going to close off this transition and give that a save. Beware though that the transition elements can only be used in certain cases. We can use it with V, if of V show also we components, which we'll look at soon. This form section works with V show. So we find in the last video we mentioned naming the transition. To provide a name, we add this name inside of the transition opening tag. So back up to the transition. Open the tag. The transition will be used to fade the menu in and out. Let's call this fade. So name equal to fade. This transition name replaces the V prefix in CSS. So let's set this up in the style section. So scroll down to the style tags down at the bottom. We're not this just after the select. Here we can add all of our transition classes. Let's begin with fade-enter, fade-enter-active, fade-enter-to, fade-leave. The last two is fade-leave-active. Finally, fade-leave-to. This fade is the name of the transition which we've gave. This is the replacement for the V prefix that we mentioned before. This may look like a lot of things going on here, but we can't simplify things for this example. So if we look at this example from before, V answer has the capacity of zero. Also in the leaving transition, v-leave-to also has the capacity of zero. So we can combine these Inside the CSS to make things a little bit more simple. So over the top we have fade-enter. I'm also going to add fade-leave-to put this section and enter the braces and have them combine this with fade answer. We're going to set the opacity just like we've seen in the example before. This is going to be zero. Also v-enter-to and v-leave has the same CSS opacity of one. So we could also combine these. However, we don't need to do this. The reason is because CSS opacity is set to one by default. There is no need to declare it unless is something other than defaults. The opacity we set at zero will be removed after the first frame, which will then restore the defaults. This means we can remove v-enter-to. Also v-leave for this example. Let's remove those two. So this just leaves us with the active classes for the enter and leave phases. We can use a certain length of time the transition takes to appear and also to remove. These two classes can also be combined. Set the same transition time, keep it even. So let's cut this one. Then let's add this just in there. Then let's add transition to both of these classes. So we're going to use CSS transition property. So we want to set the opacity of a 0.5 seconds. So give that a save. Now if we go over to the browser, and then if we hover over one of the elements, we can see that the menu nicely fades in and out of a half seconds. This just looks a little bit nicer than did before. Another thing we can do is we can also move the CSS for this phase fade transition and add it into the up-to view file as a global style. They'll be useful if we wanted to add the fade style into all the elements. Let's go over to the CSS. If we cut out the styles, save the file. Then if we go to the app.vue, can paste these in as global styles. So just at the bottom, paste these in. Now if I hover over the menu, we can see that the phade still applies. While we're at it, we can also do the same for the remove image button to make it nicely fade in and out. So I've got the image output file and then to round this button we can do exactly the same. We can add the transition wrapper and then give this a name of fade. Then close off this wrapper. Just like that and give that a save. Now if we go to the app, we can now see that the button, as well as the menu, nicely fades in and out. So this is a simple example of a transition, but it really makes a difference to the look and feel of our app. Next, we will look at adding inCSS animations.
90. Adding CSS animations: Along with transitions, we also have the options to add animations to. Animations allow us to gradually change from one style to another. We could gradually change an element from one color to another. For this example, I'm going to add a scale effect to the remove image button. This means a button will begin small, and then grow to full size when the mouse hovers over it. Then when the mouse leaves the button will then shrink outer view. We can begin in the same way by using the transition mapper. Go over to the ImageOutput.vue file. Then if we look for the button to remove the image, which is just here, I'm going to change the name of the transition to be scale. For the animation, we need to set up the at keyframes rule. We need set up keyframes to control the steps of the CSS animation. To begin, let's set up the keyframes for scaling in and then scaling out. Down in the CSS, right at the bottom of the page, just blow this image selector then the at keyframes. I'm going to create one for scale in, and then a second one for scale out, just like that. This is standard CSS, it's not Vue specific. Then we need to stop the steps of the animation. To keep things simple, I'm just going to add a beginning and an end stage. If we wanted to, we could even add more stages at different percentages during animation. Let's start with zero percent, which is the start. At zero percent, I'm going to set a transform. I am going to transform the scale to initially begin at zero, and then underneath here we're going to set the 100 percent rule. This is again going to be a transform of scale, but this time it's going to be one. This sets up the frames when the animation is scaling in. At zero percent scale is zero, so it comes here. Then at the end of the transformation, the scale is then taken up to one, which will make it full size. I'm also going to do the same for scale out by copying these two lines of code and pasting them in. But because we're scaling out, we want to do the opposite. At zero percent, this time we want the scale to be one so it's fully visible on the screen at full size. Then at the end of it at 100 percent we want is to be shrunk right back down so we can see it. We'll set the scale to be zero when we're just adding the zero on 100 percent stages. We can also change this to be called to and from rather than zero on 100 percent. If one works fine, now we have the keyframes setups control of how we want the animation to work. We can add these to the CSS rules just like we've done before. Above the keyframes I'm going to add the CSS rules. Remember because we call this animation scale, I'm going to add the scale class of enter active. Here we're going to set the animation that we want to use. The animation is scale in keyframe section, and then we set the duration. I want this to happen over 0.5 seconds. Then below we can do the leave active phase. So scale leave active. This again takes in a animation. This time because we're leaving the animation, we want to use the scale out section. The animation is scaled out. I'm going to keep this over 0.5 seconds for the duration. Remember the enter active and leave active classes, cover the full enter and leaving phase. Here is an ideal place to add our animation to, along with the timescale for its take. Let's give that save and then go over to the browser. If we go to the image output, we can see when we hover over the section that the button that was rounded with the transition, now scales from zero right through to a 100 percent of the size, over half a second. Once we have these keyframes set up, adding an animation is a lot like the transitions which we looked at in the last video. We still have access to the CSS classes, such as v leave and v enter to. But through the reminder, if using v enter, this is not immediately removed after the element is inserted. Instead, this happens with the animation end events. The root transition elements has both a transition end and also an animation end event listener attached, so Vue JS knows when the transition has ended. This is a small difference to be aware of when using animations. Next we'll move on to adding transitions to components.
91. Component transitions & transition modes: We are not limited to adding transitions on animations to just elements. We can even transition between components when we click on the menu links. It starts with the familiar transition wrapper, which we can still use with the keep-alive tags. Let's begin over in the App.vue. If we locate this keep-alive section with the components, I'm just going to create some space above and also below. Then we're going to create the familiar transition wrapper. Add this at the start. Then on the closing tag, just after the final keep-alive tag, just like that. Then I'm going to reuse the fade name, take advantage of the styles we've already set down at the bottom. Just here. Let's do this by adding the transition name inside the opening tag. The name equal to the fade, and then give them a same. Now, if we go over to the browser, we can take a look at the effects. Now if we click on the different pages, we can see that there is a transition happening. But if we take a closer look, we can see a problem. To show this in more detail, I'm going to zoom out. Then now, if we click on the different web pages, we can see that the web page starts at the bottom and then jumps. It's now back to full size. This is not the behavior which we're expecting. The reason is happened is because by default, the transition elements entering and leave phase both happen at the same time. As a new component enters, the space is still occupied by the all components. Then once the old component leaves, the space is then created for the new components, causing and end to jump into place. Fortunately, Vue just write this with a transition mode to help deal with this. We can add the mode as an attribute to the transition opening tag. Just after the name, I'm going to add the mode. Here, we can either set in-out or out-in. Let's start with in-out and take a look, and give that refresh. Now, we can see there's a bit of a delay, but the page being changed. In-out will not be useful for those because it brings in the new component first, and then removes the existing components. Let's try out-in, and let's see how this is looking. If we go back to the browser and we'll zoom out again just to make sure. Great. Now, when we select the different pages, we can see that the component is switched in the same position, rather than beginning at the bottom and then jumping back into place. This is exactly what we want. The old component is first removed, then the new component begins to fade in.
92. Javascript hooks introduction: During this section, we've used CSS to create animations and transitions in our app. Vgs also provides us with JavaScript hooks, which we can use during certain phases of the transition. If you remember from earlier in the course, we looked at how we could use Hook's during various lifecycle stages. Well, transition Hook's work like this too. By using these hooks, we have access to all the features which JavaScript officers not limited to just apply in CSS. He can see the various hooks which we can use. Just like the transition classes. We have a enter and leave in phase, both with four hooks each. Below these self-explanatory. But will begin with before enter. As it sounds, this hook is called on the beginning before the enter phase begins. We then have enter which runs wants to transition has begun the interface. The final hook of the interphase is after enter, and this is called 1C elements or components, has finished the transition in. The final enter hook is called Enter canceled. This is useful to have if the transmission gets canceled while in progress. For example, if VCO becomes false, before the transition has had a chance to complete, here we can do some cleanup work or restore the transition back to its original state. We also have the same on the leaf phase but before leave, leave, after leave, and then also leave canceled. Applying this is an easier is relatively easy to do. All we need to do is add whichever hooks you want to use as an attribute to the transition elements. For example, here we have the enter and leave hooks as our attributes. So these are the hooks we have available to use. Now let's go back to the project and see them in action.
93. Javascript hooks in action: Now we know what hooks we have available to us during the transition. We can now add them to our application. I'm going to use them to add some instructions to our app. These instructions will simply tell the user to edit the section on the left, and the changes will then appear on the card on the right-hand side. To do this, I'm going to go over to the App.vue, and then at the end to hook to the components transition. On the opening tag, I'm going to add these onto their own line, just so it's more readable, and then at the bottom, we're going to use @ Enter equals Enter. Here I'm using the @ symbol as a short hand for v on to call the Enter hook, then add in the method name of Enter. We can create this method soon. But first let's add our instruction, we want to display. I'm going to do this just about the transition, but below the nav header. I'm going to create a div to begin with, and this is going to be the surrounding section for our instructions. Let's create a div, and also the closing tag. Here I'm going to give you some ID of instructions, and then some classes to make it look a little bit nicer. Text center and also italic. Within this div, I'm going to create a new bootstrap div with the class of row, just like that. Then inside here I'm going to create two new sections. This is going to divide the page into, so it's going to be two, six column sections. The left-hand side will have some texts, to say make some changes in the editor area below. The right-hand side will then tell the user that the changes will appear below, on the right-hand side. Let's add another div. In fact, let it cluster this. Class or bootstraps col-sm-6, so it's half the width of the page. Then we'll add some p tags to add some text, and then nested inside here I'm going to add the m tags to add some emphasis onto the text. I'm going to begin with HTML entity. The ampersand, larr, then semicolon, and this is for the left arrow. We save that. We can see the left arrow is appearing on the side. Then I go ahead and add the text of make changes in the Edit Code Area below. Save that and let's see how this is looking. Great, that's exactly what we wanted of the text above the edit area. Now we'll copy this div and do the same for the output area. Copy this six column section and then paste in just below. Established need to change the text, and this time it's going to be under will show on the card, just like that. Then we need the HTML entity this time of the right arrow. The ampersand rarr semicolon. Great, so that's exactly what we wanted. We now have some instructions to the user. Now we can go ahead and setup the Enter method. We added the Enter method's name just above, sorry, just below on the transition of Enter. Now let's go down to the view instance and create a new method. Let's just do this just below the data. Let's add our methods into here, so number one is called Enter. If you create it in the usual way, and as with all events we've looked at previously, we do have some data pass to this method, which you pass into the premises of the function. I'm going to call this L, as the data passed to it is the element we are transitioning, so that makes sense. We can see this with a console log. Let's quickly add a console log into here and then output the value of L, I forgot to inspect. Then go to the console. We'll see this in action if we switch between the components. There we go. Now we see the elements which is being passed to it. This can be used at any JavaScript which we like. I'm going to use it to set the display type of the instructions to be none. This means instructions will initially show when the app is loaded, but then they'll be removed using JavaScript when we switch between components. Let's remove this console log and replace it with JavaScript. Document dot get element by ID. The ID we want to grab is this instruction section, which we give an ID of instructions just here. Now we can grab it and place it inside the brackets there. Then to remove it, we can set the style, though display to be equal to non. Of course, we can also use any of the hooks we looked at in the last video two if we need to. Let's save that. Now if we go over to the output, we can see the instructions still there. But if we switch to different components, we see that it's now removed. The instructions are only there when the user first visits the site. Of course, we can also use any other hooks we looked at too in the last video. There is one important thing to remember though, when using both Enter and Leave hooks. When using JavaScript only, rather than mixing JavaScript hooks along with CSS transitions, we have to add a second argument. The second argument is the done callback. We pass this into the parentheses of our method next to L. Separated by comma, we're going to add done as a second argument. Then we call it as a function at the end of our JavaScript code. Just at the end of this method, we can add done to call the function. This will then call it as a function, at the end of our code. CSS transitions have things such as time durations, the signal end of a transition or animation. When using JavaScript, we need to add done to the end of the code to tell Vue.js when the transition has actually finished. When we use this in combination with CSS, the done call back is optional when using hooks over that Enter and Leave, only L is required. Finally, it's considered good practice to tell Vue.js if we're only using JavaScript on a transition, rather than using both JavaScript and CSS, both together. This is how Vue.js can skip the CSS detection stage. We can do this by adding another attributes to the transition. Let's go back up to the transition opening tag, and just after the @ Enter and want to do a v-bind. CSS equals false. This of course, is not for our usecase because we also mixed the JavaScript hook with the fade CSS, so we can go ahead and remove this line. But it is useful to be aware of, and you may need it in the future. This is how we can use JavaScript hooks. In the next video, we'll look at how we can mix both transitions and animations.
94. Mixing animations & transitions: We have looked at using both transitions and animations independently so far. Both of these can also be mixed to work together too. To do this, we do need to remove the don't call mark from the app.vue file. Let's go and do that now inside the app.vue and down inside the method, we can remove the done, second arguments, and then also the call to it at the end of our method. Give us save. We remove this because it stops VGS from detecting the CSS transitions, which we will be using. So let us begin by going over to the imageoutputs.vue file. I'm first going to cut the styles from here and then move them to the main app.js file within the style tags. So let's start by cutting the scale. Scale enter-active right down to the keyframes. So cut those outside of the image output, save that and then head over to the app.vue. Down in style we can add these below the fake classes. So paste that in there. With these styles now available globally, we can use them throughout the app. As an example, we can mix in scale animation with the existing fade. So what I'm going to do first is splits up the fade-enter-active, and also the fade-leave-active onto their own lines. This is how we can use them independently. So I'm going to cut and paste this in action with the fade enter and the second one and also remove the fade-leave from the first one. We can now mixing the scale in and scale out animations, but change the durations to be longer. Let's say two seconds. So inside the fade-enter-active, going to keep the transition of the opacity for this time, we're going to mix it with animation. Let's add the animation of scaling. This time over a duration of two seconds. Rapidly scaling animation, we set with the keyframes below. Start this one here. When fading now as well, we can also use scale out. Let's do this inside the fade-leave-active. We can an animation, use the scale keyframes over a duration of two seconds. Now let's save that and go over to the browser and see how this is looking. So make it a little bit smaller so we can see it coming in and out. Great. So it doesn't look pretty, but you can see as a demonstration, how the animation and transition, both work together. Now have an animation and transition, but both flowing for different durations, things can be a little bit messed up. We do need tell VGS if we want the animation, all the transition be a priority for time in. We do this inside of the transition elements by setting the transition type. So let's go back over to the editor and find the transition wrapper which you've been using. Just here. Just after the JavaScript hook, we can add a type. Let's set the priority for animation and see how let's look in. So therefore the animation is a priority. Let's change this to transition and then save and now we can see it does look a little bit different. It doesn't quite work for our application, but it does show you how we can set the type or the priority for the transition. I am going to remove this type as we don't need it. This is because I'm also going to remove the animation from the CSS. Let's remove the type and then down to the styles, let's remove the animations that we just added because you don't need these for our use. So give us save and hopefully it should return back to normal. Great. This is how we can set if we want a transition or an animation to take priority when mixing both types
95. Custom transition classes: So far, when using transitions, we've used the classes provided to us by vuejs, such as v-enter and v-leave, which you can see here. This is ideal for lower cases, but maybe times we want to use our own custom CSS classes. These situations can arise, particularly when using a third party library for animations. Animation libraries such as animate.css, work by including the library as a CSS file or by using a CDN link to the library. Then to access the animations, we use the custom class names for each animation, such as class equals bounds, f or example. We count out this custom class name using the hooks provided tools. However, instead, vuejs provides us with some custom classes to replace each transition class. For example, we can add the anti-class attribute, with our own custom CSS class. This will then replace the v-enter class. We can see this in action if you head over to our app. Let's begin in the image output file. We gave this transition a name of scale, for the remove image button, also over in the app.vue, down in style section, down at the bottom. We then created the class names. We using of scale enter active and scale leave active. Rather than using these preset names, we can ask the custom classes, which we just looked at in the slides. To do this, over in the image outputs, we can remove the name which you provided before. Lets remove the name attributes, and then on the next line I'm going to add some new attributes, to then set up our custom class names. So I'm going to start with enter active class, and then set is to our custom name of custom enter active, of course this can be any name. Then I want to do the same for leave active class, and again set this to our a custom name. So I'm going to use custom, leave active. Now to link this to the CSS, let's go back over to the app.vue and then go down to the web-scale classes. We can then change is to activate phases to be our custom CSS class names. So the first one, rather than scale, it was custom, enter active. Then of course the same for the leave phase of custom leave active. So give it a save and then let's refresh or check this out on the browser. So if all works well, we should now hover over the remove image button, and see it scale in and out just like before, but this time using our custom classes.
96. Initial render transitions: When our app loads for the first time, the card appears in with no styling. When we switch between the components, we've added this fade effects. It will be nice too, if we could also fade the card in when the app loads up too. To do this Vue.js provides us with the appear attribute. We can simply add this attributes inside of the transition elements. I'm going to go over to the ''App.vue'' where this transition is located. It uses fade transition here surrounding the kept alive components. We can add this as a attribute, just like the name and also the mode. Just add "appear" and then give that a ''save''. Now if we go down to the fade class inside of the CSS. When using appear, the transition it applies is taken from the CSS, which we've already setup for entering and also leaving. Since you have the opacity fade-in, this is the effect used when appearing. We can see this in action. If we change one of the durations to three seconds. I'm going to do this on the appear class. So ''fade-enter-active''. Rather than 0.5 seconds, I'm going to change this to three seconds then ''save''. Now if we reload the browser, the initial loading takes longer to fade-in. Change that back to 0.5 seconds, ''refresh''. Now we can see it's a lot faster. However, if we wanted, we don't have to automatically use this existing fade class. We can override this with a custom class name. Just like we looked at in the last video. We can use the same names, but with the appear prefix, such as ''appearActiveClass'', to back up to the transition. I'm going to set up a custom name. So ''appearActiveClass''. Then we can add our custom name, 'custom-appear-active-class''. Now this is setup, we can now go down to the CSS. In fact, I'll just copy this custom name. Then down to the CSS we can set this up. I just have to ''fade-enter-active'', paste this in. Again want to set up the transition for the opacity. Let's set this to one second, for example. Now this one second transition will be independent and override any existing classes. Let's see this in action with ''refresh''. That looks about one second. That seems to be taking effect now. That's how we can add transitions to the initial render.
97. Element transitions & keys: The transitions we have looked at so far have only involved one single element for example, the remove image transition was a single button element. Also the text options we fade it in and out, although these had many elements nested inside, they will still a form as the main outer element. We can also transition between two separate elements too. A common need finish is when using v-if and v-else. I'm going to head back over to the first project where we can apply this too. But first I'm going to copy the scale animation from the app.vue of your file. Go down to the CSS, soften the scale, enter active. In fact, we rename this to custom, but for now let's just copy this and change this in just a moment. Now let's open up the cast list application from early on in the course. Drag the project into visual studio. Then we're going to open this up by double-clicking the index page. Let's get to work on this in the index.html file. We have an if else statement to show the names added to the list, which is just down here. Both these if statements and else section below displays a div. This if section displays the name. If any names that are available inside the guest list name array. If not, we then have a separate div just below, which says the text of no names added yet. This is perfect for switching between these two div elements. To do this, all we need to do is add our familiar transition mapper. Let's close this side bar for more space. Then just below the div with the class of card block. Let's add the transition wrapper. Let's make some space, then after the no names add adjective. We can enclose this off, just like that. Now we can add the name of scale to link this with the animation CSS we added before, so let's add name to the opening tag of scale. Then in no app.css. We can then add the CSS which you copied from all previous projects. All we need to do is replace custom with the scale name or for the enter active and also for the leave active so save that. Now we've opened up this index page in the browser and then refresh. We can add a name to the guest list and then submit. We can see that the name is added just like before. We can't see any of these scaling in effect. This clearly doesn't work. The reason why it doesn't work is because we're switching between two div elements with the same if else block. The problem will always arise when both elements are the same. If they are div tags or any of the elements. To fix this, we need other key to each elements, so view JS can distinguish between them. Let's go back over to the app. Then inside the v-if block, I'm going to add a key and we're going to call this names. Then in the second block for the else statement, most won't add a second key with our name of list empty. This can be any name you want, so give that a save. Now if we go back over to the browser and then reload, let's add a name to the list and enter. Now we can see we've got the scale in transition. It looks a little strange because we're transitioning the fold div rather than just a name. But we can clearly see it's now working. Remember if we're transitioning between two elements which are not the same, such as AP elements and a div, we'll not need to add this key. If we add more names, you can see the transition does not apply after the first name. Transition with lists works a little differently, and we'll look at how to do this next.
98. Group transitions: In the last video, we mentioned adding transitions to a list, such as how we do here with the v for loop, works a little differently. Let's begin by moving the transition to surround only v for loop. Let's cut the opening transition tag. Then I'm going to add this just after the v if statements, by starting there and then the closing transition tag but also cut this out, and then paste this just after the block for the for loop. [inaudible] and let's open this up inside the browser and refresh. Let's try this out. Let's start by adding some names. Let's add a second one. We can see that only the first name which we added has appeared on the Guest List. This looks a little strange. Let's open up the console and see what's going on. Right-click and go to Inspect. Let's refresh and open up the console, so let's add a name and answer. You can see there's no error there. Let's try adding a second name. Now we see a red error. Opinions are the console. Let's open this up. The error message gives us a clue on how we can fix this. He says the transition can only be used on a single elements. We need to use transition group for lists. Let's give it a go. Let's change the transition to be transition group. Let's try to scan in the browser. The first one appears, and then the second one also appears, and we don't see any error messages inside the console. There is a difference when using transition group. It will render a surrounding span element to our list. We can see this if we open up the dev tools again and inspect the name elements. Click on the Inspector, and then go over the name elements. Select any one of these. The first one is fine. Let's make a little bit more space. Now if we look at the code inside the dev tools, these are three names of A, B, C, which you just added, and also have the span ta, which is surrounding all these three names. We know we didn't put this into the code because we can't see it here. When using the normal transition elements, this does not render an element. We do need to be aware of this when using transition group. We do though have control over which element it does use. We're not restricted to only using neat span elements. The element type can be changed by adding a tag attributes, and this is done inside the opening transition group tag. Just after the name, I'm also going to add the tag elements. Let's add a p tag for example. This will change the span to be a p elements. Back open adapt tools. Let's give this a go. Let's refresh, and then we need to add a name. Let's add name into there, click the 'Inspector' and select our name. There I've name just there Chris, and now have a surrounding p tag rather than the span. I'm going to remove this tag attribute as span, is not messing up our CSS or layout, so it's okay to leave in there. I just wanted to show you how to do this in case you run into any problems. The last thing you may have already spotted is the first time we add to the list, the name is not animated. Let's just close the dev tools. Let's add our first name, and you can see it jumps straight in without any smooth animations. This problem lies within our if condition. The transition only applies if the names right is greater than zero rather than equal to. To fix this, we can refactor our code and make it known work, but more compact to. First let's copy this full opening div with if condition, then I want to delete it. Also removing the closing div. Now this else section, we want to remove this and paste in the if statements that we just copied from before. We don't need the key anymore, so we can remove this. All I want to do is to replace the greater than symbol with the equals. This will make the no names added text still appear when the Names array is zero. Then anything else will include the names in the div above. Now hopefully we can save this and should now work. Give it a refresh, and let's see this in action. Add a first name, and now we can see the transition, our second name, and so on. This is all working fine. If we go back to the start, we can see our no names text is still added when there is no names inside the array, then it's replaced by any names which will add with animations, all my working.
99. V-move class & dynamic transition names: If you remember earlier on in the course, when we created the Guest List app. We set it up, so the names added are arranged alphabetically. If I add a, b, and then c. Then if we add a again, we can see this is placed at the beginning and all the rest move across to make way, rather than these names just jumping out the way. This moving of the elements can also be animated too using a v-move class. V move works like transition classes we've already looked at. We replace the v with the name which you want to add in the transition group. Inside of our app, we already have a name of scale. This will create a class name of scale move, which we can use in a CSS file. So let's go over to the app,.CSS. I'm going to add this now. Then add this just above the key frames. So scale-move. Then I want to add a transition, set the transform over 1 second. So with a new class, we're free to add any transition we want. I'm just going to transition the move of 1 second to make the move a little smoother. Let's see how this is looking in the browser. So let's add a, b, and then c. Now if I add a in again, we see a nice smooth effects for the b. Now moving out of the way. So this now looks a lot better. We now have this smooth transition when new items are added. One last thing before we wrap this video up is the name attributes we added to the transition can also be dynamic. We can use either v bind, like we had to do in the past, or we can also use the shorter and the colon to bide the state's property inside the openings tag. Let's add a colon to make this dynamic. Then we can set this up as a data property to change it's name. So rather than scale, if we would call this the effect1, for example. We can then set it up as a data property. Let's go over to the app.js, and we can add this inside of our data. So within the opening and closing data tags, I'm going to add these on the event capacity percentage. The name was effect1. We can add our name of scale back inside here. So this is just a basic example used in our scale transition name. To use the existing CSS. We could settle multiple transitions inside the CSS file and apply these based on the name of the data property. For example, we could have a checkbox or select input to allow the user to change the transition type. So hit save, and let's refresh inside the browser and check our scale transition still works. Everything's still seems to be working correctly there. Also, this binding will also work on over attributes too, such as JavaScript hooks. So we could go back to our transition group inside the index page. We could do something such as before-enter, set this to be a value or colon enter, and do the same just here. This makes all these hooks and transitions really flexible. Although we've only added relatively simple transitions and animations to this app, they can make a big difference in the end by making our app look a lot more polished and complete.
100. Section outro: Transitions & Animations: Congratulations on getting to the end of this section. I hope you've enjoyed learning all about how we can add transitions and animations to our projects. Hopefully can now see that even just by adding some small effects to our apps, it can really finish them off and make them look and feel a lot nicer for the user. This is another great feature of the Vue.js framework and I hope you've really enjoyed this section.
101. Thank you: Congratulations on reaching the end of this course. By now, you should be feeling a lot more confident of building applications using vue.js. We have covered a lot so far including, learning how to install vue and to how to use the vue Instance along with all the properties we can add to this Instance, such as data, computed, methods and filters. During building these projects, we've also looked at list and conditional rendering, two-way data binding, and also directives which vue.js providers us, to name a few. We then dive a little deeper by setting up a better workflow by using modern build tools such as the vue-cli, where, pack and also bubble. This allows us to take a step towards building larger, more maintainable apps by split up our code into components, a passing data using various methods. Thank you for taking this course and bye for now.
102. Follow me on Skillshare!: A huge congratulations from me for reaching the end of this class. I hope you've really enjoyed it and gained some knowledge from it. If you've enjoyed this class, make sure you check out the rest of my classes here on Skillshare, and also follow me for any updates and also to be informed of any new classes as they become available. Thank you once again, good luck, and hopefully, I'll see you again in the future class.