在所有组件中更改Vue原型变量

时间:2018-03-13 12:53:45

标签: vue.js vuejs2

我想在整个页面中更改下面的全局变量

Vue.prototype.$color = 'green';

我尝试使用下面的代码,但它只在我创建的组件中更改

watch: {
   cor(newValue, oldVlue) {
       this.$color = newValue;
   }
}

我是否可以创建一种在页面的所有组件中更改原型变量的方法?

4 个答案:

答案 0 :(得分:7)

要让$color全球可用,您可以使用Mixin,更具体地说是Global Mixin

如果您只希望它是只读的,那么这是最简单的解决方案(代码较少)。请参阅代码段:

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实例来保存“共享”数据。之后,创建一个带有计算属性的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>

答案 1 :(得分:3)

由于您可能希望$color成为一个不仅可用,但在所有组件中具有反应性(以及相同)的属性,因此可能的解决方案是使用快速/小型Vuex store

下面有一个可运行的例子。在其中,您将看到三个不同的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>

答案 2 :(得分:3)

如果要使用反应性全局变量,则Mixins可能不是一个好主意。因为即使您正在使用全局Mixins,Vue也会在每次装入新组件时(实际上是每次创建新变量$ color时)导入并注入此Mixin。

我相信与Vue.prototype结合使用的可变数据类型(对象或数组)可以达到目的: 在您的main.js文件中:

Vue.prototype.$color = {value: "black"};

在您的* .vue文件中:

this.$color.value = "red"

在另一个* .vue文件中:

console.log(this.$color.value); // "red"

答案 3 :(得分:0)

如果需要全局反应变量,则可以在子组件内部使用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。