-
Notifications
You must be signed in to change notification settings - Fork 35
Vue is lightweight, simple to understand, and doesn't try to take over your app. As such it is a very good fit to start making an existing Rails app more dynamic. This filter assumes that you either know Vue, or read up on it while reading this. We'll go through some of the examples that are mentioned in the vue docs.
One of the main features of the vue filter is that it lets you structure the vue app or component as a ruby class.
Instance methods of the class, become data members for Vue. The initialize
method becomes the data()
method in vue.
class App < Vue
el '#app'
def initialize
@message = 'Hello Vue! Ruby2Js here.'
end
end
becomes:
var App = new Vue({
el: "#app",
data: function() {
return {
message: "Hello Vue! Ruby2Js here."
}
}})
For the above example to work, we had to derive from Vue class, and the class name became the js variable name. This works well for apps. But what if you want to write a Vue component.
The filter detects if your class has a render
method, or a template definition.
class FooBar<Vue
def render
end
end
var FooBar = Vue.component("foo-bar", {
render: function($h) {
return $h("span", [])
}
})
class TodoItem <Vue
template '<li>{{ todo.text }}</li>'
end
var TodoItem = Vue.component("todo-item", {
template: '<li>{{ todo.text }}</li>'
...
})
notice also how the class name becomes the variable name, as before, but also the component name in kebab-case (as per Vue convention)
Props (for components) work in a similar way, as if it were a class method:
class TodoItem <Vue
props [:message] #OR
props message: String #OR
props message: {type: String , required: false}
end
all transform into what you would expect.
In Vue you can use computed values. These are methods that take no argument and the return value is cached.
Vue lets you define methods, which may take arguments, but are not cached. They are still reactive though, which is great.
Ruby2js will sort instance methods, so that methods with arguments become vue methods, and methods without arguments become computed properties. Like this:
class Todo < Vue
options el: ".start"
def initialize
@arr = [1,2,3]
end
def calc_something(a,b)
return a +b
end
def sum_of
return @arr.inject(0) { |sum , item | sum + item }
end
end
const Todo = new Vue({
el: ".manage_start",
data() {
return {arr: [1, 2, 3]}
},
methods: {
calc_something(a, b) {
return a + b
}
},
computed: {
sum_of() {
return this.$data.arr.reduce((sum, item) => sum + item, 0)
}
}
})
And while this is really handy in 95% of the cases, sometimes you need methods without arguments, because they may return values that should not be cached (and cause weird bugs if they are). You can just defined the method with and argument that you don't use, which doesn't even have to be passed on invocation.
Vue let's you define lifecycle hooks. Eg when the method mounted
is defined, it will be called when the component or app is mounted. The full list is on vue.js or https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/vue.rb . When a method with this named is defined, it will be hoisted into the constructor, and not be part of the methods hash.
To call Vue dollar functions like $emit (for events) use the Vue
class as receiver instead, so
this.$emit(arg)
becomes Vue.emit(arg)
Vue can be used with templates and the template language, or component may define a render method and generate the dom directly. To this end Ruby2js lets you use wunderbar dsl.