Skip to content

Instantly share code, notes, and snippets.

@codebryo
Created October 11, 2018 11:02
Show Gist options
  • Save codebryo/34637e47a8288c8306de6213f7337ec1 to your computer and use it in GitHub Desktop.
Save codebryo/34637e47a8288c8306de6213f7337ec1 to your computer and use it in GitHub Desktop.
Rails vue_app helper support
/* globals Vue, Vuex */
import { merge, entries } from 'lodash'
const rootNodeSelector = '#page[vue-app]' // Entry point on the page to support global components
let iterator = 1
window.appHasBeenSetupOnce = false // Added support for loading multiple apps on one page
function setup (rootComponentNeedSeperateMount) {
window.appHasBeenSetupOnce = true
Vue.use(Vuex)
if (!rootComponentNeedSeperateMount) return
/* eslint no-new: 0 */
// Leverage Global Vue Components
if (document.querySelector('header.header')) new Vue({ el: 'header.header' })
if (document.querySelector('[vue="alert-container"]')) new Vue({ el: '[vue="alert-container"]' })
}
export function app (
component,
customStore = {},
nodeSelector = rootNodeSelector
) {
const node = document.querySelector(nodeSelector)
if (!node) return
if (!window.appHasBeenSetupOnce) setup(nodeSelector !== rootNodeSelector)
// Basic Root store
// Extended with some custom values that should be available in every store
const defaultStore = {
state: {
staticValues: {}
},
getters: {
static: state => state.staticValues
},
mutations: {
setStaticValues (state, data) {
entries(data).forEach(([key, value]) =>
Vue.set(state.staticValues, key, value)
)
}
}
}
const store = merge({}, defaultStore, customStore)
// Basic Root instance
const instance = {
name: `App ${iterator}`,
store: new Vuex.Store(store),
components: {
appView: component
}
}
iterator++
return new Vue(instance).$mount(node)
}
html
head
body
div#page[vue-app]
... Page Content comes from whater source
= vue_app :example,
prop1: 1,
':obj-prop': @data.to_json
= javascript_pack_tag 'vendor'
= javascript_pack_tag 'application'
- if custom_packs.any?
- custom_packs.each do |pack|
script[async src=asset_pack_path("#{pack}.js")]
module ApplicationHelper
def custom_packs
@custom_packs || []
end
def add_javascript_pack(*packs)
@custom_packs ||= []
@custom_packs += packs
end
def vue_app(app, props={})
app_name = app.to_s.gsub(/\_/, '-')
add_javascript_pack(app_name)
options = {
'v-cloak': true,
id: "app-#{app_name}"
}
content_tag 'app-view', nil, Hash[props].merge(options)
end
end
import { app } from '../lib/app'
import Store from '../apps/example/store'
import Example from '../apps/example'
app(Example, Store)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment