【问题标题】:Change Vue prototype variable in all components更改所有组件中的 Vue 原型变量
【发布时间】:2018-03-13 12:53:45
【问题描述】:

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

Vue.prototype.$color = 'green';

我尝试使用下面的代码,但它只在我创建的组件内发生变化

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

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

【问题讨论】:

标签: vue.js vuejs2


【解决方案1】:

要使$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>

【讨论】:

  • 我不太喜欢 Vuex,所以我使用了来自 #Meteor 的 MiniMongo 和 Mixin,但我必须找到一种 Vue 原生方式作为替代方案,谢谢。
  • Mixins 非常复杂,会拖慢 Vue,难道没有其他方法可以做到这一点吗? Vuex 是怎么做到的?
  • 此解决方案与 可变实例属性 一样有效。感谢您提出好的解决方案!
  • @NickSteele 我认为这有点晚了,但 vuex 解决方案是in other answer to this same question
【解决方案2】:

如果你想要一个反应式全局变量,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"

【讨论】:

  • 由于某种原因,当我测试它时不是这种情况,但不确定我是否做错了什么......
【解决方案3】:

由于您可能希望 $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>

【讨论】:

  • 一个更简单的解决方案是使用计算出的 $color 和 getter 和 setter。然后 j 你只需要 let color = this.$color 和 this.$color = 'red'。使用这种方法不需要 updateColor 方法,因为 setter 会设置 Vuex $color。
  • @Culda-DaisaAndrei 在示例中查看第三个 Vue 实例(查找 #app3)。
【解决方案4】:

如果你想要一个全局反应变量,你可以在子组件中使用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。

【讨论】:

    【解决方案5】:

    在组件中也这样做

    Vue.prototype.$color= 'colorName'

    它对我有用。

    【讨论】:

      猜你喜欢
      • 2018-10-01
      • 1970-01-01
      • 2017-11-30
      • 2018-10-11
      • 1970-01-01
      • 2020-12-15
      • 2021-12-19
      • 2020-07-17
      • 1970-01-01
      相关资源
      最近更新 更多