9

Well my question is simple, how to make a Ruby on Rails app work with Vue.js?

The details

I first look at the vue-rails gem, but that add Vue to the rails asset pipeline, and I want to work with other npm packages, like browserify. Then I look to that, browserify-rails that enable commonjs in the js folder app/assets/javascript/. Also I'm planning to make a Vuejs app for every rails controller, and access to backend actions with the vue-resource and vue-router (if this isn't a good approach please let me know), so I added the following line to my layout

<%= javascript_include_tag params[:controller] %>

That will add a js file with the name of the controller, so the UsersController will have the users.js file with the main vue app for that controller.

Then, to try this I scaffolded a Users resource with rails, and make it render json format in every action, like this

def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @users }
    end
end

That is working fine. Then in the app/assets/javascript/ folder I add users.js with the following content

var Vue = require('vue');
Vue.use(require('vue-resource'));

new Vue({
    ready: function(){
        this.$http.get('users.json').then(function(response){
            console.log(JSON.stringify(response));
        });
    }
});

And when I inspect dev console in chrome, I see that Vue is added, but I don't see any response, and I had already inserted one user. By the way, I'm trying with the https://vuejs-rails-yerkopalma.c9users.io/users url (I'm developing in c9.io) and only the /users/index.html.erb file is rendered. So, waht are my guesses:

  1. I might be using vue-resource in a wrong way, I mean the url passed to the get() function.
  2. I might be missing some vue-resource configuration.
  3. Maybe I just should use the vue-rails gem combined with brwoserify-rails but I just don't know how. Any help or guideline would be appreciate.

Here is my application.js file (is also included in my layout file)

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
5
  • In your .then call, you have not specified an error handler. You should add one with logging. Additionally, use your web browser's inspector to look at the actual network requests being made to see that it is formed and sent the way you expect it to be. Commented Dec 31, 2015 at 13:07
  • it is worth noting that vuejs-rails uses outdated vuejs libraries. And if you are using browserify-rails, then you won't be using sprockets/application.js. So you should really choose one way of loading your javascript dependencies. Commented Jan 1, 2016 at 7:47
  • @ytbryan I'm using sprockets and the application.js file (loading jQuery and bootstrap from here) along with browserify rails without problems. Anyway, maybe you are right about just using one way to manage js dependencies, but I don't know why you stated about outdated vuejs libraries. Does browserify rails load an outdated version of Vue.js? Commented Jan 4, 2016 at 12:57
  • 1
    No, I think browserify will load the vue that you made available. So if you have the latest vue available, then browserify will load that. I was looking at vuejs-rails the other day and notice your post. So I thought I should inform you that their javascript are outdated. Commented Jan 4, 2016 at 13:44
  • Oh I get it. Thanks for the catch :) Commented Jan 4, 2016 at 13:48

4 Answers 4

13

For Rails 5.1+, it will come with yarn & webpack support.

Also, with this pull request to webpacker, Vue will be supported out of the box.

To get started with Vue on Rails,

  1. Add gem 'webpacker' to gemfile
  2. bundle install
  3. Run rails webpacker:install && rails webpacker:install:vue

Alternatively with Rails 5.1x, do rails new app --webpack=vue

You will be ready for Vue on Rails 5

Sign up to request clarification or add additional context in comments.

7 Comments

I'm using this way! But I'm having trouble using it together with the turbolinks, do you have any suggestions?
You can start rails app without turbolink rails new app_name -J --webpack=vue Read more github.com/rails/webpacker/issues/161
@AnkitSinghaniya I did so gist.github.com/danieldocki/5389e4a066475caf12b40b929fe744fd I tested it and it worked, does it help?
This video helps show turbolinks & vue youtube.com/watch?v=lGToT9RyDxc not quite what you want since he still uses rails views and the asset pipeline, but you might get something from it
You could also use Vite.js, and add @vitejs/plugin-vue, which provides HMR out of the box. maximomussini.com/posts/a-rubyist-guide-to-vite-js
|
5

I managed to make this work with Vue.js.

first I added an el propertie to the object passed to Vue constructor, and I started to get an error saying that body element was not defined. Obviously the body element is always present in an html file, so I though it was a problem about when the Vue instances were created. So I simply wrapped all on a ready event.

$(document).on('ready page:change', function() {
    var Vue = require('vue');

    Vue.use(require('vue-resource'));       

    new Vue({
        el: 'body',
        data: {
            users: []
        },
        ready: function(){
            this.$http.get('users.json').then(function(response){

                console.log(JSON.stringify(response.data));
                this.users = response.data;
            }, function(response){
                console.log("fail");
                console.log(JSON.stringify(response));
            });                
        }
    });        
});

And that works fine!

Because I'm using turbolinks, I also included the page:change event. And in my view index.html.erb I have access to Vue instance. So this make this case working and it's fine for this particular question, however I now have another issue working with .vue components, maybe I'll open another question about it.

Notice that in my index.html.erb view I have access to the Vue instance defined in users.js file in the assets/javascript/ folder, but that I have not access to Vue or any of the js modules loaded with browserify from the views folder

1 Comment

To avoid use both, vue and jQuery, you can attach the event like: document.addEventListener('turbolinks:load', function(){...}
4

Try using the Breakfast Gem. There is an installation section for Vue.js

Basically once you install the gem you can use npm to install Vue, Vuex and the Vue Router quite easily.

And it supports single file Vue components.

Comments

1

Update: gem [vuejs][1] nows ships with vue 2.x and vue-router 2.x.

So I created gem [vuejs][1] because I was using vue.js across multiple projects + prototypes and the gem vuejs-rails doesn't seem to update their gem with the latest version of vue.js.

If you are like me, looking for an easy integration of vue.js with asset pipeline + you want to use the latest vue.js, read on:

Add this line to your application's Gemfile:

   gem 'vuejs'

At application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require vue
//= require vue-router
//= require vue-resource 
//= require_tree .

//= require vue-router and //= require vue-resource are optional.

Note that for vue & vue-router 2.x, you need to require these instead

//= require vue2
//= require vue-router2

That's it. You can try writing some javascript in one of the views to test it out.

Try this one:

<div id="app">
  <h1>Hi {{ message }}</h1>
  <input v-model="message">
</div>

<!-- <span>Message is: {{ message }}</span>
<br>
<input type="text" v-model="message" placeholder="edit me"> -->

<script type="text/javascript">
new Vue({
  el: '#app',
  data: {
    message: 'Bryan'
  }
})</script>

source: https://github.com/ytbryan/vuejs

4 Comments

And what extension should your views have?
Can you elaborate? vuejs simply bring vue.js and its router + resource into asset pipeline. What do you mean by extension?
I mean that components in vue.js apps have a .vue extension, and are loaded with browserify or with webpack. does your gem handle those files? or just bring the vue object to the pipeline? in that case what bout others npm packages? does your gem allow to use third party npm modules?
@yerkopalma Sorry for the late reply. I believe both 'vuejs' and 'vuejs-rails' gems don't ship with vue-template-compiler. Hence, I am not sure if .vue extension is possible with these two gems. Thanks to Rails 5.1+ and webpacker this is made possible with yarn and webpack integration. Please refer to this pull request to see a possible answer to your question github.com/rails/webpacker/pull/107

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.