Vue.js Обратите внимание, что смонтированный не гарантирует, что все дочерние компоненты также были смонтированы? - PullRequest
0 голосов
/ 01 февраля 2019

Может кто-нибудь объяснить объяснение ниже VUE doc https://vuejs.org/v2/api/#mounted?

Обратите внимание, что смонтированный не гарантирует, что все дочерние компоненты также были смонтированы.

Я протестировал монтирование дочерних и дочерних элементов, но оба всегда монтируются перед компонентом root / app, поэтому безопасно использовать «монтированный» без $ nextTick для доступа к DOM.Дочерние и дочерние компоненты могут получить доступ к элементу DOM из шаблона root / app, хотя он монтируется после дочерних.С другой стороны, root / app может также обращаться к элементам DOM в дочерних шаблонах.Рассмотрим этот пример ...

<div id="app">
  {{ message }}
  <child></child>
  <span id="root"></span>
</div>

<script type="text/javascript">
  var subchild = {
    template: `<div>SUBCHILD<span id="subchild"></span></div>`,
    mounted() {
      console.log("Mounted SUBCHILD", document.getElementById('root'));
    }
  };

  var child = {
    template: `<div>CHILD<span id="child"></span><subchild></subchild></div>`,
    components : { subchild },
    mounted() {
      console.log("Mounted CHILD", document.getElementById('root'));
    }
  };

  var app = new Vue({
    el: '#app',
    components : { child },
    data() {
      return { message: 'APP' };
    },
    mounted() {
      console.log("Mounted APP", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
    }

  })
</script>

https://jsfiddle.net/ecobyxrn/

Вывод в консоль ...

Смонтированный SUBCHILD [объект HTMLSpan ...] [объектHTMLSpan ...] [объект HTMLSpan ...]

подключенный ребенок [объект HTMLSpan ...] [объект HTMLSpan ...] [объект HTMLSpan ...]

подключенное приложение [объект HTMLSpan ...] [объект HTMLSpan ...] [объект HTMLSpan ...]

Так что в моем случае я не понимаю, что VUE замечают.Может кто-нибудь показать вариант использования, который потом монтирует потом потом root / app?Я думаю, что VUE doc очень плохой и не очень хорошо это объясняет.Я также попытался отложить монтирование root / app, закомментировав el: '#app' + добавив setTimeout(function() { app.$mount('#app'); }, 2000);, но результат тот же.

Кроме того, посмотрите этот образ ... VUE.js mounted hooks parent + child

Источник изображения: https://medium.com/@brockreece/vue-parent-and-child-lifecycle-hooks-5d6236bd561f

На странице источника кто-то в комментарии предупреждает автора изображения об упомянутом уведомлении VUE, но не объясняет его.Кажется, что все знают об этом уведомлении, но никто не объясняет его.

1 Ответ

0 голосов
/ 01 февраля 2019

Как уже упоминалось @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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...