【发布时间】:2018-03-13 12:53:45
【问题描述】:
我想在整个页面中更改下面的全局变量
Vue.prototype.$color = 'green';
我尝试使用下面的代码,但它只在我创建的组件内发生变化
watch: {
cor(newValue, oldVlue) {
this.$color = newValue;
}
}
我是否可以创建一种方法来更改页面所有组件的原型变量?
【问题讨论】:
我想在整个页面中更改下面的全局变量
Vue.prototype.$color = 'green';
我尝试使用下面的代码,但它只在我创建的组件内发生变化
watch: {
cor(newValue, oldVlue) {
this.$color = newValue;
}
}
我是否可以创建一种方法来更改页面所有组件的原型变量?
【问题讨论】:
要使$color 全局可用,您可以使用Mixin,更具体地说是Global Mixin。
如果您只希望它是只读的,这是最简单的解决方案(更少的代码)。见sn-p:
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/vue@2.5.15/dist/vue.min.js"></script>
<div id="app1">
<p>app1: {{ message }}</p>
</div>
<div id="app2">
<p>app2: {{ message }}</p>
</div>
$color 反应要让 Vue 随处响应 $color 的更改,您可以使用 Vuex 商店 (see other answer)。
但如果您不想为此使用 Vuex,另一种可能性是创建一个 Vue 实例 来保存“共享”数据。之后,创建一个带有 computed 属性的 mixin,该属性引用这个“共享”Vue 实例的 $data。请参阅下面的演示。
// 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/vue@2.5.15/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>
为了完整起见,请查看以下内容以了解如何使用 Vuex 和 Mixin(有关如何使用 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/vue@2.5.15/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex@3.0.1/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>
【讨论】:
如果你想要一个反应式全局变量,Mixins 可能不是一个好主意。因为即使你使用全局 Mixin,Vue 实际上在挂载新组件时都会导入并注入这个 Mixin,这意味着每次创建新变量 $color 时。
我相信可变数据类型(对象或数组)结合 Vue.prototype 可以解决问题: 在你的 main.js 文件中:
Vue.prototype.$color = {value: "black"};
在您的 *.vue 文件中:
this.$color.value = "red"
在另一个 *.vue 文件中:
console.log(this.$color.value); // "red"
【讨论】:
由于您可能希望 $color 成为一个不仅可用,而且在所有组件中都具有反应性(并且 相同)的属性,因此一种可能的解决方案是使用快速/小型 @987654321 @。
下面有一个可运行的示例。在其中,您将看到三个不同的 Vue 实例,它们将对相同的 $color 变量(即在 Vuex 商店)做出反应。
所有三个示例在功能上都是相同的。我以不同的方式编写它们只是为了描绘使用 API 的不同方式。使用对您来说更直观的方法。
const store = new Vuex.Store({
state: {
$color: 'green'
},
mutations: {
update$color: function(state, newColor) { state.$color = newColor; }
}
});
new Vue({
store: store, // add this so the store is available
el: '#app1',
// explicitly via this.$store
computed: {
$color: function() { return this.$store.state.$color }
},
methods: {
update$color: function(newColor) { return this.$store.commit('update$color', newColor); }
}
})
new Vue({
store, // shorthand for store: store
el: '#app2',
// using helpers mapState and mapMutations
computed: {
...Vuex.mapState(['$color'])
},
methods: {
...Vuex.mapMutations(['update$color'])
},
})
new Vue({
store,
el: '#app3',
// using computed properties, only
computed: {
$color: {
get: Vuex.mapState(['$color']).$color,
set: Vuex.mapMutations(['update$color']).update$color
}
},
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app1">
Color: {{ $color }} <button @click="update$color('blue')">change to blue</button> (explicitly via this.$store)
</div>
<div id="app2">
Color: {{ $color }} <button @click="update$color('red')">change to red</button> (using helpers mapState and mapMutations)
</div>
<div id="app3">
Color: {{ $color }} <button @click="$color = 'orange'">change to orange</button> (using computed properties, only)
</div>
【讨论】:
#app3)。
如果你想要一个全局反应变量,你可以在子组件中使用this.$root。 vuejs 文档中有一个例子:
// The root Vue instance
new Vue({
data: {
foo: 1
},
computed: {
bar: function () { /* ... */ }
},
methods: {
baz: function () { /* ... */ }
}
})
// Get root data
this.$root.foo
// Set root data
this.$root.foo = 2
// Access root computed properties
this.$root.bar
// Call root methods
this.$root.baz()
但请考虑在大多数情况下按照官方文档的建议使用 Vuex。
【讨论】:
在组件中也这样做
Vue.prototype.$color= 'colorName'
它对我有用。
【讨论】: