Next lesson playing in 5 seconds

  • Overview
  • Transcript

2.2 Converting a Blade View Into a Vue.js Component

Vue-ifying a Laravel app means converting Blade Views (or partial views) into Vue.js components. I'll show you how to do that in this lesson.

2.2 Converting a Blade View Into a Vue.js Component

The first form that we're going to tackle is for creating and editing pages. Now these aren't blog posts. These are pages like the contact us, or the frequently asked questions, or things like that. So of course we want to log in, the email address is The password is password. And then we can go to Pages and Create New, this is the form. There's nothing extraordinary about this. However, when it comes to the order, we do have the ability to set the order of the pages. So that not only can we specify if a page is going to be before or after an existing page, we can also nest them as well. So if we click on any one of these pages, we will of course see that page's information displayed within the appropriate fields. But notice that Order is not populated. This was just a design choice on my part, and we're going to follow that. So that's going to make things a little bit more simple. So let's just get started. Now, we want to go to resources > views > admin > pages, and then we have two views. One is create, and one is edit. Now technically, these are different forms. But they do use the same form fields. So they are using this partial. And we're just going to take the fields out of this partial and input it into our single file component. Now we're going to do this one form field at a time, just so that we can see what it is that we need to modify from going from our blade view into our view component. But this is where we are going to use our component element. And I don't know what we're going to call that. It might be something like pages-form-fields or something along those lines. One of the hardest things to do in programming Is naming things. And when it come to naming things, I'm horrible at it. So we'll just stick with this name here, pages-form-fields. Now of course we will need to supply this with data, because there are actually two pieces of information that's being fed to this view. The first is the model, which is called model. The second are the pages for that $orderPages field. So what we have listed here is not part of the model, that's something else. And so, we are going to have to feed both of these pieces of information to our component. But we're going to see how to do that, and it's really quite simple. Now let's go to resources > assets > js > components, cuz that is where we're going to put our components because that was already there. And let's add a few other folders, because I do want to keep this organized, kind of how it is with our blade views. So inside of components, let's have a new folder called admin, so that we will put all of our admin related components here. And since this is for pages, let's create another folder simply called pages. And then we will create a file that is going to be for our component. And since we called that, or at least I call it, pages-form-fields. Let's just call that file PagesFormFieldsComponent, or something along those lines. So PagesFormFields and this of course needs the extension of vue. And let's go ahead and define our template. Now our template is kind of like XML, or at least the contents are kind of like XML in that we need a root element. We need something that's going to wrap around all of our other elements. So this is just going to be a div element. And then let's copy, or rather cut and paste our form fields. So let's go to our Fields.blade.php, and let's start with our title field. So we'll just grab that, cut it, and paste it into our template. Now, of course, the very first thing that we should probably address is the value attributes on this input element. Because we are no longer in PHP, we are in JavaScript. So we don't have the dollar sign for the model variable. We don't have the arrow for accessing a property. So we have model.title. Now, in our view components, sometimes we will use the same kind of syntax, where we will have a double set of curly braces. And then whatever value or expression to output. But in this particular case, we don't want that. In fact, if we tried to run this right now, we would be told that we don't need to do that. Instead, what we want to do is bind this value, this model.title to the value attribute on this input element. And the long way of doing that is with v-bind:, and then value=, and then our expression. But notice that Visual Studio Code does not like this. Now I should point out that I am using an extension. I'm not going to try to pronounce it, but that is it, right there. And this has Vue tooling for Visual Studio code. So this little red squiggly is coming from that extension. And if we read the tool tip it says that v-bind directives require an attribute value. So instead of using these curly braces, we can just straight up say model.title and that is going to be fine. Now I said that this is the longhand version. We could just say :value = model.title. That's essentially doing the same thing, so we can just omit v-bind. And we should also have our script element, and we want to export default. Let's go ahead and say props is going to have a property called model. That's how we're going to get our model data there. Now we do need to register this component with Vue. So we do that inside of app, and we can essentially just copy and paste what is already here. But of course we want to make some changes. So we'll say, pages-form-fields, and we will require that file. Now, of course the path needs to be modified so that we say admin/pages and then our file name. But that is going to register our component, and then we can use that within our application. Now, we do need to compile this. And instead of just straight up compiling, I'm going to say, npm run watch. So that any of the changes that we make is going to automatically be updated. So that we don't have to manually come in here and rebuild everything. So let's wait for that to finish, it shouldn't take that very long. And we will see what this looks like in the browser. So let's just hop on back over, and let's refresh the page. Now, everything goes away. And if we look at the developer console, we're going to see that we cannot read property title of undefined. And that's because we didn't pass our model data to our component. So let's go ahead and do that, so that we have some data. But also notice that there's nothing here, it completely wiped out everything that was inside of the form, although that's not necessarily true. If we view the source, or not really the source. We want to Inspect, so let's Inspect. And if we look at the form, we do have some hidden input elements, but everything after that Is gone. So practically everything that is inside of that partial view has been removed from the document. And that's okay because eventually all of our form fields are going to be in our component. So we want to pass our model data here. And we can do that, of course, with model, but what we really want to do is use that v-bind as well. But we can use the shorthand syntax here with :model, but then we want to get our model data here. And that's really quite simple to do. If we use JSON in code, and then pass in the model, that is going to of course pass the data as JSON. But that JSON is going to automatically be converted into an object that is then going to be used within our component. So if we go back and refresh the page, well, we kinda see something that we like, but notice that we actually see the JSON here. So what we have to do instead is use single quotes instead of double quotes, and that's going to fix that. So that's now finally, whenever we refresh the page, we're going to have our title. We see that the value for that title is actually there, but once again we lose all of the other form fields. So now we just need to do basically the same thing for our other form fields. We'll take our URL, and we'll make the same modifications. So that we are going to bind the value of our input element to our model's URL property. And once again we're using JavaScript syntax here. And let's grab the text area and the submit button as well. We will leave the order pages section for our last migration. So let's just paste those two in. Now our text area is going to be a little bit different, in that you'll notice that there's some issues here. Of course, one of those is that it's using PHP syntax. But even when we remove that PHP syntax and use just JavaScript, we're still going to have an issue. Because this is what you might think we would want to do. Because we would use the double curly braces in order to output data. But we can see here from the tooltip that there's an unexpected mustache, use v-model instead. So we will say v-model as an attribute to this element. And then we will specify what the model is for this element, and that is simply model.content. And that's going to solve that particular problem. And as far as our submit button, we just need to leave that alone. So now we just have the ordering information, so let's grab that. Let's cut that, and let's paste that into our component. Now the very first thing that we are going to need to do is address our loop here, because we used a PHP for each. And naturally we cannot do that in JavaScript. Instead, we will use the ability to define a loop with an element. So basically we have this empty option, which we want to leave there. But then we want to list all of our other pages, and we do that very easily with an attribute within this option element, we say, v-for. And then we say, what is essentially our for each expression, except this is JavaScript, remember. So we will say for each page in orderPages. But then, as we are iterating over these order pages, each one needs a key, and we need to bind that. So we could once again say, v-bind. But we're going to use the shorthand syntax, and we say key. Now the key has to be unique, and so naturally, we would want to use the id of the page. But we also want to use that id for the value. And thankfully, all we have to do is bind that to value, and we will change our syntax here. So that you just say simply So we were able to write just one option element, but we're using it as an Iterator. So we're iterating for every item within orderPages. The key is going to be the id, the value is going to be the id. But then we want to just have the text displayed. And so, for right now, we're just going to say page.title, and we'll leave everything else off. But we do want to use our double curly braces here. We are outputting just a value, so we can do that here, and that should be it. Although we do need to define our props here. So we will say that there's another prop called orderPages and we're going to feed that just like we did with our model. So we will say orderPages=, and then we will encode our orderPages as json. And then we will go to the browser and see whether or not if this is going to work. So let's refresh the page, and there we go. However, if we look at the drop-down that is supposed to list our pages, we see that there's nothing here. And that is because of how we used the orderPages prop when assigning data. Now we used camel casing here, which matches the camel casing that we defined inside of the component itself. However, when it comes to the HTML attributes, these are case insensitive. So really what this is is orderpages, all lowercase. And so if we wanted this to match up with our orderPages prop, then we have to use kebab casing, basically just putting a dash between order and pages. So now if we save this and we go back to the browser and refresh, we're going to see our list of pages. But of course these aren't formatted visually, so that we see the nesting and the relationship between a parent and the child. And that is something that we are going to do in the next lesson.

Back to the top