Как определить, загружен ли внешний компонент и получить его требуемые данные в vue

#javascript #vue.js

Вопрос:

Привет, у меня ситуация, когда я разрабатываю плагин или расширение, в котором для основного компонента я не могу добавить какой-либо код, кроме mixins

моя ситуация примерно такая:

у меня есть 2 компонента (1) actions-comp (2) display-comp

после нажатия кнопки компонента действия должен появиться компонент отображения, и компонент отображения получит ImageUrl, который я хочу получить в компоненте действий

Вопрос: я хочу получить значение imgUrl from display-comp into actions-comp после imgUrl установки.

Примечание: actions-comp может перейти на любой уровень вложенности компонентов, но display-comp останется в основном компоненте

вот что я пробовал:

для лучшего просмотра codepen: https://codepen.io/eabangalore/pen/ExXLXwv

 const globalMixin = {
  data(){
    return {
        displayDetails:{
          show:false,
        }
    }
  }
}

const comp2 = {
     name:'actions-comp',
     template:`<button @click="displayThumbnail()">Generate and Display image</button>`,
     methods:{
       displayThumbnail(){
          this.$parent.displayDetails.show = true;
          // 1. get url of image from 'display-comp'
          // 2. print them or send 
          console.log(`the image url of display-comp is:`);
       }
     }
}

const comp3 = {
     name:'display-comp',
     template:`<img src="" id="img" width="150px" height="80px" style="border:1px solid red;"/>`,
     data(){
       return {
           imgUrl:'',
           imgLoaded:false,
       }
     },
    mounted(){
      //mimick the server response don't know how much time server will take
      setTimeout(() => {
        this.imgUrl = `https://via.placeholder.com/150`
        this.$nextTick(() => {
          document.getElementById('img').setAttribute('src',this.imgUrl);
          this.imgLoaded = true;
        });
      }, 500);
    },

    beforeDestroy(){
       this.imgLoaded = true;
   }
}


const app = new Vue({
   el:'#app',
   name:'app',
   mixins:[globalMixin],
   components:{'actions-comp':comp2,'display-comp':comp3},
});

console.log('app',app); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


<div id="app">
  
  
    <display-comp v-if="displayDetails.show"></display-comp ref="display">
  
   <actions-comp><actions-comp/>
 
  
</div> 

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

1. Это, естественно, решается с помощью Vue 3 suspense. В Vue 2 обычно ошибочно делегировать эту работу дочернему элементу. Переместите запрос к родительскому элементу и предоставьте дочернему элементу готовые к использованию данные. В качестве обходного пути вы можете выдать что-то вроде ready event от дочернего элемента. Использование $parent указывает на то, что дизайн компонента пошел не так, это было плохо даже в AngularJS, откуда он был заимствован.

2. Я бы использовал хранилище для такого варианта использования