Передача данных в props после асинхронного вызова в Vue

#asynchronous #vue.js #vue-component

#асинхронный #vue.js #vue-компонент

Вопрос:

Я создал проект vue с голыми костями, чтобы показать проблему. Единственное, что я добавил, это пакет axios. Проблема в том, что когда я пытаюсь установить свойство дочернего компонента после асинхронного вызова, я не могу прочитать это свойство в компоненте. Если вы посмотрите на код, вы увидите, что я несколько раз регистрирую консоль, чтобы показать, когда я могу получить данные, а когда не могу. Пожалуйста, помогите мне выяснить, чего мне здесь не хватает.

Родительский

 <template>
  <div id="app">
    <HelloWorld :test_prop="testData" :test_prop2="testData2" :test_prop3="testData3" test_prop4="I work also"/>
    <div>{{testData5}}</div>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import axios from 'axios';
export default {
  name: 'app',
  components: {
    HelloWorld
  },
  data() {
    return {
      testData: '',
      testData2: 'I work just fine',
      testData3: '',
      testData5: ''
    }
  },
  created: function(){
    var self = this;
    this.testDate3 = 'I dont work';
    axios.get('https://jsonplaceholder.typicode.com/posts/42').then(function(response){
      //I need this one to work
      self.testData = 'I dont work either';

      self.testData5 = 'I work also';
    });
  }
}
</script>
  

Дочерний элемент

 <template>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: ['test_prop', 'test_prop2', 'test_prop3', 'test_prop4'],
  data() {
    return {
      comp_data: this.test_prop,
      comp_data2: this.test_prop2,
      comp_data3: this.test_prop3,
      comp_data4: this.test_prop4
    }
  },
  created: function(){
    console.log(this.test_prop);
    console.log(this.test_prop2);
    console.log(this.test_prop3);
    console.log(this.test_prop4);
  }
}
</script>
  

Комментарии:

1. Привет, похоже, что вы дублируете свой код здесь. Или, может быть, это просто плохое копирование / вставка, но ваши два компонента одинаковы.

2. Спасибо, я скопировал это неправильно.

3. Вы ожидаете, что comp_data значения изменятся при изменении testData значений?

4. На родительском сервере вызывается только изначально при создании. После этого ему не понадобятся никакие данные от родителя. В реальном проекте я пытаюсь заставить дочерний элемент получить исходные данные от родительского элемента, а затем установить себя внутренне с этого момента.

Ответ №1:

Ваш console.log созданный внутри хук покажет вам начальное состояние этих переменных в родительском компоненте. Это потому, что созданный родительский хук и созданный дочерний хук будут выполняться одновременно.

Итак, когда вы решаете свое обещание, дочерний компонент уже был создан. Чтобы понять это поведение, поместите свои props в свой шаблон с помощью {{ this.test_prop }} .

Чтобы решить эту проблему, в зависимости от того, что вы хотите, вы можете либо определить некоторое значение по умолчанию для вашего props (см.), либо отобразить ваш дочерний компонент с условиемv-if. Вот и все, надеюсь, это поможет!

Комментарии:

1. Вау, это действительно сработало. Но я не понимаю, почему. Итак, если обернуть дочерний компонент в v-if, но, допустим, вызов api занимает 10 секунд, проверка v-if уже произошла, поэтому он просто не будет отображать компонент и двигаться дальше до следующего рендеринга?

2. Вот и все! Созданный хук в дочернем элементе вызывается только тогда, когда v-if имеет значение true, потому что v-if false не отображает дочерний компонент.

3. Итак, я думаю, потому что я устанавливаю исходные данные дочерних компонентов на любой реквизит, который произойдет только после завершения вызова api, поэтому не имеет значения, сколько времени займет созданный хук? Я правильно понимаю? Или это имеет значение, потому что я использую axios для выполнения вызова асинхронно и должен делать это синхронно.

4. Это зависит от того, как вы использовали условие v-if. Я предлагаю связать его с переменной, которая будет true только после выполнения обещания. Выполнение этого, независимо от того, сколько времени занимает ваше обещание.

Ответ №2:

В созданном Vue перехватываются только начальные значения свойств, переданные из основного компонента. Поэтому более поздние обновления (например, в вашем примере «после вызова ajax») в главном компоненте не будут влиять на переменные данных дочернего компонента из-за того, что уже выполняется дочерний созданный хук.
Если вы хотите обновить данные позже одним из способов, вы можете сделать это следующим образом:

  watch: {
    test_prop: function(newOne){
      this.comp_data = newOne;
    }
 }
  

Добавление наблюдателя к изменениям свойств обновит последнее значение свойства из основного компонента.

А также отредактируйте опечатку this.testDate3 . Я думаю, это должно быть this.testData3

Комментарии:

1. Я тоже использую этот подход. Из-за асинхронных props и created перехвата, запущенных в дочернем компоненте сразу после родительского created , поэтому у promise еще не будет времени для разрешения. С помощью наблюдателя, когда проблема решена, вы получаете правильные данные.