вычисляемая функция выполняется в одном компоненте, но не в другом

1

У меня есть несколько компонентов на странице, и я обнаружил, что обновления родительского объекта отражаются в одном из компонентов, но не в другом.

На главной странице PatientEditor.vue представлены следующие компоненты:

                <notes-editor v-model="pt" />
                <chart-completion v-model="pt" arrange="horiz" />

и имеет этот скрипт:

module.exports = {
  props: ["pt"]
};

Таким образом, объект pt находится в родительском объекте и передается нескольким компонентам в виде v-model

Компонент ChartCompletion.vue работает хорошо. В нем есть все.

module.exports = {
  props: ["value", "arrange"],

  computed: {
    completed_notes: function() {
      return this.value.notes.filter(function(note) {
        return note.signed_at;
      }).length;
    },

Мой проблемный ребенок, однако, является шаблоном NotesEditor.vue который содержит следующее:

module.exports = {
  props: ["value"],

  computed: {
    completed_notes: function() {
      return this.value.notes.filter(function(note) {
        return note.signed_at;
      }).length;
    }
  },

Не уверен, важно ли это, но объект notes заполняется из вызова ajax в другом компоненте, например:

      this.value.notes.splice(0, this.value.notes.length, ...response.body.notes);
      this.$emit("input", this.value);

Sooooo, вот проблема.

Когда this.value.notes обновляется, результаты видны в компоненте ChartCompletion, но они не видны в компоненте NotesEditor. Когда я использую отладчик Vue в chrome, я вижу, что объект заметок изменен, но по какой-то причине вычисленное свойство не перезапускается, хотя оно имеет идентичное определение в компоненте ChartCompletion. Кроме того, у меня есть v-for в NotesEditor который тоже не меняется.

Каков наилучший способ отладить это?

EDIT 1 - включая компонент NotesEditor

<template>
  <span>
    <table class="table">
      <thead>
        <tr>
          <th>Date</th>
          <th>Status</th>
          <th>Audio</th>
          <th>Text</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="n in value.notes" :key="n.id">
          <th>{{n.created_at}}</th>
          <td>{{n.note_status_id}}</td>
          <td>
            <span v-if="n.audio_length > 0">
              <audio controls="controls" preload="none">
                <source :src="audioURL(n.id)" type="audio/webm"> Your browser does not support the audio element.
              </audio>
              ({{n.audio_length}}s)
            </span>
            <span v-else>
              None
            </span>
          </td>
          <td>
            <span v-if="n.note_text">
              <button data-toggle="tooltip" :title="n.note_text" class="btn btn-outline-primary btn-sm" @click.prevent="openChartEditor(n.id)">
                <span class="glyphicon glyphicon-edit"></span> Edit Note ({{ n.note_text.length }} chars)
              </button>
            </span>
            <span v-else>
              <button class="btn btn-primary btn-sm" @click.prevent="openChartEditor(n.id)">
                <span class="glyphicon glyphicon-pencil"></span> Create Note
              </button>
            </span>
          </td>
        </tr>
        <tr>
          <td colspan="3">
            <record v-model="value" />
          </td>
          <td>
            <button class="btn btn-primary" @click.prevent="openChartEditor(0)">
              <span class="glyphicon glyphicon-pencil"></span> Create Note
            </button>
          </td>
        </tr>
      </tbody>
    </table>
  </span>
</template>


<script>
module.exports = {
  props: ["value"],

  data: function() {
    return {
      sendFaxWorking: false
    };
  },

  computed: {
    completed_notes: function() {
      return this.value.notes.filter(function(note) {
        return note.signed_at;
      }).length;
    }
  },

  methods: {
    audioURL: function(id) {
      return "/notes/getAudio/" + id;
    },

    openChartEditor: function(id) {
      this.$root.$emit("showEditor", id);
    }
  }
};
</script>

<style>
audio {
  vertical-align: middle;
  border: 0;
  margin: 0;
}
</style>
  • 0
    ваше v-for использует :key= ? также this.value.notes.splice( мутирует реквизит, вместо этого создайте новый, который вы затем $emit
  • 0
    Действительно ли вычисленные свойства используются в обоих компонентах? Они ленивые, поэтому они будут обновляться только в случае необходимости
Показать ещё 7 комментариев
Теги:
vue.js
vuejs2
vue-component

1 ответ

0
Лучший ответ

Я не думаю, что это хороший ответ, но он работает. Я добавил функцию наблюдателя, которая вызывает $forceUpdate()

  mounted: function() {
    this.$watch("value.notes", this.$forceUpdate);
  },

Ещё вопросы

Сообщество Overcoder
Наверх
Меню