Change Vue prototype variable in all components
To have $color
globally available, you can use a Mixin, more specifically a Global Mixin.
If you would only want it to be read-only, it is simplest solution (less code). See snippet:
Vue.mixin({
created: function () {
this.$color = 'green';
}
})
new Vue({
el: '#app1',
data: {
message: 'Hello Vue.js!'
},
mounted() {
console.log('$color #app1:', this.$color);
}
})
new Vue({
el: '#app2',
data: {
message: 'Hello Vue.js!'
},
mounted() {
console.log('$color #app2:', this.$color);
}
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app1">
<p>app1: {{ message }}</p>
</div>
<div id="app2">
<p>app2: {{ message }}</p>
</div>
Making $color
reactive
To mave Vue react everywhere to changes to $color
, you could use a Vuex store (see other answer).
But if you don't want to use Vuex just for that, another possibility is to create a Vue instance just to hold the "shared" data. After that, create a mixin with a computed property that references the $data
of this "shared" Vue instance. See demo below.
// not using a Vuex store, but a separated Vue instance to hold the data
// only use this if you REALLY don't want to use Vuex, because Vuex is preferrable
let globalData = new Vue({
data: { $color: 'green' }
});
Vue.mixin({
computed: {
$color: {
get: function () { return globalData.$data.$color },
set: function (newColor) { globalData.$data.$color = newColor; }
}
}
})
// this.$color will be available in all Vue instances...
new Vue({
el: '#app1'
})
new Vue({
el: '#app2'
})
// ...and components
Vue.component('my-comp', {template: '#t3'});
new Vue({
el: '#app3',
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app1">Color: {{ $color }} <button @click="$color = 'red'">change to red</button></div>
<div id="app2">Color: {{ $color }} <button @click="$color = 'yellow'">change to yellow</button></div>
<template id="t3">
<div>Color: {{ $color }} <button @click="$color = 'purple'">change to purple</button></div>
</template>
<div id="app3"><my-comp></my-comp></div>
For completeness, check below to see how using Vuex and Mixin would be (more details on how to use Vuex in the other answer).
// Using a Vuex to hold the "shared" data
// The store is not added to any instance, it is just referenced directly in the mixin
const store = new Vuex.Store({
state: { $color: 'green' },
mutations: { update$color: function(state, newColor) { state.$color = newColor; } }
});
Vue.mixin({
computed: {
$color: {
get: function() { return store.state.$color },
set: function(newColor) { return store.commit('update$color', newColor); }
}
}
})
// this.$color will be available in all Vue instances...
new Vue({
el: '#app1'
})
new Vue({
el: '#app2'
})
// ...and components
Vue.component('my-comp', {template: '#t3'});
new Vue({
el: '#app3',
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.min.js"></script>
<div id="app1">Color: {{ $color }} <button @click="$color = 'red'">change to red</button></div>
<div id="app2">Color: {{ $color }} <button @click="$color = 'yellow'">change to yellow</button></div>
<template id="t3">
<div>Color: {{ $color }} <button @click="$color = 'purple'">change to purple</button></div>
</template>
<div id="app3"><my-comp></my-comp></div>
If you want a reactive global variable, Mixins may not be a good idea. Because even if you are using global Mixins, Vue actually import and inject this Mixin whenever mount new components, which means every time a new variable $color created.
I believe the mutable data types (Object or Array) combined with Vue.prototype can do the trick: In your main.js file:
Vue.prototype.$color = {value: "black"};
In your *.vue file:
this.$color.value = "red"
In another *.vue file:
console.log(this.$color.value); // "red"