Как уже упоминалось @RandyCasburn, компоненты могут загружаться асинхронно.Каждому свойству объекта components
может быть присвоен объект определения компонента или Promise
, который в конечном итоге разрешается с помощью объекта определения компонента.Таким образом, в этих случаях может случиться так, что хук родительского компонента mounted
будет вызван до того, как асинхронно загруженные потомки закончат загрузку.
В качестве простой проверки этого вы можете изменить объект component
базового компонента для загрузки компонента child
после задержки:
components: {
child: () => new Promise((resolve) => {
setTimeout(() => {
resolve(child)
}, 2000)
})
}
Вы увидите, что ссылкадочернему компоненту в ловушке mounted
при запуске null
.
Кажется бесполезным, что документы Vue не упоминают это как потенциальную причину для сценария, против которого они предупреждают.И, кроме использования асинхронных компонентов, я не могу вспомнить другой сценарий, когда дочерний компонент не был бы смонтирован, когда запущен хук родителя mounted
.
Вот полный пример использования вашего кода:
Vue.config.productionTip = false
var subchild = {
template: `<div>SUBCHILD<span id="subchild"></span></div>`,
mounted() {
console.log("Mounted SUBCHILD", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
};
var child = {
template: `<div>CHILD<span id="child"></span><subchild></subchild></div>`,
components : { subchild: () => new Promise((resolve) => {
setTimeout(() => {
resolve(subchild)
}, 2000)
}) },
mounted() {
console.log("Mounted CHILD", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
};
var app = new Vue({
el: '#app',
components : { child: () => new Promise((resolve) => {
setTimeout(() => {
resolve(child)
}, 2000)
}) },
data() {
return { message: 'APP' };
},
mounted() {
console.log("Mounted APP", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
{{ message }}
<child ref="child"></child>
<span id="root"></span>
</div>