Как обрабатывать (на данный момент) недостающие данные?

Резюме: я отображаю некоторые данные, которые я получаю от API. Из-за асинхронного характера вызовов и различных частот обновления я не могу предположить, что data в моем Vue Объект будет доступен, когда я вызову его из кода HTML. Есть ли способ обработки недостающих данных в Vue.js?

Подробности:

Следующий код работает (выходы hello world) так как message.text определяется во время компиляции Vue пример:

var vm = new Vue({
  el: '#root',
  data: {
    message: {
      text: "hello"
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>

<div id="root">
  <span>{{message.text}}</span>
  <span>world</span>
</div>

Если message определяется через внешнее действие (например, вызов API), тогда приведенный ниже код завершится ошибкой:

var vm = new Vue({
  el: '#root',
  data: {
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>

<div id="root">
  <span>{{message.text}}</span>
  <span>world</span>
</div>

Решение, которое я использую сегодня, состоит в том, чтобы иметь заполнители (значения по умолчанию) для битов data который будет обработан до того, как у меня появится возможность обновить их реальными значениями, но это усложнит (и ухудшит) мой код, когда data становится сложным.

Есть ли способ проинструктировать Vue.js молча потерпеть неудачу при достижении data элементы не определены (пока)?

2 ответа

Вы можете просто объявить одну переменную с именем asyncData и обновите его, когда поступят данные, Vue не выдаст ошибку, если ключ не существует, если вы объявите пустой объект:

var vm = new Vue({
  el: '#app',
  data: {
    asyncData: {}
  }
});

Затем, когда данные поступят, вы можете просто установить их и заставить экземпляр Vue выполнить повторную визуализацию:

// Receive data
vm.asyncData['message'] = "Hello World!";
vm.$forceUpdate();

Вот JSFiddle: https://jsfiddle.net/tvzjsb7e/

Вы можете использовать v-if и не отображать div, пока данные не будут загружены, как показано ниже:

var vm = new Vue({
  el: '#root',
  data: {
    message: {}
  },
  mounted () {
     var vm = this
     setTimeout(function(){
       vm.message = {'text' : 'Hello'}
     }, 400)
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>

<div id="root">
  <div v-if="message.text">
    <span>{{message.text}}</span>
    <span>world</span>
  </div>
</div>

Если вы знаете структуру message данные, вы можете инициализировать его изначально с пустой строкой и не нужно никаких v-if или другой механизм предотвращения этой ошибки.

var vm = new Vue({
  el: '#root',
  data: {
    message: {
      text: ''
    }
  },
  mounted () {
     var vm = this
     setTimeout(function(){
       vm.message.text = 'Hello'
     }, 400)
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>

<div id="root">
  <div>
    <span>{{message.text}}</span>
    <span>world</span>
  </div>
</div>

Другие вопросы по тегам