What's up guys? This episode we're diving into another Vue.js episode, and this time we're going to be talking about how to mount Vue components from inside your rails application, this is going to be really interesting because it's something I've learned from the Laravel community on how you can actually have Vue as a wrapper around your entire application's template and then you can automatically mount those components from inside your rails views, and this is really interesting and it makes it even easier to pass in data into your Vue components, so we're going to be exploring this, and it's going to be a pretty awesome improvement over stuff we've done previously, so let's dive in.
First off, I'm just going to go set up webpacker again, we're going to run
rails webpacker:install, and then right after this we're going to run
rails webpacker:install vue and that will go ahead and install everything for us, then we're going to set up our layouts, so we're going to go modify our layouts so we have a wrapper around all of our content, and that content is going to be where Vue gets mounted to Vue, so Vue is going to be kind of this wrapper around all of our content, so let's run
rails webpacker:install vue, that's going to get us set up with everything that we need, and while that's running, let's go ahead and make some adjustments to our rails app.
yarn add vue-turbolinks and we can run
foreman start afterwards to get our rails application loaded. Now, one of the things that I want to point out here is that the way that this works is that we have to create an element with an ID of hello and then we have our component replace that element on the page, this is fine, but we can actually make some really interesting adjustments to this by mounting it to say some sort of single tag on the page, so if we did like a
We could go to our layout for application.erb and then, we can put this and wrap our content of our page with that, so we can say
<div class="container" data-behavior="vue"
that would mount our vue application to this wrapper. This will make the vue application mount across all of our views like index show new and edit and those will be all wrapped in the vue application, so that means that any time we type our components in here, like app, we can then actually register those inside of vue and have them automatically mounted on the appropriate tag. If we have view components that we wanted the app tag to render the app component, we can get rid of the data and components down here and this is going to make it so that these automatically are rendered whenever you come across them, so you can put these inside your layout, you can put them inside your views, and it will automatically mount the vue components to them, which is really cool, so if we go back to our browser, we can load this up and you'll see a "hello vue" is rendered there automatically, and that is really awesome, that means that we can go and paste this in a bunch of times, refresh our page and it's going to show up every single time. One of the benefits though is that we previously had to do like a
<div data-message><%= @object.errors.full_messages.to_json %> and that would be something that we'd have to manually parse out, pass it in as the data into our vue application that we would mount here manually. That stuff I've talked about in previous episodes, and it works, and it's fine, but we can actually improve that if we do this inside of an application tag that's wrapping all of our content, so what we could do instead is we can actually have
<app :message="<%= "hello".to_json %>"></app>
The magic of this is actually going to be that the colon part and the prop name is going to be automatically parsed as json and then available in the props inside of that component, so here we can go into app, we can get rid of this data function, and we can say
props: ["message"] and that's going to give us access to this message that we could then display, so if we refresh our page we get "hello", we could go change this to testing, and refresh our page and we're going to get testing, so it's really cool, so the really nice part about this is that it saves us from having to do the setup and mounting and we don't have to pull the datat attributes off of there and then json parse them and then pass them into the view instance as data, we can have that automatically handled for us by just the normal way that vue.js works, so that is really cool and saves us a lot of time and code from our client side, another cool thing is that if you wanted to do something like
1.upto(10).each do |i|, you can actually have rails render a bunch of these components, and then have dynamic content for each one, so if you wanted to have components for some item on your index page, you can loop through all of your items in rails just like you normally would, and then each item could then be rendered out using vue components like so, so you could have this, where it displays 1 through 10 because we're using a rails loop to create 10 of those items of the app component tag on the page with the necessary json in it, so it's really neat and a great way to integrate rails and vue.js in together. Now, another feature that I want to point out here is that we can actually do a special thing called
<app inline-template> here, where our app is going to be ignoring the template inside of our vue single file component, and this is really interesting because that allows us a lot more freedom the way that we might want, so we might want to say, well in this case we want our message to be in an h1 for this version of it, so we'll have our message up here,
<app inline-template :message"<%= "GORAILS".to_json %">
It's kind of interesting a different approach that you might want to take using Vue.js in there, it makes for a light coupling between the two, but it allows them to talk to each other really really easily and can save you a lot of trouble as you go and add more interactive stuff into your app, in effect you're almost building out your vue components, sort of like you would with Stimiulus, where you can just drop them in wherever you might need to into your application, and that I think is pretty awesome and saves a lot of trouble, I've been using this in Hatchbox as I've been building it, so I wanted to talk to you guys about this, because I first learned about this in Laravel where they're doing that around their applications and I though that was pretty cool, so I hope you enjoyed this episode, if you want to see more Vue.js stuff let me know in the comments below, and I will talk to you guys in the next episode. Peace
Transcript written by Miguel
<table> <row-component></row-component> <row-component></row-component> </table>
<row-component></row-component> <row-component></row-component> <table></table>
Using this approach, how would you get rails data into a component?
Eg. In "Using VueJS for Nested Forms in Rails: Part 1" you get a reference to the form div element and then parse the element dataset. But with this approach the element could be anything and how would you get a reference to the element in a SFC?