Проверьте планировщик для 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>