vuejs原型阵列没有被观看

时间:2017-07-18 20:07:43

标签: javascript vue.js

在我的vuejs程序中,我正在尝试创建一个警报/通知系统的全局实例。这将是应用程序的最根本实例。然后我的计划是推送到一个对象数组并将其传递给组件。 这只有一半有效。

在我的app.vue中我有

<template>
  <div id="app">
    <alert-queue :alerts="$alerts"></alert-queue>
    <router-view></router-view>
  </div>
</template>

在我的main.js中我有

exports.install = function (Vue, options) {
  Vue.prototype.$alerts = []
}

和我的alert_queue.vue是

<template>
  <div id="alert-queue">
    <div v-for="alert in alerts" >

    <transition name="fade">
      <div>
        <div class="alert-card-close">
          <span @click="dismissAlert(alert)"> &times; </span>
        </div>
        <div class="alert-card-message">
          {{alert.message}}
        </div>
      </div>
    </transition>

  </div>
  </div>
</template>

<script>
export default {
  name: 'alert',
  props: {
    alerts: {
      default: []
    }
  },
  data () {
    return {
    }
  },
  methods: {
    dismissAlert (alert) {
      for (let i = 0; i < this.alerts.length; i++) {
        if (this.alerts[i].message === alert.message) {
          this.alerts.splice([i], 1)
        }
      }
    }
  }
}

</script>

我现在可以使用this.$alerts.push({})添加到此列表中,我可以看到它们是通过console.logging结果添加的。

问题是该组件无法识别它们,除非我手动进入并通过更改代码中的某些内容并让webpack重新加载结果来强制刷新它。据我所知,没有办法以编程方式执行此操作....有没有办法让原型组件像应用程序的其余部分一样被监视?

我试过让root文件中有一个$ alerts对象但是当我使用$root.$alerts.push({})时它不起作用,因为$ root是readonly。

还有其他方法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

您可以使$alerts成为Vue实例并将其用作事件总线:

exports.install = function (Vue, options) {
  Vue.prototype.$alerts = new Vue({
    data: {alerts: []},
    events: { ... },
    methods: { ... }
  })
}

然后在您的组件中,您可以调用方法this.$alerts.addAlert(),然后方法将推送到数组并广播事件alert-added。在其他地方,您可以使用this.$alerts.on('alert-added', (alert) => { ... }

除此之外,我认为这是Vuex的一个很好的用例,它非常适用于此:https://github.com/vuejs/vuex

答案 1 :(得分:0)

Vue.prototype上定义的属性不像Vue实例的数据属性那样具有反应性。

我同意,在大多数情况下,杰夫的方法或使用Vuex是可行的方法。

但是,您只需将this.$alerts设置为Vue实例的数据属性,然后通过关联更新该属性(成为被动的)将更新全局$alerts数组:

&#13;
&#13;
Vue.prototype.$alerts = ['Alert #1'];

Vue.component('child', {
  template: `<div><div v-for="i in items">{{ i }}</div></div>`,
  props: ['items'],
})

new Vue({
  el: '#app',
  data() {
    return {
      globalAlerts: this.$alerts,
    }
  },
  methods: {
    addToArray() {
      this.globalAlerts.push('Alert #' + (this.globalAlerts.length + 1));
    }
  }
})
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<div id="app">
  <child :items="$alerts"></child>
  <button @click="addToArray">Add alert</button>
</div>
&#13;
&#13;
&#13;