Skip to main content
Using VueJS with Rails:

Vue.js Components in Rails Views

Episode 239 · April 12, 2018

Learn how to deeply integrate your Vue.js components with Ruby on Rails views

VueJS Javascript


Earn a free month

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.

I'm going to go to our head tag and what we're going to do is just grab this JavaScript include tag and we're going to change it to JavaScript pack tag lo load our webpacker pack, then we can go into app/javascript and go into our packs. Now hello_vue.js is where it has some examples for this, and we're going to grab this example down here at the bottom that uses Vue Turbolinks and we're going to pull that into our application.js file, so we're going to actually set that up in here instead. This has your traditional turbolinks load, create a view app, and you have to mention the components here, and that's going to be what it renders and all of that stuff. One of the dependencies that we have is the Vue turbolinks package, so we're going to run 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

el: '[data-behaviour="vue"]'

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 %">

Then, we can refresh the page and we're going to see GORAILS in really big font because it's an h1 tag, and this is overriding the single file components template as well, so if you wanted to, you can actually have rails code insideo of your app templates or your vue component templates, and so you could have your image tags in here that would be harder to pass over into vue js, you could actually use them inside of here if you wanted, you could use form-for if you wanted as well, or form-with, we do any of that type of thing because you were inside of a rails vue, and that's really interesting and something that you might want to do or might take advantage of in certain situations. For the most part I would just render all of these as single file templates and keep that template along with the code to process it and the styles in single file components, but there are opportunities where using an inline template can come in handy, and so I wanted to point that out and talk about that because that is something that you could consider doing in your application. Now before we go, I just wanted to point out how clean this ends up being compared to the old style of doing things that I was previously showing in episodes. Now, this old style is basically the same thing we would still register our components but we were doing them inside of our Vue instance, and then we were specifying a template and saying: Whenever you find this element of id of hello, then we're going to go mount and replace that element with our new template here which was just rendered out this app component, and this works fine, but we can actually simplify that a lot by number one having that element always on every page, so it wraps all of our content which means that we can use vue there if we want, but we don't have to use any vue components, and so this ends up being, we don't have to check every page anymore, that is handy and the json parsing that we previously had to do to load say the message would have had to come inside of this if statement, we need to make sure the element exists, then we need to check it's data sets and grab the message here, and then we would have had to pass that into like the data object, something like this, where we would specify the message is the message, and that is fine, but it was kind of messy to set up, and we can simplify a lot of that stuff into just a really really showrt vue method here where we set up vue and then rails templates can determine what needs to go where on which page, so this allows you to get rid of kind of all this complexity in your JavaScript and then your views in your rails app can go and determine which vue components should be rendered and which data.

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


Subscribe to the newsletter

Join 31,353+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.