Почему мне нужно нажать на кнопку два раза, чтобы установить реквизит на компонент? - PullRequest
0 голосов
/ 19 сентября 2018

Почему direction реквизиты обновляются только после первого клика / выполнения, а questionid нет?

Предложение в # vuejs @ freenode:

deadbeat: мое предположениечто реактивное свойство обновляется только после прямого вызова голосования $ refs, но оно обновляется в первый раз

Vue.component('vote-component', {
  template: '<div>{{this.direction}}</div>',
  props: {
    questionid: Number,
    direction: String
  },
  methods: {
    vote() {
      console.log({
        id: this.questionid,
        direction: this.direction
      });
    }
  }
})

new Vue({
  el: "#app",
  data() {
    return {
      direction: '',
      question: {
        id: 10
      }
    }
  },
  methods: {
    vote(direction) {
      this.direction = direction;
      this.$refs.voteComp.vote();
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
  <button @click="vote('UP')">Y</button>
  <vote-component ref="voteComp" :direction="direction" :questionid="question.id" />
</div>

1 Ответ

0 голосов
/ 19 сентября 2018

Проверьте планировщик для Vue watcher , реактивность props = 'direction' с type = String срабатывает при текущей задаче.Но значение direction будет обновлено в следующем цикле рендеринга (фактически следующий цикл обработки событий , вы можете посмотреть это видео для лучшего понимания) (Vue вызывает nextTick(vueQueue), что-тоаналогично setTimeout(()=>{this.direction=newValue}, 0)).

Ниже приведена одна демонстрация:

Вы увидите, что я добавил одно Обещание на App.vote.the callback of Promise.then is Микро-задание будет выполнено непосредственно после того, как текущее задание завершится до следующего цикла рендеринга.

Тогда вы увидите, что console.log('watch', newVal, oldVal) будет выполнено после Promise.then.

Также я поставил один setTimeout там до this.direction=direction, вы увидите, что он будет выполнен после this.$refs.voteComp.vote(), но до console.log('watch', newVal, oldVal), потому что это более старая задача в цикл событий -> очередь задач .

А для prop=questionid будет так же.

Vue.component('vote-component', {
  template: '<div>{{questionid}}: {{this.direction}}</div>',
  props: {
    questionid: Number,
    direction: String
  },
  watch: {
    direction: function (newVal, oldVal) {
      console.log('**watch**', newVal, oldVal)
    }
  },
  methods: {
    vote() {
      console.log({
        id: this.questionid,
        direction: this.direction
      });
    }
  }
})

new Vue({
  el: "#app",
  data() {
    return {
      direction: '',
      question: {
        id: 10
      }
    }
  },
  methods: {
    vote(direction) {
      setTimeout(()=>{
        console.log('the handler at setTimeout Executed')
      }, 0)
      this.direction = direction
      this.question.id = 7
      new Promise((resolve, reject) => {
        console.log('update direction in root')
        resolve()
      }).then(()=>{
        console.log('micro task executed')
      })
      
      this.$refs.voteComp.vote();
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
  <button @click="vote('UP')">Y</button>
  <vote-component ref="voteComp" :direction="direction" :questionid="question.id" />
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...