Skip to content

Instantly share code, notes, and snippets.

@ace-subido
Last active October 8, 2018 10:40
Show Gist options
  • Save ace-subido/504740df81da3c7061ef74fb7bfcc6df to your computer and use it in GitHub Desktop.
Save ace-subido/504740df81da3c7061ef74fb7bfcc6df to your computer and use it in GitHub Desktop.
Small vuejs components all over your Rails Views

Use this if:

  • You just want a few interactive pieces here and there and you're still rendering everything from the Rails views
  • Your Rails frontend isn't a single-page VueJS application

Note: This works if your app has a rails/webpacker and VueJS installed

Usage

In your views:

= vue_component component_name: "my-component", props: { hello: "world" }

In your webpacker app/javascripts/packs/application.js

import MyComponent from "../components/MyComponent"
import VueMounter from "../services/VueMounter"

let mounter = new VueMounter()

mounter.setWatchList({
  "my-components": MyComponent,
})

mounter.mountComponents()
module VueComponentHelper
def vue_component(component_name:, props: {}, html_options: {})
html_options[:data] = {} if html_options[:data].blank?
html_options[:data].merge!(
vue_component: component_name,
vue_props: props.to_json,
)
html_options[:id] = ["vue", component_name].join("-")
html_tag = html_options[:tag] || :div
html_options.except!(:tag)
content_tag html_tag, "", html_options
end
end
import Vue from "@vue"
class VueMounter {
constructor() { }
setWatchList(vueComponents) {
this.vueComponents = vueComponents
}
mountComponents() {
var vueComponents = document.querySelectorAll("[data-vue-component]")
if (vueComponents.length <= 0) { return }
vueComponents.forEach((vueComponent) => {
this.mountComponent(vueComponent)
})
}
mountComponent(vueComponent) {
let name = vueComponent.getAttribute("data-vue-component")
let props = JSON.parse(vueComponent.getAttribute("data-vue-props"))
var componentObj = this.vueComponents[name]
Vue.component(name, componentObj)
new Vue({
el: `#${vueComponent.id}`,
render: (createElement) => {
return createElement(name, { props: props })
},
})
}
}
export default VueMounter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment