WEBVTT NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com 00:00:01.096 --> 00:00:05.146 align:middle As we've seen, it's totally possible to configure the Vue instance 00:00:05.306 --> 00:00:07.516 align:middle and put the template in the same file. 00:00:08.136 --> 00:00:11.816 align:middle But... this is going to get crazy as our app grows: 00:00:12.206 --> 00:00:16.536 align:middle can you imagine writing 100 lines of HTML inside this string... 00:00:16.666 --> 00:00:18.426 align:middle or more? Yikes! 00:00:19.326 --> 00:00:26.256 align:middle Fortunately, Vue solves in a unique, and pretty cool way: with single file components. 00:00:27.176 --> 00:00:30.806 align:middle Inside the js/ directory create a new folder called pages/, 00:00:30.806 --> 00:00:34.046 align:middle and then a file called products.vue. 00:00:34.046 --> 00:00:38.456 align:middle We'll talk more about the directory structure we're creating along the way. 00:00:39.436 --> 00:00:44.646 align:middle Notice that .vue extension: these files aren't really JavaScript, 00:00:45.066 --> 00:00:48.106 align:middle they're a custom format invented by Vue. 00:00:48.836 --> 00:00:51.176 align:middle On top, add a <template> tag. 00:00:52.436 --> 00:00:58.786 align:middle Then, copy the h1 HTML from the original file, delete the template variable, and paste here. 00:00:59.766 --> 00:01:01.816 align:middle Next, add a <script> tag. 00:01:02.856 --> 00:01:08.176 align:middle Anything in here is JavaScript and we'll export default an object 00:01:08.406 --> 00:01:10.326 align:middle that will hold our Vue options. 00:01:10.856 --> 00:01:16.656 align:middle Copy the data() function, delete it, and move it here. 00:01:17.826 --> 00:01:18.446 align:middle That's it! 00:01:18.926 --> 00:01:23.806 align:middle I know, the format is a bit strange, but it's super nice to work with. 00:01:24.756 --> 00:01:28.966 align:middle On top, the <template> section allows us to write HTML just 00:01:28.966 --> 00:01:30.946 align:middle like if we were in a Twig template. 00:01:31.746 --> 00:01:35.516 align:middle And below, the <script> tag allows us to set up our data, 00:01:35.876 --> 00:01:38.716 align:middle as well as any of the other options that we'll learn about. 00:01:39.326 --> 00:01:42.326 align:middle This is a fully-functional Vue component. 00:01:43.066 --> 00:01:48.016 align:middle Back in products.js, to use this, first, import it: import App - 00:01:48.806 --> 00:01:51.456 align:middle we could call that variable anything - from '. 00:01:51.816 --> 00:01:54.196 align:middle /pages/products. 00:01:55.306 --> 00:01:59.166 align:middle Thanks to Encore, we don't need to include the .vue extension. 00:01:59.166 --> 00:02:04.916 align:middle Now, inside of render, instead of worrying about compiling the template and all this boring, 00:02:04.916 --> 00:02:10.736 align:middle crazy-looking code, the App variable already has everything we need. 00:02:11.206 --> 00:02:13.296 align:middle Render it with return h(App). 00:02:13.676 --> 00:02:15.876 align:middle That feels good! 00:02:16.586 --> 00:02:19.736 align:middle Let's try it: move over, refresh and... 00:02:20.166 --> 00:02:21.896 align:middle it still works! 00:02:22.786 --> 00:02:27.536 align:middle From here on out, we're going to do pretty much all our work inside 00:02:27.536 --> 00:02:31.726 align:middle of these .vue files - called single file components. 00:02:32.706 --> 00:02:38.516 align:middle One option that we're going to add to every component is name: set it to Products. 00:02:39.386 --> 00:02:43.536 align:middle We could use any name here: the purpose of this option is to help debugging: 00:02:43.976 --> 00:02:48.246 align:middle if we have an error, Vue will tell us that it came from the Products component. 00:02:49.046 --> 00:02:53.156 align:middle So, always include it, but it doesn't change how our app works. 00:02:54.076 --> 00:03:00.106 align:middle Before we keep working, there are two small changes I want to make to products.js. 00:03:00.106 --> 00:03:04.186 align:middle First, the el option: it tells Vue that it should render 00:03:04.296 --> 00:03:07.476 align:middle into the id="app" element on the page. 00:03:08.046 --> 00:03:11.986 align:middle This works, but you usually see this done in a different way. 00:03:12.856 --> 00:03:17.946 align:middle Remove el and, after the Vue object is created, call . 00:03:18.136 --> 00:03:21.736 align:middle $mount() and pass it #app. 00:03:22.806 --> 00:03:27.956 align:middle I also like this better: we first create this Vue object - which is a template 00:03:27.956 --> 00:03:33.086 align:middle and set of data that's ready to go - and then choose where to mount it on the page. 00:03:34.146 --> 00:03:38.826 align:middle Second, because the render() method only contains a return line, 00:03:39.176 --> 00:03:45.036 align:middle we can shorten it: render set to h => h(App). 00:03:46.756 --> 00:03:52.996 align:middle That's effectively the same: it uses the arrow function to say that render is a function 00:03:52.996 --> 00:03:56.846 align:middle that accepts an h argument and will return h(App). 00:03:57.956 --> 00:04:03.436 align:middle I'm mostly making this change because this is how you'll see Vue apps instantiated on the web. 00:04:04.526 --> 00:04:11.696 align:middle Next, let's get to work inside our single file component: we'll add the HTML markup needed 00:04:11.696 --> 00:04:16.406 align:middle for our product list page and then learn how we can add styles.