Vue.js Course for Beginners [2021 Tutorial]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Gwendolyn Farraday previously created one of  the most popular Vue courses on the internet.   Now she's back with an all new full Vue course to  teach the latest version to absolute beginners.   Hi, everyone. My name is Gwendolyn  Faraday and I will be your instructor   for this course. I have been a professional  software developer for over five years now.   And I've had the opportunity to work in several  different languages and frameworks over the years,   including Angular react, and Vue js. I  currently work as a software consultant   in various technologies, and use Vue js as my  preferred front end framework for any type of   web or mobile application. If you would  like to reach out to me, you can find me   anywhere online at Faraday Academy. If you  have any specific feedback for this course,   please email me at gwenf@protonmail.com.  I hope you enjoy this course.   Vue js is a JavaScript framework for building  applications and websites. How does it help you?   It provides tools out of the box to help you make  your websites and apps faster and more dynamic.   And it also gives you a set of standards for code  organization and expectations for individuals and   teams that work in the same code base. If  you have heard of the virtual Dom before,   Vue js is a virtual Dom framework. If you don't  know what that is, it's okay. It's not important   for understanding this course. The virtual Dom  basically makes JavaScript web applications   a little bit faster and more efficient  Vue by itself is extremely lightweight,   you can get it down to about eight or 10 kilobytes  g zipped. Although in a practical sense, your Vue   and bundled JavaScript will probably never be that  small in an application anyway. Although it is   good to know that Vue doesn't have a lot of extra  code taking up more space in your application.   Why does Vue JS call itself a progressive  framework, they use the term progressive   to mean that you can use it anywhere from  small features on websites where you want to   add some interactivity and using it as  kind of a drop in replacement for jQuery   and legacy applications. All the way up to using  it as a more full featured batteries included   framework for large scale applications like  Gmail or Twitter or something like that.   You get to decide what features you want to add  in from the Vue ecosystem beyond the core library,   and it's extremely flexible to allow you to  choose the tools and other libraries you want   on your own. Or you can use the ones that  Vue provides in its ecosystem by default,   many people and companies are using it for its  incrementally adoptable nature. That means that   if they have a legacy application, it's quite  simple to update their application page by page   to turn it into a Vue application into a more  modern application, instead of having to rewrite   the whole app at once. That is one very convenient  thing about Vue j s. Let's look at a really quick   overVue of the history of Vue. The Vue project was  started in 2013 by its founder, Evan you. In 2014.   version one launched and started to become popular  in China where revenue is from a few years later,   Vue two was launched with many new updates  and improvements over Vue version one. And   with the release of version two is really where  we start to see the massive growth of Vue j s and   popularity in the rest of the world. So many  developers had not heard of uJs before 2017.   But from 2017, and especially in 2018 and  2019 Vue really solidified itself as one of   the top three JavaScript frameworks. Many Vue  conferences started popping up lots of content   creation around the Vue ecosystem started to  take place. And many companies started to use Vue   for their applications as well. In fact,  many companies that do you recognize,   which are household names in the West, use Vue, j  s now. And now we can see that Vue version three   has been released in fall of 2020. And along  the way, over these last six years, we see   many different libraries that are also created and  maintained by Ave and the core team of Vue. Like   the vcli Vue router in Vue x, also being regularly  updated to match with the current version of Vue.   Even now, with Vue three just released, we  see that a new version of Vue, router and VX   have also been released to be compatible with  Vue version three. In this course, we will be   using the Vue j s core library as well as the  vcli. For more information on Vue, x Vue router,   Vue test utils and some of the other tools in the  Vue ecosystem that I don't cover in depth in this   course, I will be making future courses about  those on my Faraday Academy YouTube channel.   So let's get started with learning v j,  s. And keep in mind, I'm using v3 here.   So make sure you are at the correct  website, which is v3 dot Vue, J s.org.   And then click on getting started here. This will  take you to the documentation. And by default, the   introduction to Vue j s, I'm going to go straight  to the installation link on the sidebar here.   And if I scroll down, I can see the place where  it says CDN. And you'll notice here it says Vue   add next make sure you are importing the  right library from the right URL here at   next is necessary, because Vue three is not  in the main Vue j s repository yet it's in   this other repository that you can reference  with that next, which points to Vue three,   until the whole ecosystem and everything finishes  getting updated. There is going to be a difference   between importing Vue to an importing Vue  at next, which points to Vue version three.   And I'm going to go ahead and grab this script  tag here. So I'm in VS code, and I just have   a basic HTML file. And I'll be adding Vue  j s into this application to demonstrate   the basics of Vue syntax before I get into  building a larger application with the Vue COI.   So first of all, I'm going to be using VS code  plug in called live server. And you can see at   the bottom here it says go live. So if you go to  plugins, which is this four box icon on the side,   you can type in live server and click on this plug  in. And you can install it if you do not already   have it installed. But I already have it installed  and enabled. So I'm going to go back to my code   over here. And at the bottom, I'll just click go  live. And you can see it shows my HTML page, I'll   just zoom in a little bit here with the static  content. Now if you don't want to use live server,   you can just come here and right click and click  on copy path. And then you can go to your browser   and paste that absolute path to the project  or to your index dot HTML file. And it will   display the same way in the browser. live server  just makes things a bit easier because it will   automatically refresh when you make code changes.  And it also opens up the browser page for you.   But it's up to you if you want to use it or not.  So now I want to add Vue to this application.   So I'm going to go inside of the  body tag and just below this div,   just paste in the script tag that I just copied.  So now this is all that I have to do to import   Vue and start using it in my application. I  don't actually need Babel or anything else   to get started. So to write my own custom code,  I'm going to add my own script tag right below   that. So there's basically two things that I  need to do here. And the first is to use this   Vue variable that I have access to from importing  Vue. And that script tag and Vue gives me this   method called create app. And that basically  creates my Vue application. And I can pass it   an options object, which I'll get to in a second.  Now I need to somehow connect this JavaScript for   my Vue application with the HTML that I'm going to  be displaying in the browser. And that is through   another method that I can actually chain on to  this Vue instance I'm creating. So I'm actually   going to save this as a variable. I'm going  to say let app equals Vue create app. And then   I'm going to use this other method called  Mount because I want to tell it to mount my   Vue application somewhere in my HTML here.  So I'll do ID equals, I'll just call it app.   And I'm actually going to tell it to mount  to my Vue j s application inside of that div.   And that means that the Vue j s instance that I'm  creating here will be able to connect and display   data and interact with any kind of DOM element  inside of this div here. So that will be more   clear in a second. So now let me change this,  let me create a variable on my Vue instance.   And to do this, I need to create a function called  data here. Now this whole object here is called   the options object. So any variables or functions  that I'm going to use in my application will live   on this object here. So specifically with data  that is a function, and it needs to return an   object. And on this object that is returned by  the data function, I can put whatever variables I   want. So I'm going to create a greeting variable.  And I'm basically going to say hello, v3,   then exclamation point. And now I  can actually go into my div here,   delete that static code there. And I'm going to  use my variable now. So to use a variable in Vue,   you use this double curly brace syntax, it's  called double mustache syntax, which is kind of   hard to pronounce. So you can just call it double  curly braces. It's a common syntax in templating   languages. And it basically means that anything  found in between these sets of double curly braces   will be parsed as JavaScript by Vue. So Vue is  first going to look inside of this data object   that we're returning, and see if there is  a variable named greeting, and then it is   going to display that variable or the value  of that variable inside of these curly braces.   And you can see that now it displays the  greeting variable from our Vue instance.   Let's talk about Vue j. s directives. They are  basically a way to connect elements in our HTML   or template here with the Vue j. s JavaScript. And  let's see what that looks like through an example.   I'm going to create an input here.  In the browser, it looks like this.   Now, what if I want to get the value out of this  input Vue has a built in way to do that through a   directive called v model. Now, these directives in  Vue are used just like an HTML attribute, but they   are prepended with v dash to differentiate them  from regular HTML attributes. And Vue when it is   parsing this Vue application will see this keyword  v model, and will bind it to whatever variable we   pass in as an argument to the model here. So  here inside quotes, I need to put a variable   name. And I'm actually going to put the variable  greeting here. And let's see what that does.   So you can see now in my input, it actually starts  off with the text Hello Vue. And as I change it,   it also changes the greeting variable that is  displayed on the page. This is called two way   data binding and is handled in Vue with that V  model directive. Let's look at another directive.   I'm going to create an HR here. And I'll make  a div with a class of box. And I'm going to   use another directive here called v if, which also  takes an argument, which will be another variable.   So I'm going to set an is visible variable  which I have to create. So let me do is visible   and set this to true to start, I am going to  paste in some styling that I made. This is just   to style the box so you can see it on the page.  Awful that you can see that I do see that box,   because this V if directive is basically just  like an if statement in JavaScript. So if this   value is truthy, then this element will be  displayed on the page. But if it's false,   this div will not be rendered to the DOM at  all. So let me change this variable to false.   And you can see the box disappears. And if I  check, I can inspect element. And there is no div   found in the DOM. Now v If is very similar  to V show, which is another vj s directive,   it takes the same kind of argument a Boolean  expression. And let me set this to true again,   you can see if it's true, it  shows on the page, just like v if.   However, when it's false, you can see there's  still a div, render to the DOM. The only   difference is the style is set to display none.  So you won't actually see it, but it is there in   the DOM. So when would you use v show? Well, in  most cases, you would just use v if, because you   either want something to render or not. Like if  you have a loading spinner, you would use V, if   it's loading show the spinner. And then  when the page or whatever has loaded,   you would set the variable to false and then  v if would remove it from the DOM. Now v   show is useful for specific cases, when you might  need to toggle something more frequently. And it   would be more performant than adding and removing  it to the DOM constantly. So it's already there,   all you're doing is changing the CSS. So you're  changing it from display none to display block.   So changing this back to Vf. There are other  directives that you can chain on to Vf. There's v,   elsif, and V else. And you can already guess what  these do. So I'm just going to show you the syntax   here. So v else if and V else is the one that  doesn't take any argument. And I'm just going to   demonstrate these really quickly. I'll add another  variable here. So it's visible is visible to.   So I've added a little bit more CSS here to  differentiate between the three boxes that   I've created here. And this works as a regular if  else statement. So if is visible is true, this div   will be rendered. If it's not true, it's going  to keep going down the chain. So it will look at   any v else ifs you have here, you can have as many  as you want. So then it will look at is visible to   to see if that is true. If that's not true, then  it will automatically display this third box.   Now the third box is blue, the second  box is red, and the first box is purple.   So you can see the blue box displayed  because the other two values were false.   Likewise, I could change one of these  variables to true. And then that box   would be rendered in the DOM here. Now I want to  point something out here, if I refresh the page,   you can see for a split second, you  actually saw all of the boxes render,   as well as the curly braces show up on the screen  here before it was parsed as a Vue variable. I'm   going to refresh the page again and slow it down  a little bit, just in case you couldn't see that.   So how do I prevent that from happening? Vue has  something called v cloak, which is a convenient   utility that will hide anything from rendering  until the whole Vue application is ready.   So I'm going to add a V cloak here. And then I  basically need to add a style for it. So you can   see, I'm setting v cloak or this V cloak attribute  to display none. This is the recommended pattern   in Vue js. And then I just add a V cloak to my  div with my app in it. Now if I go back here   and refresh, you no longer see the curly braces  or the other boxes render. How does that happen?   I'm going to go to inspect element. And you  can see on the div with ID app here, there   is no v cloak attribute. But if I refresh the  page, you can't really see it because it's too   fast. But basically, that V cloak attribute  remains on this div until the app is loaded,   and then it's removed. Once everything is rendered  to the DOM. I don't often run into cases where I   have to manually use this, but it is a nice  feature to know about if you run into that   issue. These were just a few basic directives. We  will definitely be covering more directives as we   go along in this course. In the next video,  we will go over events and methods in Vue js.   Now that you've seen how to use variables and  directives in Vue, j s, let's make this code a   little bit more interactive with a So you probably  already know that there are many events that   can be captured in the browser and used in our  applications. For example, when the user clicks   on an element on the screen, like a button, or if  the user presses a certain key on the keyboard,   like Enter to submit a form, let's try out both of  these cases in our little mini application here.   First, going to get rid of the two extra  boxes. And I'm going to add a button here.   Which for right now, I will label as showbox.  So right now, this V if is set to false or the   variable is visible set to false. So this div will  never be rendered on page unless we somehow update   that variable. Before we were hard coding the  variable value here as true or false. But we can   actually use this button to change the variable  value as well. And this is done with another   directive called v dash on. Now, the v dash on  directive is specific for events. You can use it   for custom events that you create yourself. Or you  can use it for any of the standard browser events,   like, as I mentioned before, when a user  clicks or presses a key on their keyboard.   So here's specifically, I'm going to do v on  colon, and then the type of event which will   be a click event. So I'm listening for  a click event on this button right now.   But now when someone clicks on the button, I have  to tell you what to do with that click event. So I   need to pass in an argument of whatever JavaScript  I want to run when this button is clicked.   And for right now, I will keep it simple. And  I'm going to set the is visible variable to true   when that button is clicked. Now you  can see I have this button show box.   When it's clicked, the box shows what if I want  to hide the box. Right now, this only shows the   box. And the only way to get rid of it is by  refreshing. I can set up a toggle for the box,   by simply saying is visible equals the  opposite of whatever it currently is. So   is visible equals not as visible. So if it's  true, it will be set to false. If it's false,   it will be set to true. And this should  toggle our box, we label this to toggle box.   And now, if I keep clicking toggles on and off,  that is basically how events work. There's also   a shorthand for creating events. So you don't have  to type out the dash on colon, you can just type   the app symbol, and then the event name. And this  is exactly the same thing as it was when I typed v   dash on colon. the at symbol just replaces all  of that. So what if you wanted to do something   more complex in here not just setting a variable  to True or false? Well, you can actually use this   to pass in any kind of method on your VJs object.  So I'm going to get rid of is visible here.   And I'm going to create a method called toggle  box. And now I have to create this toggle box   method. You can see I already have data on my vj s  object, this data function. But now I need to make   another key, which is called methods and  methods is an object of functions. I can   put as many functions as I want on this methods  object to be able to use these in my Vue, j s   application. So let me create that toggle  box function. I could do the same thing here   as I did above, but I'm just going to use the  function shorthand and I want the same logic   again but inside this function, so in order  to refer to this is visible variable here,   I have to get it off of the this context. And  Vue j s handles putting all of my methods and   variables on the this context so that they're  available to me anywhere in my Vue application.   So I can do this.is visible and then set it equal  to not this.is visible This is not function there.   And this should work the same way as it did  before. So I can test it out and toggle the box   once again. So that is the basics of how methods  work. And you can see because I have called my   method toggle box That it is also available  to me anywhere inside my Vue JS template here.   So let's look at one more type of event.  And that will be an event listening for   keyboard input. So here I want to listen for key  presses. This is also an event. So I'm going to   start with the Add symbol. And listen for a key up  event. I could also use key down if I wanted to.   So for keyboard events, I need to add a modifier  to say which keyboard input I am listening for. So   for input here, I want to run a function or some  JavaScript, whenever I press the enter key. So for   enter, I actually have a shorthand because this is  a common keyboard input. So I can say, Listen for   the key up event specifically with the enter key.  Or I can always use the key code associated with   any key on the keyboard. So for enter, that  would be 13. It doesn't matter which one I use,   I'm just going to go ahead and use key up dot  enter, because it's a bit more obvious what it is.   And then it's the same syntax here. And I'm going  to create a greet method for this key up event.   So let me go down to my methods, create a method  called greet. Use the method shorthand. And I'm   actually just going to console dot log, this dot  greeting. And let's see how that works. So I can   just focus this input anywhere and just hit enter,  it doesn't matter what's already in the input.   And you can see it logs out the  greeting. If I change the input,   it logs out whatever the greeting variable  is currently set to. Now what if I want to   pass something into a function as I'm calling it  into one of these methods, then I could do that,   just by adding the parentheses to call the  function. So for example, greet here, I can   just pass something in. So just for demonstration  purposes, I'm going to pass in the greeting   through the template here. I'm going to accept  that here. And I'll still call it greeting. And   then get rid of this because I'm no longer looking  for the greeting variable. On the vj s instance   here, I am actually just going to be using the  greeting variable that I am passing in here.   And just to show you that it's different, I can  use the greeting variable and then pass it in with   some exclamation points appended to it. And  now when I go here, and I click Enter again,   you can see that it is the greeting variable  that I passed in through the template. If I   erase a few characters here, hit ENTER again,  you can see it's still the same variable set   to the new value. Those are the basics of  how to use events and methods in Vue js.   I do want to point out here, you see this dot  enter, that is an event modifier in Vue js. So   you're not only listening to the key up event  you're listening to specifically the enter key.   Now there are many modifiers that you can use. For  example, at this click event here, for example,   I get I have a modifier here that says I'm  only listening for right clicks. So a normal   left click on a mouse will not trigger this  toggle box. But only if you make a right click,   I can also use some handy modifiers like  prevent. So if I don't want a form to submit   instead of using the regular event dot prevent  default in my method, I can just add this modifier   here dot prevent. And I can do that for stop  propagation as well. So I could add that stop.   You can chain as many of these modifiers as  you want in Vue j s, there are definitely a   handy thing to know about when you're building  Vue applications. That's all for this video,   we will be diving deeper into events and methods  later on in this course and in future courses.   In the next video, we're going to talk  about custom components in Vue js.   Let's talk about Vue components. Now when  we created our Vue application here, we are   basically just using one standard component, you  could call it just a default options object for   use in our template. So now we're going to work on  breaking up parts of our application into separate   components in order to prepare for learning how to  build larger applications and work on applications   with the Vue COI outside of a single HTML  file. Let's take a break from the code for a   second and take a look At what we are going to be  building with Vue components, we're going to use   a simple example of a form to work on breaking  up an application into separate components.   Now, where you see the red outline, those  are each going to be a separate component.   So the outer red outline around the whole login  form will be its own login form component.   And then each input with its label will be a  custom input component that we are going to create   and be able to reuse for as many inputs as we  have. So we're going to start off with this outer   component, and then break out the inner components  into their own components after that. And then   we are going to look at how you can pass data  around between components in your application.   So what would a Vue component look like?  Let's say we wanted to have a form in here.   And I'm gonna get rid of this greeting really  quick. And put a form here. So I could do this   directly in the HTML and create a form tag. Or  I can create a custom tag as a Vue component   called custom form. Now, this is the same  syntax as if it were an HTML tag. Except,   of course, it is not a standard HTML tag. So I  have to define it as a Vue component down here.   And I need to define it after I define my  app variable, which is my Vue instance.   And before I actually mount it to the  DOM, so I can chain this here as app dot   component. This is a function and it takes  two arguments here that I'm going to pass in.   So the first one is the name of the component  that I'm going to use. And that is the name that   I'm going to be using in my HTML up there.  So I'll give it the same name custom form.   And the second is an options object. And since  this is his own self contained component, I can   actually use any of the same options that I've  been using here, such as data and methods, etc.   The only extra thing that I need right now is  I have to define a template for this component.   And the easiest way to define a template is  by using graves. So I can make this multi line   and pass in the HTML here. So real quick, I'm  going to create a div. And I'm just going to put,   let's say, two inputs in here for right now, but a  type of email, and then an input type of password.   And let's call this a login form. Since we're  doing email and password, I'll change that up   here to login form. And since template is the only  required option that I need to pass in on this   object, it should run like it is right now. So  let me see if this works. I'm gonna go to go live.   And you can see these two form inputs up at the  top here, completely unstyled, just basic browser   inputs. So I'm going to style these inputs  really quickly, so they're easier to see.   After all of these boxes, I'm going to add  a reference to input here. I'm going to say   margin of 10 pixels just on all sides, and  display of block so they don't go in line. And   now they are a bit easier to see here.  Alright, let me code for the styles again.   And now let me add a data method to this  component. So you can see what that looks like.   So after this template key I have here, I'm going  to do the same thing I did above. With data,   I'll just use the function shorthand here, return  an object. And here I'm going to give it a title.   And the title will be login form. And now  I need to do something with this title.   So up here when I defined variables, I use them  inside of my app template here. But since my   login form is a self contained component, any  variables I define on data here, I am going   to have to use them inside its own template. So  I'll just add another line here and give it an h1   and by the way, This doesn't  have syntax highlighting,   and isn't kind of a weird template form. Because  I'm just doing this all in one HTML file.   This is just a stepping stone to get to more  standard ways of creating Vue components   where you will have syntax highlighting, and auto  completion and all of those other great features.   So here, I need to use that variable title.  So I'll use that the same way I did before   by referencing it. And now I should see the title  on top of those two input boxes. And indeed,   I do here I am, zoomed in quite a bit. So that is  a basics of how you can create a component here,   I'm going to go ahead and keep building out  this form, and then also show you how to   compose components now. So I'm just going to  change this really quickly to form. And then   I'm going to add some submit functionality here.  So I'm going to add an event for submit, submit,   and then pass in an argument with the method  I want to run or the function I want to run   when I submit a form. So I'm just going to  call my function, I suppose handle Submit.   And then I need to make a methods object down here  with that function. I'll call it a handle, submit.   And I will just console dot log  submitted. So now when the form submits,   it will run this function, there's a few  more things that I need to do, I need to   add a button here, that will actually submit  the form. So by default buttons are type submit,   so I don't need to add that here. But I  am going to add some text to the button.   Now when the form submits it refreshes the whole  page. Of course, this is the default behavior in   browsers. So you can just automatically click  and send data from the form to your back end.   But since we are going to be handling the form  submission from our handle submit function,   we don't want this default behavior with  the page refresh. So like we saw earlier,   we have event modifiers. So we can do prevent,  to prevent default, this would be the same thing   as passing in an event object to our handle submit  function, and then doing e dot prevent default.   Again, this is just a shorthand. So  now if we look at our console, here,   we see that it logs submitted when we submit the  form. So now, we probably want to be capturing   these inputs. So we can do that. Again, by using  the directive v model to bind to the value of the   form input to a variable, we'll call this one  email. And we'll v model this one as password.   And then add these into data. And now let's  log those out. So let's log out email. And   password. Of course, if you remember, I have  to get it off of the this context, since I'm   referencing it inside of JavaScript here. And  now I should be able to type in something here,   this has to be an email. So  I'll say gwen@example.com.   Just any password, and I'll click  Login. And you can see it did log out my   credentials here. Okay, so that's one  component. In the next video, let's look   at how to break up this component and take out  the inputs to put them in separate components,   as you saw in the markups earlier in this video.  And we'll also look at how to pass data between   components. So from a parent component to a child,  and then also from a child backup to the parent.   So what if we want to compose multiple components  together? Let's demonstrate this by removing the   inputs and creating a custom component just for  our form inputs. Let's say we want some logic just   contained within a special input component. So let  me fold this real quick. And I'm going to create   another component here. I'll do app dot component  again. And I'm going to call this custom input   passing in options. object. Again,  I need to have a template here.   And in this one, I'm just  going to have Label Label   when a display a label variable here, and  then I'll have that wrap around the input.   And I'll use a type, just the default text  for right now we'll change that in a second.   And that is a default input.   So now where am I going to use this component,  so I'm actually going to replace my input fields   in this component with this new one that I  created. So what I can do here is Call this Custom   input, and custom input. And I can use my  components inside of this other component.   Now there's one more step that I have to take  here. And that is registering the component.   So I have to let my login form component  know about the other custom component.   And I can do that here by creating components  array, and then just give it the string of   the component that I want to be using, which is  custom input. Now let's see how this works. Okay,   so I have these two inputs. Now it is giving me  this warning, that property label was accessed   during render, but it's not defined on the  instance. This is happening, because here,   I'm referencing this variable label, but it is not  defined anywhere. So it's giving me that warning.   Now I could define data function here and  create the variable on this component.   But I want to demonstrate passing data from one  component to another. So instead of defining it   on this component, I'm actually going to define  label on the parent component and pass it to the   custom input component. To do that, I'm going  to come here and add just a label, let me add   in, we call it email label for right  now. And I'm going to call it email.   And I'll also have a password, label and call this   password. Now I have to get these two variables  passed into these custom components here.   And so what I'm going to do here, I can go ahead  and get rid of the V model for just a second. And   I'm going to add a label here that I'm going  to pass in. And I'm going to pass in the email   label. Now this looks just like an HTML attribute.  But I'm actually going to add a modifier on here.   That is a Vue directive called v bind. What v bind  does is basically turn this regular HTML attribute   into something that can be parsed as JavaScript  so that I can pass down a variable to the child   component. So I'm v binding this label, which is  email label, which refers to this string here,   which is email, this will get passed down as a  property to the child component called label.   And now in this custom input child component, I  need to receive that property to accept it here   with a props object. And the simplest way to  write props is to make an array of strings,   just like I did for custom components. And these  props are basically just a list of all of the   names of the information that I'm passing down  from the parent to this child. So now, because   I'm defining label in props, I will have access  to use the label variable here inside my template.   Now if you look at the login form,  you can see that the email field,   it has a label here, and you can tell it to  label because when I click on the word email,   it focuses on the field it's related to.  So let me give a label the password now to   I'm going to pass in password here. By the way  v bind, there is also a shortcut for V bind.   This is one of the most common directives  in all Vue applications. So the shortcut is   instead of using v bind colon, you just use  colon and then label. So let me pass a label in   here as well. So I'll pass a label in As password  label, since we're using this reusable component,   the label will always display as the label  that we pass in. And now you can see that   both form fields are properly labeled here. Now  I want to point one thing out really quickly.   And that is for email and these password  labels, you could not make variables for   these and just pass them in as strings here.  So for example, if I get rid of the bind   of the colon, shortcut there, then I could  just pass in, let's say, password. And   let me put enter email here. So it's different.  And now I can just pass in this text as a string.   Because there's no more v bind here, Vue is  no longer looking for a variable. So now in   the application, you can see that it's just  passing the string down as a label to the   child component and displaying that string, I'm  going to do those changes. When you're working in   actual Vue applications, you will see that 95%  of the time, you want to pass a variable in when   you're passing a prop down to a child component,  either a data variable or some kind of a function.   So you'll almost always be using this V  bind syntax here. Now there's one issue   because in the child component, we have the  input down here, we're not actually listening   for changes to the text in the input, we're not  v modeling that to any variable, so we don't   have access to whatever is inside the input.  So we actually need to create a V model here   in the child, I'm going to save the model.  And just temporarily here, I want to map this   to a variable in the child. And I'm going to could  just call this input value. And I need to create   data function here, return an object with input  value as an empty string. So now in this case,   you're already familiar with the model. And you  know that anytime we type a character into this   input, it's going to update this variable and  this variable, and the input will stay in sync.   But now how can I get the value of this  variable up to the parent component here,   because I actually want it to stay in sync with  these two variables on the parent component.   So that way, when I submit my form, I can have  access to it in this handle submit function.   So there are actually a couple different  ways of doing this. I'm going to show you   the most straightforward approach for getting  started with this. And then in future courses,   I'm going to explain a little bit more in depth  about how you can use custom events and other   methods of capturing the value of a variable from  the child to the parent. So to get started, here,   I'm going to use my same input variable.  But I'm going to use a new object here.   And this object is called computed. I'm  going to comment out data for a second.   So computed is an object where you can put  variable names in here as keys. So for example,   this input value variable that I want to  create, I can put it in here as a key.   And whenever this value changes, I can actually  get it to run getter and setter functions. So   I can create a getter function, and then  a setter. So when I get the variable   value here, it will run this function. And  then when I go to set the variable value,   it will run the set function. So now what value  do I want to put in my getter here, I want to   get that value from the parent component. So  I'm actually going to use these two variables   that I already have here. And I'm just going to  get rid of these types. I'm not using them yet. So   get rid of those. And I'm actually going to  do something different. I'm going to create   v model directly on my custom component here. And  I'll show you why in a second. And I want to model   this to the variable that I'm going to be using.  So for this one, that is the password variable.   And for this one, that's email And these got out  of order. So I'll switch them around. Okay, so now   I'm be modeling the email and password. And now I  want to get these variables in my child component   here. Now, how do I do that. So in props, I can  actually accept a prop called model value. And   this comes from the parent. Now it doesn't really  look like we are passing in another Prop, because   we're not v binding any variable and passing it to  the child. But actually, what v modeling does on   a child component is actually under the hood,  it's giving us another prop called model value,   which is mapped to email. So v model does a few  steps all at once, it's kind of a shorthand here.   So I have access to this model value prop because  I'm using the model. So I can accept that prop   in the child here v model. And then in my getter  function, I can do this dot model value. And I can   return that. So now whenever I get the value for  this input, it should be the same as the value in   the parent component. And I can check that by just  typing in some values here. And you can see that   the inputs are pre populated with the value from  the parent component. Because I am v modeling this   input to a getter function that I'm setting here  and saying that the value will be this dot model   value, which comes from the V model variable in  the parent component, which are these variables.   So now, how do we handle setting the value if  we type text into this input here, so we need to   capture the value first and Vue passes this in  via a parameter. So we can give this parameter   any name that we want, I'm just going to call it  value. And I'm just going to first log out this   value. And so here, I can try typing in. And you  can see it's logging out the value of the input   from that log in the setter function. But  now it's not setting a variable anywhere.   So let me go ahead and set the variable. Now to  do that, I'm going to use a new method that you   haven't seen yet. And that is this dot dollar  sign emit. What emit does is allow me to emit   events that other components can listen to. And I  can pass data around by Vue application like that.   I can emit events that are built in like I could  emit some kind of on click event or something like   that. Or I can emit a custom event that I create.  For right now I'm going to use an event that   Vue gives me and this is called an update event.  This syntax is actually new, slightly updated   in Vue three. So if you see older tutorials,  and might not be using this exact same syntax,   it will probably be using an input event here  instead. But I'm going to pass in a value here.   Oops, I need a comma. So this  first argument is the type of event   that I'm emitting. And the second argument is  the value that I'm passing through that event,   which is this value that I'm getting  from the input via the set function.   Now, how can I listen for an  event in another component?   I could set this manually. But like I said  before, V model is a shorthand. So v model   is actually listening for this update event from  my child. And whenever this update event emits,   this V model from the parent component is  updating the value of the variable for us.   Let's test this out. I'm going to start typing  here, typing here. And I'm going to press login.   And you can see that it logs out the  values of the email and password. So this   isn't that clear. So let me put a real email here,  or real fake email anyway. And you can see there's   the email and there's a password, which are  coming from this log statement in handle Submit.   Now, you might be wondering, why do we have to  go through all that trouble to model a variable   from a child to a parent. And the reason why  is because the props that we pass to children,   they are immutable. We cannot them  in the child, these variables on   data here can only be changed in the same  component. So my custom input can't change   anything we pass in via props here. So for  example, if I tried to model this to label here,   getting all of these warnings attempting  to mutate prop label, props are read only.   So I'm gonna undo that. So that's why I had  to create this extra variable in the child   and create a getter. So I'm getting this  read only model value prop from the parent.   And then what I'm doing to update the value of  that prop is I made it emitting an event to the   parent, this update model value event. So the  parent, because I have this V model shorthand   is listening for that event. And this  component, this login form component   is actually updating these variables itself. So  I'm not actually mutating props from the child.   Now, there are definitely other ways of handling  changing props in the child component, I could   listen for changes on this input. And I could call  a method on a methods object, which could do the   same thing either amid an event, I could also pass  a function from the parent to the child, and the   child can call functions in the parent. And then  I could update variables in that way too. There   are also other state management solutions. And we  will explore all of these different options later,   I just wanted to give you an initial taste of how  this can be done in Vue js, and specifically in   Vue version three, now that the syntax has changed  a little bit. So in this video, we've gone over   custom components, composing components  together, importing them into each other,   like we are with this custom input into the login  form component. We also talked about using props,   passing data from the parent to the child, and  then being able to set data by emitting an event   that the parent can listen to and passing it a  value. In the next video, we are going to talk   about loops in Vue to simplify our syntax here  with having multiple of the same component.   Now let's talk about loops. Here, we have two of  the same component, these custom input components.   And I would like to just be able to loop through  as many of these components as I want. To do this,   I need to add an array and data here. And  this array will have all of the information   for each input here, including the variable  that I want to model to the label name.   And I'm also going to add a type. So I'm going  to create an array here called inputs. And just   to demonstrate really quickly, I'm going to add  just some strings here, like email, password.   And let's say name. So what if I wanted to  display all three of these strings inside the   template here, I'm going to come back to looping  over the form in a second. But for right now,   I'm just going to create a p tag here. And I  want to show each one of these strings inside   its own paragraph tag. So I'm going to create a  loop for these, I'm going to say V four equals,   and then I need to pass in the array here,  which is called inputs. And this will loop   over the inputs array. Now this is a four in  loop. So I'm going to have to create a variable   that I can use in the iterations. So I'm  going to say for str, short for string   in inputs, and now I have access to this  string variable each time through the loop.   And I can basically just display it in a variable  now. Right, so it is complaining that I made a   mistake in my syntax. And of course that is  because I didn't put a comma after my array.   And now you can see that these top three here are  strings that are displayed in a paragraph tag.   Of course, they are so big because I am zoomed in  so far, but they are displaying properly. And that   is basically how you use a loop in Vue js. I am  missing a prop here that I need to add. Whenever   you do a loop you have to add a key prop here and  this key has to be unique on E iteration of the   loop. Now the reasons for using this key prop are  a little bit more advanced. So I'm not going to go   in depth on it in this video. But I just want you  to understand that it is good practice for you to   use a key that will uniquely identify any elements  that you loop through in your Vue JS templates.   This can help with performance and preventing  bugs in your applications. And when you move into   programming a more structured Vue application with  Vue components in their own files, you will see   that your linter and code editor will pick up on  it if you don't have a key value here. And it will   give you a warning and ask you to add one. So we  have to have a key to give a unique reference to   each one of these paragraph tags, we're adding  into the template. Now what I can do since the   names are unique here, each string is different.  So I can v bind to key, the string variable str.   This is a really simple Vue application.  So you basically don't notice a difference   in the browser. But you can see that there  are keys attached to these elements. Now,   I want to point out though, that one more  way that you can create this unique key   every time through the loop is you can actually  get an index through each iteration of the loop.   You can get it here and then use it as your key.  And if I print out I, you can see that I is the   index of each iteration in the loop, put that  back a string. So this was just a demonstration,   of course. So I'm actually going to get rid of  this whole p tag here. And what I really want   to be putting in inputs here are objects for the  information that has to do with each input that   I want. So the first one, let me put a label  here. And I'm going to say the label is email,   I'm going to create a value here. And this was  what I'm going to V model to. And then I'll   go ahead and add a type. So let's say type is  email. And I'll do the same thing for password.   I can get rid of those now. Alright, so now my  application is broken, because I got rid of all   the data that I had been passing into these custom  inputs. And actually, I'm going to get rid of one   of these custom inputs, because now I'm going to  be looping over just one, and it will create one   for each iteration of the loop. Let me clean this  up a little bit. But these on separate lines.   And so the first thing I want to do is create a  V four here. And this V four will look through   inputs, just as I did before, I'm going to say  four inputs in inputs. And I'm actually going to   get the index here really quick as well. And  then use a key of V bind the index. So now I   can't v model email, I need to V model based off  of this input object, which is each object in this   inputs array. So I'm going to have to V model  input dot value here to model it to the value.   So I'll do input that value, the label, also,  I'm gonna have to do input dot label. And   now I do have a type. So let me rebind a type  as well. And I'm going to do input dot type.   So that's one thing that I need to  update in this child component. Now,   I'm still accepting that model value prop and the  label prop. But I also want to accept a type prop   now. And instead of doing type is text, now  I have a prop from the parent based off of   which component it is in the loop. So now I'm  going to V bind this so it can take a variable,   and I'm going to say type, which will  refer to whatever prop I've passed in.   So I'm going to come to my form here. And I'm  going to type in and I actually forgot to change   the logging here for handle Submit. So I don't  want to overcomplicate things for this example.   So what I'm going to do is just delete this and  log out this dot inputs of zero and that value   and then this dot inputs, have one and then  that value. And this should fix my problem here.   Let me just type something in. And it's  complaining that I don't have an email address,   I'm just going to type in a fake email, login.  And you can see that it has my correct login   information. So this is the basics of how  to handle loops in Vue j s, is you can use   V for either on regular HTML elements like an h1  or any custom components that you make as well.   This is very commonly done with card components.  If you see a website like Pinterest, how it shows   all those different little boxes with pretty  photos in them. If that was both in Vue js,   it would be doing this V for loop over  all of those data objects that make up   all of those Pinterest cards on your Pinterest  wall. The last thing we need to look at before   we get into the demo application is lifecycle  hooks. So we will cover those in the next video.   Another important concept in Vue j. s is lifecycle  hooks, also called component lifecycle hooks.   So what is the hook and what are component life  cycles. To understand this, I made a quick demo.   Similar to the demo that we  started off with in this course,   I can click the toggle box button and a box  appears. Now I'm using a V if to take this box,   add it you can see it was added  to the DOM. Now if I click again,   it was completely removed from the DOM here,  that whole process of coming into the DOM.   And then finally leaving the DOM. That is the  life cycle of this box component that I have.   Now, sometimes things might leave the  DOM because you navigate to another page,   or because something is coming into Vue via  scrolling, or because you're hiding and showing   something like this example. In any case, you can  use something called lifecycle hooks. A hook is   just a function that will be triggered to run at  a specific point in the lifecycle of a component.   For example, it's a function that will be called  right when this purple box appears on the screen,   or right before it leaves the screen. If  you look at the Vue, j s documentation.   Now this is the version two documentation here,  because they don't have what I'm going to show   you yet in the version three docks. But it is  the same thing. So I'm under learn guide. And   then if I scroll down on the sidebar, I'm at  the Vue instance and creating a Vue instance.   And I can actually click on  the lifecycle diagram here.   So this is a diagram like it says of the  instance lifecycle of your Vue instance.   And like it says, You don't need to fully  understand everything that goes on right now.   But it is a useful reference. And this  chart isn't just useful for your Vue   instance. But every single Vue component  will have access to these lifecycle hooks.   So you can see these two up top in the red. All  of the boxes in the red are the lifecycle hooks,   you can see before create and created, these  hooks will be run right before and right after   Vue. js has initialized your component.  Now the next two before mount and mounted,   the format is run right before your component  is mounted to the DOM. And mounted is run   as soon as your component is mounted to the DOM.  components can also go through updates. So before   update and updated, like it says here, this  will happen. Or these updates will be triggered   when data changes on your component. So any  of those data variables that you create,   if you're incrementing a number or changing some  kind of value, then updated and before update will   run. And then when your component is going to  leave the DOM. Now here it says before destroy and   destroyed. Now this terminology has been updated  for Vue three for these two lifecycle hooks.   So if we go to the Vue three documentation  now and we're on lifecycle hooks here.   I'm going to scroll down so you can see  before create created before mount mounted   before update and updated. I'm going to  skip over some of these and Now you can see   it's before unmount and unmounted, which is  in place of before destroy and destroyed.   The lifecycle hooks function exactly  the same way, they've just been renamed.   I hope this will become a little  bit more clear as we look at a demo.   So in the code, you can see I have  the same box that we used before   appear. And here is the toggle box button inside  of my Vue template. But this time, I do have a   special test box custom component that I made,  which is toggled based off of a V, if so this   is my main application. And the options object  with my is visible variable for whether or not   the box is visible. And then I just have a toggle  box method, which I call when I click this button.   So again, this is pretty much the same thing that  we did before. Except for this new component here.   I put the box in its own component. Now Now that  we've learned about composing components, and I'm   just going to add some lifecycle hooks here really  quickly to illustrate when these are called on the   component lifecycle. So I'm just going to add  a couple of them here. We're gonna add created,   and then mounted, and then unmounted. And in  each of these, I'll put a console dot log.   And let's see when these console dot logs print  out. Back in my browser, I'm going to hit toggle   box here. And you can see in the terminal at the  bottom, created, printed and then mounted printed   in the same order that we saw in the VJs  documentation. So this one happened before. And   then this one happened after it was mounted to the  screen to the DOM here. Now if I hit toggle box,   again, we can see unmounted prints because  that is run after the box leaves the DOM.   Now let's look at another one. After methods here,  I'm going to put lifecycle hook on this component,   or on the main Vue instance that we  have here. And I'm going to try updated.   And I'll hit toggle box. And you can see  that we have created and mounted those both   print from the box component itself, but from the  main instance also updated prints. And that is   because we are updating this data variable from  is visible false to is visible true. And so the   update function is triggered on this component  because our data updated for that component.   And if we toggle it again, we can see updated is  run again, because that variable was changed to   false again. So updated will run every single time  the data changes. Now, why might you want to use a   lifecycle hook, some of the most common use cases  are checking whether someone is authorized to Vue   a certain page or component. A lot of people use  the created and mounted hooks as well to pull data   into their application from a back end or from in  browser storage. Sometimes they are also used to   initialize events. And then when the component is  about to unmount, you can clean up that event. Or   you can save some data or run some kind of check  on before unmount or in the unmounted function.   So those are the basics of lifecycle hooks, I  encourage you to test out lifecycle hooks on your   different components and see what happens when you  use different lifecycle hooks. In a future course   we can get into some more advanced examples and a  few of the more advanced lifecycle hooks as well   that you won't see as often. So those are  the basics of Vue js. In the next video,   we are going to build a Vue three application  from scratch, starting with the Vue COI this time.   This is a demo of the application that we will  be building. It's a simple shop application with   a few items. Now it looks like the web page is  already done. But actually it's just static HTML   and CSS so far. As you can see, if I click the Add  to Cart button, nothing happens. And if I scroll   up, the only things that are actually functional  on this site right now are these top nav links.   Which are just regular browser anchor  tag links to bring you to another page.   So this one goes to the Products page. And you can  see I have this cart, which is not functional. So   if I click the X, nothing happens, it's just  fully slid out here to demo how it will look.   And if I click the X, nothing happens, it doesn't  delete the item, I can't add items to the cart.   And on this page, I have a past Orders table,  which is also just static content right now.   This project is going to be a little bit  different than tutorials that you are used to,   we are not going to be starting from scratch  with some mock ups here. Instead, we will be   starting with a static application with HTML and  CSS already coded, then we will figure out step   by step how to add Vue JS into the application.  This will help to give you a deeper understanding   of how Vue works and how to build real world Vue  applications. First, I will give you an overVue   of the code base. And then we're going to see how  it looks in the browser. And then finally, we will   start with the Vue JS portion and implementing  our own Vue code into each feature one at a time,   the goal is to eventually reach a point where  it gets to be difficult to continue to code   inside of HTML. And then we are going to move  the project over to a Vue COI setup project   where we will have Webpack and the full  ecosystem of Vue j s tooling and libraries   like Vue x and Vue router. So let's get started  looking at the code. So I'm going to start here   with the package dot JSON. Now this is the file  that's generated by NPM. You should have seen one   of these before if you've worked with JavaScript,  and it has some metadata about our project here,   and then the scripts section. So you don't need  to know what all of these scripts are doing.   This code will be available for you. So if you  want to dive deeper into each one of these you   can. But since we're focusing on Vue here, the  important part is that we have this start server   that compiles our styles and serves  our application for us. Now later on,   I'll show you how to start an application  with the vcli. But I had to use some kind   of a temporary server here in the meantime.  So that's what live server is doing for us,   it will serve it on a port, similar to what we  did with the live server plugin that we used in   VS code for the last demo application. So to  start this application, I'm going to go up to   my terminal option here. And I'm going to  choose new terminal. And my terminal opens   at the bottom here inside my current folder. And  I'm going to run the start command. So NPM start,   you can see that automatically opens the  application on the correct port here. And   if I scroll down, I can see the same page  that you already saw. Now back in the code,   let's look in the source directory. So the source  directory is where all of our JavaScript and other   code is going to live. And this is where we'll  also be adding Vue js. This is our main HTML file   for the application, which is the home page. And  you can see the links here go to Vues pages inside   of this Vues directory over here. So the links  will take you to the past orders page and also   the Products page. Now to start working with Vue  j s, I'm going to start with these cards here.   Right now I want to be able to update and save the  quantities and be able to add them to the cart. So   in this app dot html file, I'm going to go ahead  and add my link to Vue j s, just like I had in   the last demo application. So I'm going to go  to the bottom here and paste the script tag.   So I'm importing vj s. And now I need to write  some custom vj s code to get my application.   So I will create another script tag. And here  I'm going to do let app equal Vue dot create   app up a pass it in empty object for right now.  And then here I'm going to do app dot mount   and then mounted in the same DOM  element as before with the ID of app.   And let me just check here. Yes, the wrapper  div here. If I fold it, you can see all of   the content is created inside of app. So to get  started here I definitely want to create a data   method. And I need to return an object. And  on this object, I want to track my inventory.   So when someone clicks the Add to Cart button,  I want to increment or change the amount of   inventory that I have. So inventory itself will  be an object. And you can see the different   types of produce that I have here. So carrots,  pineapples, and cherries. And so I'm going to add   these three items to my inventory, carrots, and  I'm going to initialize all of these with zero.   That looks good. Now I need to find these elements  inside my application and put the variables there.   So if I look down at these cards, you can  see here's the recommended product section.   So I have carrots here. And I have the price  here is the quantity with the input field.   And what I want to do here,  instead of setting the value,   I want to do v model. And this  should be inventory, dot carrots.   And then I'm going to copy the same thing for the  other fields. So come down here to pineapples,   and paste this. And then cherries as well. Okay,  now let me take a look at that. And you can see   it still shows zero here. Just like before  I can update a number, we do three carats.   And now the number starts at three. So now we want  to do something when someone clicks add to cart,   if they have a certain quantity in  here, we want to add it to a cart total,   we change this back to zero. So to do that, I need  to create a method, we create my methods object,   I'll create an Add To Cart method. And in this  method, I need to take in the number of items   that someone wants to add to their cart, and also  the type of item. So to do this, I'm going to need   another place to store what  items are actually in the cart.   So I'm going to create a cart here. And for right  now, I'm just going to copy the same items over.   And then when I call the add to cart method,  I need to pass in the type of item and   quantity, then I can access my cart variables  by doing this, that cart and pass in a variable   that I want to access on my cart object, I  need to use the square brackets, and then I   can pass in type. So it would be the same as  this cart carrots or this card, pineapples,   or whichever item we want to access. And  then I'm going to increment by the quantity.   So plus equals quantity. Now I don't have to  return anything from this function. Because   this is really the action that I want to take  by calling this function is to update whatever   I have in my cart right now. And to show this,  I'm just going to log this out in the console   in the browser, so you can see it when I log out  this cart. And I'm gonna open my console here.   So for carrots, I'm going to add three, you  can see nothing happened. That is because I   forgot to connect this method to that button.  So let me go up here and add that button.   So I'm just going to add it  to carrots right now, here.   So when someone clicks on the Add to Cart  button, I'm going to call the add to cart   method. Now I need to call it passing in  a few arguments here. So the first one   is going to be the type of item that I want to  add to the cart. So this one will be carrots,   and I also need to pass in the quantity.  To pass in the quantity I need to use the   inventory carats variable. So  I can just pass that in here.   I could also just call it from inside of my  function which is Actually what I'm going to do.   So let me scroll down to see my function again.  And instead of quantity here, instead of passing   in this extra variable, I'm going to just update  this to this dot, this dot inventory, and then   get the type from there. So let's see  if this is working. Let me add to cart.   And you can see there is definitely a  problem because the input value is a string,   and it's trying to add it to the numbers zero,  so then it turns the expression into a string.   Now Vue has a very easy way of fixing this. And  this is through a modifier just like we learned   about a little bit in the last demo that we  did. So let me go up here to the V model.   And we don't want this V model to be considered  as a string, we want to go ahead and cast it as   a number. So Vue gives us this modifier  as a shortcut. So v model DOT number.   So now if we look in our application,  may add to cart. And I can see down here   that my carrots have one item in it, which  is a number so I can add to cart again.   And now it's two, and I can add multiples.  And now there's eight carrots in the cart.   Let's stop here for this video. And don't forget  to download the related code and try out these   features for yourself. In the next video, we  will work on displaying the items in the cart.   So now we want to hook up this cart  menu or cart slide out. And right now   it's just static content. So we can  only see it from the Products page.   And if you look at the code, we go to the  products dot html, I'm going to fold this header,   and also the main container, which is  this main part of the page right here.   And now I can just see this aside,  which is that cart section on the side.   So I basically want to get all of this HTML and  make it available on my other pages like my app   page, which is the homepage, so that I can use  Vue j s to trigger opening or closing the menu.   And I also want to make these cart items dynamic.  So when I add more items to the cart, it can   update the quantity and the price. And I can also  set a variable. So if there are no items in the   cart, this will display. Now HTML itself doesn't  have something like an import to import a block   of HTML into another HTML file. A lot of people  use PHP or some other back end tool for that.   But we can also easily do this in JavaScript. So  we're going to do this in Vue, j. s, actually.   So I'm going to remove this sidebar from the page  that it is on right now. And move it into our Vue   application. Of course, our Vue application is  nested inside of the app dot html page. But we   can move it outside later. So that this menu  will be accessible on all pages in the future.   So I'm going to fold this Vue create app. And  now I will paste this HTML aside that I have.   Now it's giving me an error or a couple errors  right now because it's inside of a script tag.   But I'm going to fix that. So if you recall,   in the earlier lessons, we defined the different  components inside of our Vue application. So   this is a perfect use case for a component  right now, because it's this reusable block of   HTML or template that we want to use on  multiple different pages and also interact with.   So I'm going to register this as a component.  And I'm just going to call it sidebar.   And now I pass in the object just as before, and  on this options object, I can set the template   and then use graves. And now I want to grab  this aside again. And paste it inside of here.   And so now I have this whole aside all of the  code inside of my template for this component.   And now I can add this To the page with the name  sidebar. So I'm going to go ahead and add it here.   And remember that our div wraps the whole Vue  application. So I can put this anywhere inside   of that div with ID of app. I'm going to put it  here, actually between the main and the footer,   I'm going to put the custom component, sidebar,  and Vue will handle putting the template I have   down here where this sidebar element is in the  template. So let me go back to the HTML here,   you can see the sidebar is no longer on the  Products page. But if I go to the home page,   now I have a sidebar here. So now that the sidebar  is in Vue js, I can start making it interactive.   And the first thing I want to do is be able  to hide and show the sidebar. So basically,   when this is clicked, I want to hide it. And then  when another button is clicked, I want to show it.   So I need to create a variable for this. And  let me go down to my JavaScript down here.   So inside of my regular create app here,  in my main options object, I'm going to add   an element to data here. And I'm  going to call it show sidebar, false.   And now I can come to my sidebar, and simply use  a vi F, and point it to the variable show sidebar.   So if show sidebar is true, then my custom  component will show up on the page. If it's false,   then I shouldn't see the sidebar at all. And  you can see it's false, I don't see any sidebar.   And when I change this to true, I see the sidebar.  Now I just need to add a toggle for this sidebar   and change it back to false by default. And now  I can create a method called toggle sidebar.   And I'm going to say this dot show sidebar equals  the opposite of whatever it is because it will   toggle true or false every time this function is  run. So I'm going to say it equals not this dot   show sidebar. So if it's currently false, that  means it will be set equal to true and if it's   true, it will be then set equal to false. Now I  just have to call this method. So the first place   that I'm going to put it is on this button here,  this cart button should open that cart sidebar.   I'm going to find that on the page.   Here is that Cart button. And I'm just going  to add an ad click here. Add click equals   toggle sidebar, I don't need to pass anything  in so I can just leave it as this. And Vue will   automatically look through my methods and find  that method. So let me see if that works. Go back   to the page should be able to click on this now.  And yes, it does toggle. Now the next thing I need   to be able to do is close it and I need to close  it using this x here. So I'll have to go down to   my template here. And here is the button.  That's that x that's in the corner of the header   for the sidebar. So I need to add an app click  on this. And I'll have to do app click. And now   I want to use the function toggle sidebar. But  because this is wrapped in its own component,   I actually don't have access to the  toggle sidebar function from here,   I actually have to pass it into this component  to be able to access it. And I can do that here.   So I'll pass it in as toggle equals toggle  sidebar, I'm using my method on the vj s   object called toggle sidebar passing it into the  sidebar component with the name toggle. So inside   my component here, it's going to be called toggle.  So I'm going to have to accept it as a prop and as   accepted as toggle. And that will be my function  name. So now I have to rename this function and   call it toggle. Let me see if this works. Go to  cart click x and it is not working. So I do have   an error here maximum call stack size exceeded.  So let me see what I do. Wrong in the code.   So I'm importing the prop toggle, the function  should be called from here of toggle sidebar   that is pointing to toggle sidebar here. And, oh,  I forgot to make this point to a Vue variable.   Instead, it was just trying to use it as a  string before which was causing an error.   So now it should be calling the actual toggle  sidebar function. And let me see that in the code.   Okay, it works just as intended now. So  now on the sidebar, I want to be displaying   actually dynamic items here. For right now,  I only have one item hooked up carrots.   And so I'm only going to be  working with this one item   until the next video. So let's hook this  item up. When I add items to the cart here,   I should it should update in the cart over here.  Now to do that, I need to take this cart object   and pass it in to my sidebar, so my sidebar has  access to it. First, let me do some cleanup here.   With this on multiple lines to  make it a little bit cleaner.   And I'm going to pass in cart as just  cart. And now I have to receive this prop   in my component here. So I'm going to do it here  and call it cart. And now cart that I'm getting   in my component is actually that cart object. So  since I'm only working with carrots for right now,   I'm going to just assume that and  only add the number here for carrots.   So I'll use my double mustache syntax. And I  have that cart variable. So I'll do cart dot   carrots, and that will be the number of  carrots that I have. So let me go back to here   and automatically updated. Let me add  three. And my cart now is quantity three.   So if I add, let's add five more now this quantity  eight in my cart. So now my cart is dynamic. Of   course the total should also be updated based off  of the quantity should be price times quantity   equals the total for that item. So let me do that  really quickly. This is the total number. So I'm   just going to have to do this. And let's say cart  dot carats times the price which it says it's $1.   But here it says 482. So I'm going to use this  price because $1 isn't that interesting. So I'll   do times 482. And then before that, I need to  put in dollars. And let's see if that works.   To add to cart. Now there is an error, let's see  what the error is unexpected token with a dot.   The reason why it's complaining is because $1 sign  followed by curly braces. in JavaScript, whenever   you put that syntax inside of the backticks that  we have around this template here. It's called a   template string. And it will parse whatever is  inside those outer curly braces as JavaScript.   So thinks we're trying to pass in a JavaScript  object. And it's complaining because cart carrots   is not a valid key. So the only thing we have  to do here is actually escape the dollar sign.   So JavaScript doesn't think where you're trying  to use a template string and pass in a variable.   And then Vue can just parse the double curly  brace syntax on its own. This should work.   So let me go to cart now my cart opens as normal.  You can see there's zero carrots. And now if I add   two carrots to the cart, and now gives me the  correct total of 964. Now I also want to have   a total of all the items in the cart. I only  have one item now but I will have more items   soon. So I'm going to go ahead and add a function  for that. And then we will hook up the rest of the   items in the next video. So back in the code  here, this is the total that I want to update.   So I'm going to add this and escape that dollar  sign that comes with For the double curly braces,   now I could create a formula just in line here and  say carrot cart carrots, times the carrot price,   plus the second item times that price,   and so on and so on. But that's not going  to make a lot of sense. And that doesn't   scale for multiple items. So what I'm going  to do here is actually add a computed object.   And if you remember computed  watches the changes in variables,   and we'll update the result. So I'll  call this computed function cart total.   And on my cart appear. Right now I have just  the number of each item. So for right now,   I'm just going to hard code the price down here.  So I'm going to return cart dot carats times   the price, which is 482. And now I can  take this computed variable that I created,   and put it in here. And now the cart total,  that amount should be updated every single time.   Let's see if this works. Add to cart, open my  cart. And there is a bug because it's not opening   and stepping through trying to figure  out why the cart total isn't working.   And it is because I have accessed  it incorrectly. So cart dot carrots   has to be accessed This is inside of JavaScript,  so I need to access it on the this context in my   component. So I have to access it on this card  carrots, and that should come up with my number   times that number. So let me go back to my  page. And now it opens. And if I add items,   I can see it's $24.10. Of course this isn't  that pretty. Sometimes it rounds it to one,   or sometimes there's only one decimal, and  sometimes there's like 10 here. So let's   just run this really quick using something built  in in JavaScript. So we just get two decimals.   I'm going to wrap this here, that two fixed.  And then the number two. And let's go back to   the browser, I'm going to open up the cart, add a  few items. And now it's at two decimals Exactly.   Always two. Okay, I'm going to leave it  there in this video. Again, please try out   implementing these features on  your own from the example code,   you should be able to check out the starter  branch called homepage, one from the repository   and start exactly where I did at the  beginning of this video. In the next video,   we will cover adding all of the rest of the items  to the cart by importing them into our JavaScript.   So we can use loops to make our code more  efficient and not have to hard code everything.   In this video, we are going to pull in dynamic  content to populate our page. And that will be   from this food dot JSON file. So this actually  has a list of objects of all different kinds of   groceries that we are going to display in our  app. It has some information, like the names   as well as the price. And then even if we  want to add a filter to sort by the type.   So how can we pull this into our application.  Actually, we are going to use lifecycle hooks   in Vue j s for this. If we come to our  main Vue application here, below methods,   I am going to add mounted hook just like we had  before. And inside of here, I am going to fetch   this JSON data. And that's going to be an  asynchronous call. So I first need to fetch this   from the file name, which is food dot JSON. And  I'm going to call this the response. And then   I need to call the JSON method on that response.  Which I put on this line, and that will be data.   And actually I need to add a weight to these  calls. So res dot JSON, I can call that method.   I'm going to await this as well. And then  because I'm using a weight, I need to add async   To this mounted method. So now I've  created the mounted lifecycle hook,   I get my data, which is the array of all of  the food objects. And now that I have my data,   I am going to set it on state here. So instead of  inventory here, I'm going to replace inventory,   just get rid of all this dummy data that I have  right now. Set it as an empty array. This will   definitely break my application right now. But  it's okay because it's a step toward fixing it.   So now I'm going to set this stat inventory  equal to data. Let's see if that even works.   And I'm going to come to my Vue here, I can  see my root. And I can see that the inventory   in my root element here that I have all 15  items. Good. So I know my data is working. Now,   the next two things I need to do are display  that data on this page here. And so these are   just three recommended items, actually, all  of the products will display on this page. So   for the homepage, I'm just going to display the  first three and slice that list as I loop over it.   So now that I have inventory, I'm actually  going to come up here to my main container.   And I'm going to come to the recommended  section and fold all of these cards   and get rid of the last two,  because I'm only going to need one   for my loop. And now with this initial  card, I'm going to turn it into a V for loop   and loop over each item in that  inventory array. So equals product   in inventory. Let me just see what this looks like  really quick. And yes, it tries to loop through   every single item in the whole inventory. So I'm  going to slice it at three items now. And I can do   this because inside of my Vue directive, I can put  valid JavaScript. So we're going to do dot slice   from 023. And now we'll go back to my page.  And you can see I only have three items. Now,   of course, it is only displaying carrot,  because that's all still hard coded.   So let me put some dynamic content in here.  And first with the name, I'm going to put   product dot name. And then I believe it's product  dot type. Yes. So here, I'll put product dot type.   And for the price, now I do have prices in two  different currencies, I'm just going to use US   dollars for right now. So I need to  access price dot USD. And so here,   I'm going to go ahead and escape this. And then  do product dot price, dot u, s, d. And actually,   this is just an HTML template. This isn't inside  of a JavaScript template string, so I don't need   to escape that at all. And that should be all of  the dynamic content that we need for right now.   Let's actually go ahead and update the icon  as well. So that would be product dot icon.   Make sure that's the right. One. Yes,  that icon. Okay, so let me go to the page.   Okay, so the icons not working, but all the  other data is displaying quite nicely. So now   we want to add functionality so that the quantity  properly updates and we can add it to the cart.   Of course right now, all of these elements have  the same v model. So that's why they are marrying   each other. So let's change that. Now I'm going to  go to the V model here which is inventory carrots,   but I need the inventory of the correct item  instead of just hard coding carrots here. So   because these numbers are In order or because this  is an ordered list, I'm going to come to my loop   and get the index. Of course, I could use the ID  as well. But I'll just use the index in the loop   here. And actually, I almost forgot, I also need  to add a key here since I am looping. So let me   add that key. And I'm going to come down here,  and inventory, I'm going to pass in that index.   And then I'm going to add a new attribute called  quantity. And so this should model to an attribute   called quantity, which is not currently on the  objects, but that's okay, I'll just leave it off.   And this should just add the quantity key to the  object as needed. So let's see if this works.   Let me go back over here. I'm going to add  one here, you can see they're not all mirrored   for each other anymore, I'm going to add it to  cart. And let me see how this represents in my   Vue data here, I can come to inventory. And I can  see quantity of one. Whatever number I've put this   number mirrors it. But now I need a way to add  this to the cart. So let me set up the cart then.   And here at this add to cart function, I do  need to change it because I need to pass in   instead of a string, the dynamic name of  the item. So I can do product dot name.   And actually here, I didn't think of this, but  instead of inventory and getting the inventory at   index, I, I already really have that in this  loop. That's what the product variable is.   So I'm just going to replace that.  And that should work just fine.   Now, of course, I don't really need this  index anymore, because for the key, I can use   the ID of the product. So let me just use  that product ID and that should work okay.   And then this should also mirror  object to let me see if that does.   Yes, and the quantity is married.   Okay, now for the cart, passing in the product  name as Add To Cart. Let's take a look at the   add to cart function. We are passing in the type  here. And then saying this duck card duck type. So   it will be like this cart dot radishes plus  equals whatever the amount is that this   that inventory. So we do need to do one  more thing here, we could either search and   find the item by name in the inventory, or  the easier thing to do would be to pass in   the index of that item. So that's what we're going  to do. And while I'm changing this, instead of   type now, I think it makes more sense to call  it name because it is the name of the item.   And we're using type for the type of item  like vegetable or fruit not the name anymore.   So now to access it in inventory, I want to do  index and then dot quantity. And that should work.   But we have to actually passing the index here.  And up here, we're actually going to be passing in   the index actually. So we're going to  take the index here. And now add to cart.   Okay, so we are getting not a number for  these values. So I actually want to see what   we are passing in or what gets  passed in to the function.   And so to debug the function quickly, I'm just  going to console dot log and name and index.   Now back in the code. So the arguments are  getting passed into the function just fine.   So stepping back through this, I can see that  my problem here is that I am doing a plus   equals on cart or this cart name when there  is no value for that name in the cart yet.   And by the way, I'm going to go ahead and  get rid of my dummy data. In the cart,   and here, I'm just going to put a simple  check. So if not this dot cart name,   then I'm going to set this  cart name and equal to zero.   And now this statement should work. Okay, let  me try again. So here, I'm going to do two.   And this should update. Let's see. Okay, yes.  So it's taking a minute, for some reason,   buy, it shows the correct number of each in the  cart, no more, not a number. Now that shows it   on the cart over here, I want to show it  in the sidebar. Right now in the sidebar   is hooked up to only look for carrots.  So let's make the sidebar dynamic now.   So if you remember, the sidebar here is  in this template. So it's part of the   custom sidebar component that we made. And we are  already passing the cart in here. Now we actually   need more information because the cart is only  showing us the number of items in the cart. But   we also want more information from those items,  such as the price. So I'm going to come up here   to my sidebar, and after cart, I'm going  to be passing in the inventory as well   as inventory. And now I can receive  that as a prop in my component.   So basically, we have to loop through  all of the items in the cart and display   their information now. And we have a table here.  So we have all of the headers for the table.   And then we can loop through these rows  and basically make as many rows as we want.   So I'm going to go ahead and add a  v4 here to loop through each item   in the cart. And here, I do need to use the  index, I will be using that as a key here.   Okay, and now these are being looped through in  sidebar. So if I come to the sidebar, I should see   no items right now, of course the totally  needs to be fixed. And now I can see   I have this item. And now I have another item. So  now I need to get rid of these hard coded names.   Now to do that, I'm going to go ahead and grab  the key for these items in the cart. And actually,   because cart is an object, this index is  actually going to be a key. And then the   third one is index, or just I. So now I have  access to the item name, which is the key,   the item quantity, which will change this to  the name, quantity. And here, I can change this   to that key and we should see the names of all  of the items in our cart. Let's test this out.   Let me add different items to the cart,  should see radishes and artichokes.   And in the cart, we do indeed see radishes and  artichokes. Now let's display the quantity.   So here, we can get rid of this and say  just quantity, which we're pulling off of   the object in the cart. Of course, we already  know that should work when we add an item here.   And quantity works. Now price is a little bit  trickier. Because we don't have the price stored   on the cart, we actually have to search through  inventory for the price. So we're going to make a   helper method for that. First, let me escape this.  And then we're going to call get price Asin the   name of the item which is the key and we will find  the price and return it based off of the name.   So after computed here, I'm going to add  methods for this regular methods object   and add that get price. And basically  we can access this dot inventory   and to do a dot find. So we want to  find one of the inventory items. So   I'll call each item product in the function that  I pass in, and find will loop through all products   in the inventory and try to find whatever item I  want. So I want the item where the product name   is equal to the name that I'm  passing into the function.   And when I find that product, I'm going to set  it equal to a variable here. kind of confusing,   if I call it product again, so maybe  I'll just call this one p instead.   There we go. And now for the return function, now  that I have the product saved in this variable,   I can do product. And it should be dot  price dot USD again. So dot price that USD.   And that should return the price of the item. And  let's see if that works. So let me get one here   and Vue the cart. And I can indeed see the  price. Let me try that for artichokes too.   And I can see the price and quantities of the  item correctly. Now, let me update the function   for total. And so total here needs to be dynamic,  based off of the whole cart really. So to do this,   I'm actually going to use a helper method. So  what I'm going to do is take this out of computed,   and instead use it as a method. So since it's  not computed as a method, I'm going to call it   a verb. So calculate total. And I'm going to  go ahead and rename the method call down here,   of course, I'll actually be calling that as  a function now. And I won't be needing this   line of code anymore. So now we basically  need to calculate the total based off of   the quantity in the cart. And then we have to  look up the price in the inventory. Fortunately,   we already have a method to be able to look  up the price. So we're going to just use that.   And the easiest way to do this is  actually to do object dot values.   And so object dot values can give me an easy  array of values out of an object. And because cart   is an object, I'm not going to loop through it  directly, I'm just going to grab all of the values   out. So I will pass in cart. And now I have an  array of all of the values here, which are the   quantities that I want. So out of that array, I'm  going to reduce it. Now the reduced function is   just a built in JavaScript function, where I save  an accumulator. Some people like to call it a Some   call it an accumulator, because that's what it  uses on MDN. And basically, I'm calculating a   sum on each iteration through the loop. I also  have my current item that's being looped through.   And then I can also get the index of that item  in the function. And basically, what I want to do   is return the accumulator, sum total, whatever  you want to call it, plus the current item or the   current value, because I'm looping through all of  the values on the cart here. And I need the value   times the price. So I'm going to have to call  this dot get price. And then I need to pass in the   name of the item that I want to get the price for.  So the easiest way to do that is to also make an   array of names. So I'm going to do that by using  this time object keys. And I will do this cart,   get all of the keys this time off of cart.  And actually, I forgot to put this here.   And so I will do the current  value times this dot get price.   And now that I have the names here,  I'm just going to look up by the index.   So I can pass a names index to that this dot  get price function, and that should work.   For the function. I forgot to put an arrow  here. And now for the total variable.   I just stored it in a variable to explicitly  name it. All I need to do now is return the total   now, this time function works, there  might be a more optimized way to do this.   This is just to demonstrate how to calculate a  total using a VJs method for this application. And   it's basically just using regular JavaScript. So  let me add items to the cart here. And of course,   of course, this total, we haven't done yet. But  we do have two radishes, and the total says $2. So   let's add some artichokes. And now we have a total  of $30.32. As you can see, those are the correct   values, what I believe is happening is because  objects are unordered, and arrays are ordered,   that the names and the object values, they aren't  being listed in the array in the same order.   So I'm going to have to instead of making two  separate arrays here, I'm going to get rid of   this one. And here, I will just have to change  this to entries. And now my current value here   will basically be in array, that will be the  key and the value, each time looping through   this larger array. So for the value, now, I  will have to access it at the first index. And   instead of names here, I can access the name  at the current item at the zeroeth index,   that all looks good. The last thing I'm  going to do is add an initial value here.   And this means that the accumulator will  start at zero. And also, if there are no items   in this array, which there aren't any to start,  that means the number will just be zero total.   And for here for the total, actually,  I'm going to use that method again,   that we use before, which was too  fixed. So I could do it to two decimals,   which is what I want in my cart. Let me see if  this works. And this is exactly what I want here.   So let me add items. Yes. And the  price is exactly right. One artichoke,   and the price still works there. Now what about  the total here, that should be easy enough to do   with our get price method. So let's go down to the  total. Right now it's hard coded as carrots, which   doesn't exist. So now I can do just the quantity,  which is the quantity of the item in the cart.   And then I'll call the get price method.  And I'm going to pass in the key,   which is the name of the item. And so that should  multiply by the total. Let's see if that works.   add an item and check out the cart.  And we do indeed see the total here.   Now it still says no items in cart, let's go ahead  and fix that. So this should only show if in fact,   there are no items. And so I'm going to add a V if  here. And just to speed this up, we're going to do   object that keys and then check the cart object.  So if there are no keys on the cart object   that will be zero, which is a falsie value.  And let's see if that works. Let's go down here   to radishes, add one in the cart, we  are still seeing this no items in cart.   So I believe I have to do length  here. Let's see if that works.   Okay, that does work, but I have it  backwards. So I basically need to do if   not, because if the length is zero, I  want to show this. And if it's not zero,   then I don't want to show this no items in cart  because there will be items in the cart. So let's   see if that works. Let's first go here, it does  show no items in cart. And now let me go here.   And now it changes to the item in the cart.  And all of the totals are shown correctly   and the quantities updated and all of that  stuff. The only other thing I want to do is   provide full CRUD operations, and this delete does  not work. So I'm going to hook up the Delete now.   So you can see the Delete is here on this  button for remove. And so I'm going to add   a function here and actually this function  will have to be not inside of this component.   But inside of the parent component, which  is my main Vue application in this case,   so I'm going to do a click. So when this  button is clicked, I'm going to say remove   item to remove the item from the cart, and  then I need to pass in the name of the item,   which is the key. Now this remove item is going  to have to be a function passed in as a prop here.   Because I can't mutate props, I couldn't change  the inventory, or the cart actually directly   from this component, I have to change it from  the parent component where it originates. So   I'll take a remove item function, let me go ahead  and pass that in. Remove item equals remove item.   And now I have to create that function here as one  of these methods. So let me add that remove item,   this will take in the item name. And I am  going to remove it from the cart basically.   So I can just remove JavaScript, delete  this cart name. Let's see if that works.   Let me add some vegetables to my  cart. And now I will remove them.   And it does not remove let's see if I'm getting  an error. Remove item is not a function. So let's   see why it's not considered a function. I  do have it in methods here, remove item.   Let's go here. This is remove item  that I'm passing into my sidebar.   I'm also accepting it as a prop in  the sidebar here. Let me get rid   of computed. So it's not recognizing this as a  function. So what I'm going to do is rename it   in the child component. Now, this is a  workaround only for the CDN, you won't have this   problem if you were using Vue JS from NPM. But I'm  just renaming the function in app component here.   There we go. And of course, I need to pass  it in as the name remove. So I basically   gave it a different name for the child  component and for the parent component.   And let's see if it recognizes this  as a function. Now, I will come here.   And I can remove it from the cart. Awesome.  Of course, when I add things to the cart,   I do want the number to clear here. So let me take  care of that really quickly. In Add To Cart here,   just really quickly, I'm going to set  this to zero. Let's see if that works.   And back to zero, and it is in the  cart now. Awesome. The only other thing   is that the cart does show zero items, even  when there are items in it. That's because   the number is not dynamic. So let me change that  really quickly. Here, inside of the parentheses,   I'm going to change this to be dynamic. And  I'm just going to call the variable total   quantity. Okay, and now I  need to make this variable.   So what I'm going to do is  create a computed object here.   And I'm going to say total quantity is basically  the sum of all of the quantities in the cart.   And to do this, I'm going to use another reduce  method, I'm going to say object, that values   pass in this cart. And then I will reduce  those to sum up all of the numbers.   So I have my accumulator and my current  value. And then all I need to do is add   the accumulator and current value together. Of  course, I'll set a default of zero here as a   starting point or initial value. And I'm just  going to return this directly this time. Let   me see if that worked. Right now it says zero, but  let me add items Notes three, let me add one more.   And now it's four. So the quantity is working.  If I remove one, now it's just one. So that is   a dynamic value now. And that is basically  it for the homepage here. In the next video,   we are going to move the Vue JS code outside  of the app dot html file. So we can see   how it can work in multiple different pages. And  also some of the struggles that we might run into   trying to build a multi page site via the  Vue CDN and trying to do things like share   data across pages and stuff like that. If you  want to see the starter code for this video,   make sure you check out the branch and the repo  called homepage, number two, or homepage, two.   Hi, everyone, welcome back. First, I want  to reVue what we did in the last video,   we connected the cart slide out draw menu on  the right here and made that fully functional.   And then we added an actual loop, as well as  functionality to be able to add items to our   cart here. Now this is only one page, of course.  So we also have the Products page here. So if   I go to Products page, you can see the URL  changes to go to the products dot html page.   Now if I look at this in my code, so let me open  up the source. And this app dot html file. Again,   you can see here is the header with all of the  links on it. I'm going to fold that real quick.   And then you can see the different sections of  the page, including that sidebar that slides out   that we actually want on every page. But now it's  kind of just hard coded into this homepage. I can   also go to Vues here. So you can see in the header  actually. So when I click on products, it goes to   Vues slash products, that HTML. So it's actually  navigating me to this products dot html page.   And if you look at the header  here, here's the whole page,   including a completely separate div with ID of app  where we would have to inject our Vue JS code. You   can see we already did that on this page, because  our Vue j s is in the script down here. And we are   rendering it or mounting it inside of that  div. But if I go to products, we have no   JavaScript, no interaction,  everything is hard coded.   We also have a duplicate header. So this  is exactly the same thing as the header on   this page is just copy pasted into the HTML on  this page. Of course, we don't want to do that   everywhere. We don't want to have a copy  pasted header for all of our different pages.   Not only that, we would have to copy  paste the whole cart sidebar as well.   So to make this code reusable here, we need  to extract these things into other files.   Now, this is not easy to do for plain HTML. But  we can use a Vue component like we did before   with the sidebar. So I'm actually going to extract  all of this out into a separate JavaScript file.   And now import this file into my HTML.   And you can see my page is still working.   My cart is still fully functional. And what  this allows me to do is now take this file   this JavaScript file that I have separated and  import it also into my products dot html file.   And I'm actually going to grab both of  the script tags so I can also have my Vue   and I'm going to put them at the bottom here,  except I'm going to have to go up a directory here   because my app.js file lives outside of my Vues,  right? Here's products. And I need to get upload   folder to app. So I have to do dot dot. And  that should reference the correct app.js file.   Let me see if that's working for go  to products. And you can see the cart   page doesn't open. But that's because I  have not hooked up the cart button yet.   So I will have to copy this over from the app dot  html file for right now. So if I go here, I can   just take the same code. And now it should  reference that same toggle sidebar function,   and also display the total quantity correctly as  well, because I am importing the same Vue j s code   in the script tag here. Now, you can see that the  cart variable displays just fine on the Products   page. But if I click here, of course, the cart  doesn't open. Because the cart is only available   on this page, I only have the sidebar  component here. And the sidebar component,   you know is actually a custom  component that we made in vj s.   So we can put that on any page where we import  the vj s. So I'm just going to put it here below   this main tag. And with all the same variables,  there should be fine, because we're sharing the   same Vue JS script. Let me save that. Now  you can see I can toggle the cart here.   And all of this is pretty much the same thing that  we did on the homepage, down here where we looped   through the different types of foods, we would  do the same thing over here on the Products page,   loop through them hook up in each individual  number, then hook up the Add to Cart button   so that it would actually display in the cart over  here. Now if I add items here, may add a couple to   cart can see I have three in my cart here. If I go  to products, you can see the page refreshed. And   now there are no items in my cart. So though there  is some functionality to this application. So far,   there are a few problems that we have run into  with just using a CDN to import Vue j s. And   that is how do we share data across pages and  across pager refreshes. So here at the homepage,   when I add something to the cart here, it  leaves the car as soon as the page refreshes.   So as soon as I navigate to another page,  it's gone. Now how would I fix that problem.   So generally, in front end applications,  we would want to do something like persist   our data or save our data somewhere. One easy way  to do that in the browser. And one very common way   is to go here in application. And you can  see there's different types of storage.   This is in browser storage. And local storage  will persist even if the page is refreshed. So we   can actually save the data like our current data  into local storage here. And then if we refresh   or anything, we will just automatically try to  pull anything that's saved from local storage   for the way our application is set up right now.  That would be every time we navigate to a new   page, we would have to check local storage, see  if there's anything in there and then pull it into   our application. It's kind of a workaround for  our setup. So one way to fix this would actually   be to create a single page application with Vue  where the front end would actually do the routing.   Instead of our server. In this case, we're just  using a live server in VS code. But our servers   serving at pages every time we go to a new URL  here. And that's why it has to refresh because   it's coming from the server. Whereas if we make  a single page application, there will be no   page refreshes, we will go seamlessly from page to  page because our front end in other words, Vue j S   will be routing us to different pages. The  second problem, as you can see is sharing code.   We do have some duplicate code across pages.  Of course, we are reusing the same sidebar   template here, this sidebar template. We just  registered it as a Vue template, a Vue component   called sidebar and we can use that on any page.  Now. We could do the same thing with header as   well. And we would probably do that if we were  going to build an application using the CDN.   We get to extract this into a template as well.  And then we would have to do the same thing for   the past orders page. Of course, none of this is  dynamic or set up yet. But the easiest thing to do   is actually to set up our project with something  called the Vue see ally. As our code base grows,   it will be very difficult to manage many different  components, if we are managing them just importing   different files into all of our different  HTML files. But there is a much easier way.   And that is with the Vue COI This is why it was  created. The vcli basically gives us one command,   Vue create, and our project name, and  then it creates a whole project for us.   It walks us through a setup wizard asks us  what features we want. And then we'll create   all of the files, folders and build tools  necessary for a robust front end single page   application. So in the next video, we are going  to take all of our code currently in HTML files   and our JavaScript file and convert it to a Vue  COI application. I'll see you in the next video.   Let's get started with the Vue COI,  I am at sea ally dot Vue j s.org.   And I'm just going to click getting started. And  if I go over to the side, click on installation,   I can see that it is prompting me to globally  install this Vue COI package at Vue slash c li   so that from my command line or terminal, I will  be able to use a Vue command to create projects.   Now you might see some places on the internet  that install a different package without the   at sign in slash dist Vue dash c li or something  like that. That is an older version of the package   Vue basically has its own namespace and then each  one of its packages are after the forward slash.   So to install vcli you can copy this command  here. I'm going to go to my terminal.   Now I have the Vue COI installed, I can  check and make sure that it's installed   by checking the version. Right  now I have version 4.5 point 11.   And now I want to use it to create an actual  Vue project. And I can do this through the Vue,   create command, and then give it the name of the  project that I'm going to create. If you want to   see the documentation for this command, you can  come over here under basics to creating a project   and read about how Vue create works here.  I'm going to go ahead and say Vue create   product and cart as the name  of my project and click Enter.   Now, if you've used some tools like create  react app, you will notice that here,   it's a little bit different. It doesn't just  bootstrap the whole project for you right away,   you actually get to pick your own options, and  the packages that you want to install and use.   These top four options here are actually custom  options that I have created myself. Vue gives us   these two defaults right now one is for version  two of you, and one is for version three.   And then it also gives us the option  at the bottom to manually select   features. So I'm going to go ahead and do that  just to show you how it works. So I basically   use the arrow keys to go down and then I can  click enter when I want to select something.   Now you'll notice that this list here is multi  select. And if I press spacebar, I can select or   deselect an item. Of course I want to choose my  Vue version because I want to use version three.   I definitely need to have Babel setup for me for  transpiling my Vue code, I'm going to need routing   in this application. I'm also going to use state  management with Vue x. But I'm going to add that   later to show you how to add a Vue COI package  after you've already set up your application,   CSS preprocessors or things like sass, if you  think you will want To use sass in the future,   it's a good idea to go ahead and set it up. Now,  I believe this also works with less and stylus   as well. And then I definitely want linting and  formatting in this project. And I can optionally   select testing if I want, which, but I'm not  going to do that this time. So once I'm ready,   I'm going to hit enter, it takes me to the next  step, I can choose the version of uJs, arrow down.   And I'm going to choose version three, use history  mode for the router. This is a pretty small coding   change. But it's usually what you want to in  a project. This basically only affects the URL   of your project from a user point of Vue. So  if you want your routes to be after a hashtag,   it will use hash router. If you want your ads to  be after just a normal forward slash, like any   website, you would navigate to in your browser,  then you can just go ahead and use history router.   And I'm going to use history router. Now it's  asking me to pick a linter, and formatter,   so I'm going to go ahead and pick es lint  plus the standard config that it has for VJs.   Click enter lint files when they're saved, I'm  going to choose to put my configuration in the   package dot JSON this time, just so I don't have a  bunch of extra config files. Usually when you have   larger projects, you want dedicated config files.  So it's not cluttering up your package dot JSON.   Do I want to save this as a preset? No, I do not  this time. But if you remember at the beginning of   this walkthrough, the four top options, those were  presets that I had saved in the past, but here I'm   just going to say no. Here, it's basically setting  up my whole project with the file structure and   everything. And it's also running an npm install,  you can see it successfully created my project.   If I list the folders inside now, I have  this new folder that was created for me   by Vue JS called product and cart. I'm going  to go into that folder. And you can see when   you spawn up the project for me, it  also initialize a git repository for me,   and saved all of the changes that it did initially  as a commit. So let me open this up in VS code.   And I have my complete project created for me by  Vue. In the next video, we will look through all   of these folders and files and give you a little  bit of a tour of how your Vue project is laid out.   Let's look at all of these files  and folders Have you spun up for us.   Now looking at this, this looks pretty much like  the last project that we worked on with static   HTML, CSS and JavaScript files. And that was by  design, to give you the same style of coding and   file structure that you would be using in a real  Vue application. This however, is much much nicer.   Starting with the Vue, see ally gives us  a lot more features out of the box that   we can see in the package dot JSON, we have three  scripts here by default, there would be more if   you choose to install the testing packages as  well, because we installed a linter, the vcli   gives us this link command. And then it also gives  us our main two commands for the Vue application   for development locally, it gives us this serve  command, which basically calls this package vcli   service. That's from Vue, j s gives it the serve  command and it will run a development server for   us. So there's no more of the old complicated  server setup that we had in the last version of   this in the last application. The build command is  really for when we want to host our project live.   This will generate production ready files for  you like your HTML, CSS, and JavaScript. So you   can deploy them and have a live website somewhere.  We're just going to be talking about this command   in this video. And to give you an idea of  what it does, let's go ahead and run it.   I can use NPM to run the  command. So NPM run serve.   And now my app is running at Port 8080.  If I highlight something on the terminal,   it automatically copies when it  come to my browser, open a new tab   and I can see it gives me an app or already  set up out of the box. And because we chose to   install a router as well, it installed the default  Vue router, which is also called Vue router.   And you can see I can go to different page routes.  Now this isn't the same as our last application,   because there's no page refresh in between page  routes. These are not HTML links. This is just a   JavaScript router, rendering hiding or showing  different pages of this application. You also   notice from the homepage, it's just Port 8080.  When you go to the about page at ad slash about,   if we look in the public folder here, you can see  here's our HTML page. And we have a div of ID app.   And this is where our app will be injected.  But also when our application is built. Under   the hood, this Vue COI service command is running  Webpack, and bundling all of our files together,   and also handling running Babel to transpile our  files, and so all of the JavaScript and everything   will be injected as script tags as well here.  But we generally don't have to worry about this   index dot HTML file in a Vue project. Because  again, most of what we will be doing is in the   source folder right here. So we have a main  dot j. s file that is always created for us.   So this is basically the same thing that we did in  the previous application. If you do c Vue to code,   this file will look a little bit different. But  you'll still be able to see the different parts,   just the organization and syntax is a little  bit different. Just like before, we have to pass   in a root component, we chain on any packages  that we want to use, in this case, the router,   and then we mount that to the DOM.  So inside of the div with ID of app.   And you could also rewrite this as const app.   And then app dot use router, and then app dot  mount. That's a bit easier to parse through as   you add more packages. Now, when we are looking  at this initial page, where does all of this   come from? Let's take a look. So we have our  main component app. But you'll notice in app,   there's no real content here. All it is, is  a div. This is basically the top navigation.   Now, where did this router link come  from? This is a custom component actually.   And if you look at our main j s, when we use  App dot use router, we are actually given   some components like router link, as  well as router Vue. Now router link   is actually a substitution for using  the anchor tag to link to another page.   Except router link is made by Vue router,  specifically for single page application routing,   where our JavaScript handles the routing.  Instead of linking to a separate HTML page.   Of course, we only have one HTML page. And all  of our static content is injected into that one   page. And the router handles intercepting the  route and making it appear as though you've   navigated to another page. While really it's just  showing and hiding different elements on the DOM.   So we have these two router links. And then  what does router Vue do? So router Vue,   is actually our page content. And our router  will handle replacing this router Vue tag   with whatever component we tell it to in our  routes file that we are about to look at.   So router Vue is just a temporary placeholder  for whatever we put on the page. And you'll see   as we navigate to different pages, those home  and about links at the top of this file. Those   will stay no matter what page we navigate to. But  all of the content below it will change because   those are the components getting injected into  this router Vue area here. If we look into our   router index.js file here, we can see that we  are using the Vue router API to create a router   and when we create a router here, we are  passing in two things. So the routes,   which is an array of all our routes that we  have in the application, and then history mode,   it set this up for us because we chose to  use history mode. And Vue is handling all   of that under the hood. But let's talk about the  routes here. So we have the default home route,   which is this page. And then we also have the  about page, which is found at this route. Now,   you don't have to worry about code splitting,  and lazy loading and all of that other stuff.   Those are more advanced routing concepts.  So I'm going to get rid of that line.   And then just import the about component.   Just like the home component. Now you basically  define routes here. And instead of importing   the components that you want to show on a page  into your app dot Vue, you just use a router Vue   tag here. And then you import any of your Vue  components, like home and about into this file,   you define the path where that component  can be found it the name of that component,   now the name is mostly used for routing, and then  you tell it which component will be found at that   path. So at the home path, we're going to find the  home component. Now, where's the home component,   you can see that it is in Vues slash home. So  let's go in here. And we can see that this is the   component, it has an image, which is the Vue logo  on top. And then it also imports another component   into itself. Now this component is not in the  Vues folder, it's in the components directory.   Now why is it in the components directory, instead  of just one folder for all Vue files, basically,   in front end applications, files are usually  split up between Vues, or pages. So basically,   anything in this Vues folder will be connected to  the router. So they will have their own routes,   there'll be their own pages. Anything in the  components folder are things that are imported   into other components. They're meant to be parts  of pages or reusable components that you use   throughout your application. Basically, anything  in the Vues folder is connected to the router.   And if it's not connected to the router,  and just imported into another component,   then put it in the components folder.  And you'll see at the home route,   there's a Vue image at the top. And  then there are all of these links here.   And that's exactly what we see in the home route.   Now if we go to the about page, it's not importing  any other components or doing anything fancy.   There's only this h1. So I header with that text,  which is what we see when we go to the about page.   assets, of course, are a place for usually  CSS images, anything like that to live.   Sometimes you will see other folders created here  in Vue projects. But these are the basic ones.   The only one that we are going  to add later is the store folder.   And we'll talk about that in a few videos.  In the next video, we are going to start   transferring our content over from our old  static application into our Vue application.   Let's start moving things over one  by one starting with the homepage.   I'm going to go over to my original code here  into source and then go into my app dot html here.   The first thing that I need  to grab is this header.   Now I do have some JavaScript functionality in  here and I'll handle hooking that up in a minute.   But let me just copy paste for right now.  And move this over to a new file. Now I'm   going to need it on this homepage here. But since  this header is actually my app wide navigation,   I am actually going to want to replace the  navigation here. So that I can use this and see   this on any page. For right now I'm going to get  rid of these. Now there's a bit of cleanup that   I need to do here. Because these anchor tags need  to be changed to the Vue router router link tags.   And now I need an actual route. So  instead of pointing to an HTML file,   I am going to give it a route that will be  in my router here linked to a component.   So I have this products dot html here, what I'm  going to do is changed that to slash products.   Of course, this can't be an H ref, this will be  two, since that's expected by the router link,   also need to change this from h ref to two. And  I can just call this route past orders get rid of   the dot html. And here as well change this to  two. And this should just be a forward slash.   I'm not going to worry about this yet.  This last router link at the bottom,   I'm going to just comment that for right now. And  basically I need to create these three components   that are linked to the routes. Now I already  have the home route here that is linked to the   home component, I'm actually going to get rid of  about and I'm going to change this to products.   I'm going to have to create a new component.   Now let me delete about from here.   And let me create a new file.  I'll call this products dot Vue.   Now this is a little bit different. Instead of  calling this just a regular JavaScript file,   with the extension j s Vue has a custom file  extension, which is dot Vue. All of these dot Vue   files are parsed by the Vue and web pack setup,  that the Vue COI sets up for us. So using these   dot Vue files, we can put our HTML template, our  JavaScript, and even our CSS all in the same file   that gets parsed and all put together and  bundled by the tools that vcli sets up for us.   Now I have a new file, I'm just  going to create a template in here.   And I have four spaces, I'm going  to switch to using two spaces   for tab spacing. And I'm just gonna  put h1 products for right now.   Alright, before we get too  far, let's see how this looks.   And we do have a Products page and home page  now. But of course, this is completely unstyled.   Let's pause here and start to bring over  some of the styles in the next video.   Let's start to move our styles over.   Now our styles are going to live inside of this  assets folder. And I can go ahead and create a   folder inside of there called styles.  Now how do I use styles in my project.   If you come to this app component here, you will  notice that there is a style tag at the bottom   of the component. And these are what is providing  custom styles for the application. If I look in my   browser, this is what is styling and centering  the elements. If I get rid of these styles,   this is what it looks like without  any of those custom styles.   In any Vue component, you can add styles  directly inside of that component.   So if I wanted to do something I could  change all h1 tags to the color of   Blue. And you'll notice this is just plain CSS  here that you can write inside of these Vue files.   Now, if I go here, you can see that this is  an h1 tag, and it has changed to being blue.   Also on the products tag that is blue  as well, because that is another h1.   Now, if I look at this, though, those h1 elements  are nowhere to be found in this component. Those   are actually in other components. But by default,  the style tag globally affects anything in the   application. So if I put a style tag here, even  though it's in the app dot Vue file, anywhere in   my application that has an h1 tag can be affected  by this. Now, this is generally not good practice.   Because if you want to globally change a style,  you should put that in a separate style sheet.   So in some other dot CSS file, here, if I'm  putting styles inside of my app dot Vue file,   generally, what I intend to do is only let it  affect the app dot Vue file. So it won't change   styles in any other component. Right, it will only  affect whatever is in my template in this file.   And that's why I use the scope keyword here.  Now, now that I've added the scope keyword, so   you can see that the text changed back to black.  Because now that I've scoped this, it is only   affecting styles within this Vue component, not  in other components throughout the application.   Now, if I wanted to add an external stylesheet,  let me just go ahead and create a temporary one   here. I'll call this main dot CSS. And let me  paste in my last style. And I'll change the color.   This will not affect my application yet, because  I have to import the CSS file. Now instead of   importing this into one of my HTML files, what  Vue does is allow me to import it directly into   my JavaScript. So generally, that would be this  main.js file, what I can do is import from assets,   styles. And then that main dot CSS, and the Vue,  see ally set up Webpack for me in such a way that   I can import styles directly into my JavaScript.  And it is all handled by the tooling.   So now if I go back to my browser, it's  a little bit darker. But you can tell   that this is purple now. Because I am  importing it globally, into my project   from this main dot CSS file. Those are the basics  of how you import styles into an application. Now,   if I come back to my original static application  with our HTML files that we were using,   if I come to styles here, you can see that these  aren't just CSS files. They are sass files,   for the most part. So how do I get these into  my project if they aren't standard CSS files.   So Vue also has built in ways  of handling this, let me copy   these styles. And I'm going to delete this  styles folder here. And I'm going to paste.   So I pasted in this styles folder from my other  project. And now if I look in this folder,   there is one file called style dot SCSS, which is  a sass file. And this imports all of the rest of   the files here, all of my other sass files. Now  it is this file that I really want to import into   my project to get all of my styles. I'm going to  comment this out. And now I'll import that sass   file directly from assets slash styles, slash  style dot s CSS. I'll save that. And now you   can see that it is giving me an error saying can't  resolve sass loader so it's trying to load those   sass files. But since they aren't regular CSS, we  have to add another module to be able to import   those files. And that is like it says SAS loader.  If we look in the Vue COI documentation, and go   to working with CSS under development, we can see  that it has this section on pre processors. Now,   as it mentioned, we can select our preprocessor  when we're creating the project, meaning when we   ran that first Vue, create a project name, that  command would take us through setting up SAS   automatically. Now, since we did not choose  SAS back, then when we were setting it up,   there are ways of adding these packages, which  you can do through this command, npm install,   and then installing the sass loader. And also the  sass package. Now, if I scroll down a little bit,   it is giving me this note about Webpack  four, which is what I'm using in vcli. Four,   I have to make sure I have a compatible version  of these loaders. So I am going to go ahead and   grab this npm install command where I can install  sass loader at a specific version and also sass   and installed those packages for me. Now I  should be able to run my server once again.   NPM run serve. Now it is complaining that I don't  have one specific CSS module, because I haven't   installed it in my node modules. But that is  actually a good sign because that means that   it is reading through the rest of my file here,  it's reading through this, getting to this line   and saying, Hey, I can't find that file. So I'm  just going to comment that out for right now.   And now we have one more error here. And  that is it's looking for images that it   can't find right now. Let's go ahead and  resolve those. And they're coming from   this file. So if I go to splash dot sass,  now you'll notice the syntax is a little   bit different here. You can basically think of it  as just an indented syntax without curly braces.   Either way, you can see that the attributes are  the same here. So I have a background image,   it's looking for this image. And again, there's a  background image, which is looking for this green   image. So I'm going to create an images folder  here, an IMG folder, and put those two images   inside of the IMG folder, and then update  this path. So back in my old application,   they were in my public directory, I have  green, and splash. I'm gonna copy those   and paste them here. And I should be  able to reference the relative path here.   close this file. And you can see I have the  styles for my main application in here. Now,   let me do one more thing and get  rid of this boilerplate here.   So I can be ready to put my own content  there. So let me get out of here.   And go to source slash Vues and home, I'll  get rid of this image, also get rid of   that component. I'm just going to put home here  for now and get rid of the component everywhere.   Now if I go back to this page, you can see  that it is ready to add my own custom content.   And I can see the Products page in navigates  as well. One more thing I'll go ahead and do   is add a past orders page to the router at this  route. And all I have to do is basically copy   the products route. This will be past  orders. I can call it past orders.   Past orders. Now I need to create this  component. It's connected to my router. So   I'm going to create it in the Vues folder.  Call it past orders that Vue and I have   a shortcut snippet here. I'll show you To  use us and second, but if I click enter,   it just created the template tag for me. And I'm  going to put an h1 in here that says, past orders.   And now I have this page working. So all  three pages are there. In the next video,   I'll be putting content on these pages, and then  hooking them up to JavaScript to be functional.   Now, let's work on putting  actual content on this homepage.   I'm in the original application. Now, let me go  to source inside of Vues here, I have my pages,   actually, the main page is still in app dot  html. So I'm going to go ahead and grab these   two container elements here, the div and the main  container, copy those, go over to my new code,   my vcli project. And here, I can come to  my homepage, and just paste that in here.   Alright, now take this, just the indentation, get  rid of that old word. And now I have my splash   container. And also my main container.  And nothing is showing up on the page.   So if I look in the dev tools, it says  cannot read property slice of undefined.   And I can search for where that is being used. And  inventory dot slice. So of course, it is broken   right now because I don't have any inventory.  So let me grab that from my original code base.   If I go here, I can see in food dot JSON, this  file is really where I have my inventory items.   So I'm going to copy this  file, copy, go over here.   And inside of source, I'm just going to paste  that file. And now I need to import this into   my Vue j s. So if I want this right now in my home  component, I need to import it at the bottom here.   So let me import my data. So import food from  go up a directory food, that JSON. Let's set   it equal to a data variable. So data and then I  can return. And then I can set inventory equal to   food. Okay, let's try this out. And now we  see the banner displays just fine. And we   can see our recommended Products section at the  bottom, which is already displaying real data.   Because we already set this up. And this is  basically the same logic as with the other app.   But we've only rewritten this  in a component structure.   Now let's pull in the other pages really quick.  So we have past orders, and also products.   Let's go to products. And if I go to the Products  page, I can just grab this main section here,   go back over to my code, and then paste that  in. Now this page should work as it is because   if I look at all of the code here, we never  made that dynamic. So that's something that   we will have to change later. But this is  all hard coded. Let me grab the past orders   page real quick. And then we can take a look at  it in the browser. So if I go to past orders,   let me fold this main section. I'm gonna copy  this and go over here to my code. Paste that.   And now let's take a look at these pages. Okay,  so our past orders page has an error. And it's   complaining that this eye tag, which was used  for icons generally that it doesn't have a   closing tag, meaning it's not explicitly self  closing and I not explicitly closing it either,   like this TD dag here has a closing TD tag there.  So I'll have to fix that. That's just how Vue   templates work. So let me search for I, and seems  like it's only in two places, which is good.   All I have to do to fix that is  either I could do a closing tag,   things like IMG and I and certain tags don't  really have closing tags. So all I have to do   is make them self closing, since you're never  going to nest anything inside of this tag in   general. So I'm just adding the forward slash at  the end. And I will do that with this AI as well.   And that fixed my error. And  now here's the Products page.   And the past orders page as  well. This is kind of a table Vue   of previous orders. Now what about the sidebar?  Let's add that logic back in in the next video.   In our original application, we had this  sidebar on the right to display our cart.   In this video, we're going to move that  over to our new Vue see ally application.   So I'm in the original code base here. If  I go to any of my files, I can see there's   a sidebar component, which is a custom Vue  component that I define in my app dot j s file,   this sidebar component that I register, and  I can basically use it globally throughout   my application. Now, of course, this is just  regular Vue code. So I could absolutely do   the same thing in my new application. But  there are other ways that I can now create   reusable components. So I'm actually going  to put it in my components folder. instead.   I'm going to copy all of that. Let me go to  components, I have this old HelloWorld component,   I'm going to delete it because  I don't need it anymore.   And then I'm going to create  a new file here and call this   sidebar dot Vue. In here, of course, I need the  template. And I'm going to paste all of that code.   And this is basically all of the cart logic.  Now there are a few things I will need to add,   pass in a dynamic toggle here when the button  is clicked. So let me go ahead and set that up.   Now the first thing I need to do is import  this sidebar component into my application.   And it's going to be globally available  across all my pages. So I'm going to   import it into my app dot Vue file. And I'll  do it below. Actually I do at the bottom here.   I'm going to put sidebar, it has to be  of course self closing here. And also the   convention is to capitalize custom components.  So you can easily see them and see they're even   highlighted differently than anything that is  lowercase that I've pulled in from a library   or that is just standard HTML. I'm going to get  rid of my style tag here and add a script tag.   And now I can import that component. So I'm going  to import sidebar from that slash components slash   sidebar dot Vue. Now another way of writing  this and what you'll see, a lot of times see   in Vue applications. Instead here you'll see  an add sign. Now this is a shortcut kind of   a reference to the source folder. So that way  anywhere in my application, no matter how many   files deep my components are, I don't have to  do anything like dot dot slash dot, dot slash   dot, dot, etc. I can always reference the source  folder with an at symbol. So it will be source   slash components slash sidebar dot Vue. Now any  component that I import into another component,   I need to register it and tell my  Vue application I'm going to be using   this component. And I can do that by setting a  Component Object on this default options object   in Vue. And I can set the sidebar component here,  registering it here or including it in the list of   component notes here just means that I can use  it up here in my template. So how this works   basically this whole object here, it's called  the options object. And any kind of JavaScript   functions or data will get set on this object,  I just want to point out that this is the exact   same as the options object you used in custom  components like this one, except the template   in our dot Vue file is just included at  the top up here inside of this template.   And if we look at this main app component here,  everything inside this object, all of this data,   computed methods, all of this stuff is the options  object. But here we have it to be used globally.   And when we create a vcli application,  we basically get one template,   and one options object per component that we use  to define everything on. Now the thing about this   is that each component only knows about the  JavaScript inside the options object of that   component. So if I create a function here, I can  only use it up here and in no other component,   unless I explicitly pass it into that component to  be used. Just the same way that we pass the data   and functions around to different components when  we were building the static application. And here,   we're going to need to do that, again, because  sidebar requires certain things to be passed in.   Now, if we look, here, we can see  that first there is a V, if Boolean,   there's a function to toggle the sidebar,  when it's clicked, or when the button is   clicked to open or close it. There is also a cart  object for what is currently inside the cart.   There are all of our inventory items,  and then there is a remove item function.   So I'm going to copy all of these things and  paste them over here. And now I need to define   these properties. The first thing is Vf, I need  to create a show sidebar data property here.   And I'm gonna set this just default as true for  right now. So I can see the sidebar. Now I need   a toggle sidebar function. Now, where does  this come from? It has to come from my app   component up here, because I'm passing it in,  basically from app to the sidebar component.   So here's my toggle sidebar function. And I'm just  going to grab all of these functions right now.   And I'll create that methods object.  And I pasted in all of my methods here.   Now, here's another tricky part because I want  to reference inventory here. But unfortunately,   I only have it in my home component, which I  just kind of quickly put there to fix my issue   of basically inventory being undefined. So I'm  going to have to restructure my application. So   I'm not importing inventory separately into each  component. So let me actually take this import.   And I'm going to just import inventory into my  app dot Vue component. So I'm importing it here.   And then my logic here, so inventory food.  And I'm going to add that to that as well.   So inventory is food. Now I need to get it   to my home component. But it's not really a  registered component on this page, like sidebar,   I can easily pass elements into sidebar as props,  because it's a registered component right here.   But home is a little bit different because the  router is dynamically putting the home component   there. So how do I pass props through the router  then, to whatever component the router loads,   what we're going to do is pass in inventory  into basically any router Vue component.   So I'm going to pass in the inventory  variable And of course, I need to V bind this   to make it actually look for a variable, and  not consider it to just be a string here.   So now I'm passing in inventory. And I need  to accept that in the child component. So   instead of data here, I'm actually going  to have to use props just as I did before,   and have a props object, or I'll just do it as an  array actually. And I have to call it inventory.   There are few more broken elements that I will  have to fix here that the sidebar is expecting,   I have my inventory and remove item. And  I really just need my cart at this point.   Now, if I look in the original version, I  can see the cart is just an empty object.   And then things can be dynamically added  to the cart. But we're going to worry about   dynamically adding things in a minute. But  first, I'll just set it to an empty object.   So let me go to data here and set cart to an empty  object. Really quick, let's go ahead and grab this   computed property as well, because we will need  it. So I'll come down here and put computed.   And let's check this out in the browser. So it's  complaining right now that it can't find this   JSON file. And that's because we are  importing it from the wrong place.   And yeah, the app is running products,  past orders, everything seems to be working   okay. However, we don't have the sidebar yet. So  let me go ahead and uncomment, this code here.   So we have toggle sidebar, and also showing  the quantity and the button here. So here,   I should be able to see the button that we had  before in our previous application. Alright,   when I come here, and refresh, nothing shows  up. So we have some kind of an issue. It says   uncaught type error kept by path of undefined.  So the path, this is referring to the router.   So I think it's giving us an error in the router  link, because we are not properly using the router   link. So let me just change this to a div, we  basically aren't telling it to route anywhere,   we are just using it as a clickable element.  So we might as well be using something else.   And now it is working. Except I can't click  on the cart button that's not working yet.   But everything else is working. Let me  scroll up to see my original error here. So   it says cannot convert undefined or null to  an object. And this loop is basically inside   of my sidebar component. So it's  complaining about this line here,   line 25. I'm trying to loop through a cart object,  get the quantity and key as well as the index. And   basically it's saying that cart must be undefined  value. So let me take a look in my app here.   It's not opening. So let me actually  take a look at the original code.   And inside of my app dot j s, I  have all of this code moved over   except this mounted here, but I don't need  that anymore, because I can now directly   import the JSON file. I don't need to fetch it.  So here's my sidebar component. And actually,   I didn't copy over any of the methods here  and I'm also forgetting to add in the props.   So let me go ahead and do that. Just  copy this. Go back here to sidebar   and I do need a script tag at the bottom here. So  I'm going to add a script tag, paste in the props.   And then I also want the methods from  here so I'm going to grab those as well.   Now calculate total and get price are defined  Then I also have all of the props here. So   let's see if this works. Yay. And the toggle is  perfectly working. Of course, it's starting off   as open. If I refresh it, it just automatically  opens. So let me change that in app dot Vue.   I'll come here and say show sidebar is false.  All right, let me see if we can use this.   So it's not dynamically adding items to the  cart yet. So we will fix that in the next video.   In this video, we are going to hook up  the add to cart functionality so that   when we add to cart here, it will show up in the  sidebar. If I look in the terminal, right now,   you can see that this add to cart,  it's saying it's not a function.   So I'm getting an error when I click this Add to  Cart button. Now I can see why I'm getting that,   because that is in my homepage component.  And if I go down here, I can see this add to   cart function that I'm calling when I click that  button is not defined anywhere in this component.   Where is that function defined? It is  in the app dot Vue file. So if I go to   my methods, I can see I have an Add To Cart method  right here, I basically need to pass this function   into my homepage for my homepage to be able  to use. So I'm going to also pass that through   the router, as I did before. And then in my  homepage, I can also receive that as a prop.   add that on to the props list, add to cart. So I  should have access to the function that I passed   into this home component now through the router  Vue. And let me refresh and see if this works.   Add To Cart. And you can see that the function is  working because the quantity changed down to zero.   The cart says two items. And if I open it,  it does indeed list two items here. Now,   why are there forward slashes here,  we can actually see in the homepage,   that in regular JavaScript, this is actually in  the sidebar component, that in order to put $1   sign before the variable we needed to escape  it. But we don't have to do that in a Vue j s   application. Because it's no longer in a regular  JavaScript file. It's in our Vue, j s template.   So I can get rid of all of these escaping  characters. And now that looks much better.   Now if I want to delete this, it deletes  I no longer have any items in the cart,   I can add a couple items and I get items  in the cart. If I go to another page,   the cart should still work. Because that  is a shared component that I can see   across any page. In simple applications. This  type of data sharing works pretty well, we can   keep all of our variables in a parent component.  So in this case, in our app dot Vue component,   we pass functions and variables down to children.  And then children can call functions, like add to   cart that will then update the state of the parent  component. Now in more complicated applications,   we would need something a little bit more robust  for state management, and being able to share   all of this data throughout our application.  And we will talk about that in a future series   where we cover Vue x, which is Vue j s is default  state management library. But for right now,   we are going to leave the application as it is  and work on it in future series and lessons.   So we have the homepage, the cart sidebar. Now we  really need to hook up some of the information on   this page. So the Products page And it's really  exactly the same as the product section. Here,   on the homepage, we have all of the same kind  of cards and information. So since we have the   same thing pretty much in multiple places of  the application, it makes sense to pull out   all of this UI that makes up these cards into its  own component. And then we can share it across   the application and on any page that we want.  So let's go ahead and create a card component.   Now in components here, I'm going to create a  new file. And I'm going to call this product   card dot Vue. I'll start with a template.  And now I'm going to go to my home page.   And I can see there's a for loop here that is  looping through and displaying all of the cards.   So I'm going to grab this whole card here  and paste it in my product card file.   Now this is just an individual card. So I don't  need a for loop in here. Let me get rid of this   logic. And this will just be one card. Now  I will need the product information for this   card to display correctly. So I'm going to have to  accept that as a prop in my component. So let me   create a script tag. I'll create props here, just  an array of props. And I'm going to say, product.   So I accept the product props into my component.  And now I can use it in my template. Now, I can   remove all of this logic from here. And the only  thing I need is actually to import that component.   So I need to import product card from, I'm going  to use my source folder shortcut slash components,   and slash product card dot Vue. And now I need  to register this as a component so I can use it.   And now in my code up here,  I'm going to use product card.   I'll clean up the lines a little bit here.   And I need to make this self closing. Because  all tags in Vue templates need to either   be self closing or having a closing tag.  Now I am no longer using this index here,   I'm going to see in my product,  if I'm using the index anywhere.   And I am indeed passing in the  index. So I will need to accept   the index as a prop as well. Let me change  this to index that's a little bit more clear.   And I will get index here. And  I'm going to pass that in here.   Of course index is a variable, not a string, so  have to V bind that. And that should work here.   Let's see if this works. And we are getting  an error here. Now that is because product   is now a prop. And of course we cannot  mutate props from the parent component.   So we can actually fix this by not  mapping to the product prop at all,   we're actually going to create a local  variable inside of this product component. So   each component each time we use the product card  component, it will have its own local variable.   And we can do that by adding a data  prop here. And in the method, we need   it return returns an object. And now we can  simply map quantity because each card only has   one input box. So we'll just map it internally  in the card. And we can check that this works.   Not sure why it only has two cards right now.  But let's try this. So I pressed the number two.   And I can look in my Vue, j. s, Dev Tools.  And I'm getting an error here. And it says   I can't read property name of undefined. So  product name. Yes, I believe I have forgotten   to pass in the correct props here. So let me  add those, I need to pass in product equals   product. And then while I'm here, let me  also add the add to cart function equals   Add To Cart. There we go. And now let's check it  the page loads and the page is loading. Alright,   so now we have all of the cards loading. And  let me just look, in my Vue dev tools, I can see   all of my product card components. So let me  just take a look. If I change this to two,   and I can see the quantity is two. If I change it  to 22, it's now 22. Alright, so that is mapping   correctly. Now I need to get this quantity, the  value up through the home component to the app   component, where I am actually performing  the function of adding it to the cart.   So what I'm going to do, for right  now, I'm just going to pass in a third   parameter, and I will pass in quantity.  And now let's take a look at our function,   our Add To Cart function in the app component.  So we are adding items on to the cart,   if they're not already there. And then we are  basically incrementing the number here. So   now that we have that third parameter being passed  in, which is the quantity, all we have to do   is changed this line to B plus equals quantity,  which is now getting passed in. And then of   course, we don't need this line, because we  are no longer mapping to a nested quantity.   Rather, we have the quantity variable right here.  This also means that we don't need to pass up the   index anymore. So we can remove that from this  function. We only need the name and the quantity   basically, so that we can add it to the cart.  Let's check and see if this works. If I come here,   the number still maps to the  component. Now if I click Add to cart,   it is not in my cart. Let's  see if we got an error.   Add to cart is not a function. Let  me look inside of my home dot Vue.   I have add to cart that I am getting from the  parent component. So from the app component, I'm   passing that in to the product card. And I should  have it Oh right, I didn't accept it as a prop   inside of the product card. So now  let's see if this works. Let me refresh   and go into my Vue dev tools. And now I can see  it's properly working here. If I want to add   10 artichokes, and I have two radishes,   and I have 12 items in the cart. Now my  rounding functionality isn't properly working,   as you can see, but it is properly adding and  displaying the quantity and the total in the   cart. But I don't just want this functionality on  the homepage. I also want it on the Products page.   So let me import those components  into the Products page now.   So if I come to my product stock Vue file, I  actually have access to inventory already in here.   Because if you remember in my app dot Vue  Passing inventory and the add to cart function   into anything displayed by the router Vue,  which is basically any of our pages here home,   past orders or products. They're all connected  to our router. So let's accept those props in the   Products page to start with. First, let me fold  up all of these cards, get them out of the way.   So let me do a script tag, props. And I'm  going to accept inventory and add to cart.   One more thing I need to do is import this product  card. So I'm going to go to the home component,   and just copy this import  and paste it into product   or into the Products page. And now I  need to define this as a component here.   Product card. And this should be components not  component. And I also have one more error here,   which this should be a capital P. And now if I  see if I highlight this, all of these highlight,   let me take a look at what this error is here.  The product card component has been registered,   but not us. So let's fix that. So I  basically have all of these cards here.   For the different items that show up on  the page, I'm actually going to just delete   all of these right now. And instead, I'm going  to add the product card. So if I go to home,   I can take a look at my product card that  I'm actually using inside the template.   And I'm just going to copy that and paste it  here. But instead of slicing at three here,   let me just do the first six elements instead. Now  because we already have inventory being passed in,   as well as the add to cart function, of course  inside the loop, we're taking care of the product   variable, there's really no other state that  we have locally on the products component.   So this should pretty much work out of the box  for us. Let's check here. And we can see that   it does indeed loop through and display all  of the cards on the Products page. Now, let   me add a couple of these items to the cart here.  And you can see the cart just updated with five.   If I add few artichokes, let's add some cherries,  and some cabbage, carrots. everything right,   we have 17 items in the cart now. And we  can see that it added all of these items.   Now if I go to the homepage, I can still see 17  items in the cart. Because we moved to a single   page application. All of our routing is handled  by the Vue JS JavaScript. And we are actually   sharing state between components. So all of the  state for our cart lives in the app component,   which is the parent component of all the  other pages, the home page, the product page.   And that's why all of the items in the cart all  of the data that we save here, in our application,   it stays no matter what page we navigate to.  And even though this is displayed, or this   card is on multiple pages, you can see how have  you made it very easy for us to reuse the same   code and the same template to loop through and  display wherever we wanted on the application.   And that's basically how reusable components  work in Vue js. I hope you enjoyed this course.   And you learned a lot about Vue js, learning it  on three different levels through this course.   We started off working in a basic index dot  HTML file. And then we went on to a static   site of grading it a little bit with some Vue  js. And then we moved on to using the Vue COI   and creating a fully dynamic single page  application that we have here. definitely   reach out to me if you have any feedback,  comments or questions about this course.   You can find me on Twitter and pretty much  everywhere online as Gwen Faraday or at   Faraday Academy. Have a great day and  I hope to see you in the next course.
Info
Channel: freeCodeCamp.org
Views: 96,672
Rating: 4.954845 out of 5
Keywords:
Id: FXpIoQ_rT_c
Channel Id: undefined
Length: 219min 56sec (13196 seconds)
Published: Tue Sep 07 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.