Reputation: 12329
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:
vue-resource
in a wrong way, I mean the url passed to the get()
function. vue-resource
configuration. 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
Upvotes: 9
Views: 12321
Reputation: 2694
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,
gem 'webpacker'
to gemfilebundle install
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
Upvotes: 13
Reputation: 1369
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.
Upvotes: 4
Reputation: 2694
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
Upvotes: 1
Reputation: 12329
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
Upvotes: 5