I have a vue-router enabled app using single-file .vue
components, bundled using browserify. This app is served by a flask webserver, which passes it global config settings (page title, layout order, etc) as JSON. I've been struggling to pass the globals into the app in a clean way.
main.js
(used as entry point for browserify):
var Content = require('./vue/Content.vue');
var App = Vue.extend();
var router = new VueRouter({ history: true });
router.map({
'/': { component: Content, name: 'home' }
});
router.start(App, '#app');
index.html, served by flask webserver
<body>
{% with ga_id = ''|get_env('GA_ID') %}
<div id="app" ><router-view ga-id={{ga_id}} global-settings={{globalsettings|tojson|safe}}></router-view></div>
{% endwith %}
<script type="text/javascript">
window.global_settings = {{globalsettings|tojson|safe}};
</script>
<script src="/js/build.js" defer></script>
</body>
App.vue
, main component of the app:
<template>
</template>
<script type="text/javascript">
var app = {
props: ['gaId', 'globalSettings'],
ready: function ready() {
console.log(this.gaId); //returns expected string
console.log(this.globalSettings); //truncated at first space in the string
console.log(window.global_settings); // returns expected json
},
module.exports = app;
</script>
and for completeness' sake, routes.py
:
@APP.route('/', methods=['GET'])
def index():
settings = APP.app_config['settings']
return render_template('index.html', rawsettings=settings)
It feels wrong to pass Vue a global variable by setting it on the window
, but I haven't been able to pass it in otherwise.
I tried using the data function in Vue.extend
in main.js
:
Vue.extend({
data: function() {
return {
global: 'test'
}
}
})
but this.global
is undefined in App.vue
. Is there a better pattern I should be using?
This feature from Vue.js official API documentation means that inside any component,
this.$root
will reference the root Vue instance, or, in your case, theApp
variable.So, ideally, you want to change this line:
to
and then you can access
global_settings
from any component usingthis.$root.global_settings
.However, depending on how your code is bundled,
App
might return undefined in the global scope. Which leads me to a better point altogether...consider using vuex
vuex is the official state manager for vuejs. Basically it serves as a center for shared state (or data) accross all components, which fits the concept of "global settings" well! Vuex also comes with its very powerful features especially for large scale applications. However, if you don't plan on using vuex extensively, then something like my earlier approach might be more desirable or lightweight.