Vue пользовательская обработка событий с наблюдателями - PullRequest
0 голосов
/ 13 июня 2019

Я хочу показать прокси-текст во время выполнения вызова ajax. Кроме того, когда вызов завершен, я хочу скрыть текст. Итак, я кодировал два компонента, один из них - AppBody, который будет удерживать кнопку для имитации вызова ajax в своем слоте. Другой - DownloadBtn, в котором метод execute будет выполнять вызов ajax. До и после вызова ajax я менял значение переменной с именем loaderStatus и смотрел эту переменную на предмет изменений. Всякий раз, когда переменная изменялась, она генерировала пользовательское событие, называемое загрузкой. После получения события от дочернего компонента DownloadBtn компонент AppBody подтвердил это событие в методе doSomething экземпляра vue, и изменилась другая переменная с именем loadSpinner. Я связываю эту переменную loadSpinner с реквизитом AppBody, поэтому всякий раз, когда этот loadSpinner изменяется, текстовое значение должно появляться / скрываться соответственно. Но проблема в том, что текст появляется, но не прячется, как ожидалось. Однако, если я удаляю реквизиты, то консольный журнал возвращает ожидаемый результат, но у меня нет текста, так как текст зависел от этого значения реквизита. Любая помощь будет высоко оценен. Скриптовая ссылка: jsfiddle

У меня есть фрагмент кода js:

Vue.component("app-body", {
    template : 
  `
   <div> 
      <div v-if="loader">
         <p>Please Wait Ajax Call is Running</p>
      </div>
      <div v-else>
         <slot></slot>
      </div>
   </div>
  `,
  data () {
    return {}
  },
  props : {
    loader : Boolean,
  }
});

Vue.component("download-btn", {
    template : `
    <div >
        <button type="button"  @click="execute"> Download </button>
    </div>
  `,
  data () {
    return {
        loaderStatus : false,
    }
  },
  props : {

  },
  methods : {
    execute () {
        //ajax call
        this.loaderStatus = true;
        console.log("Starting ajax call");

        fetch("https://jsonplaceholder.typicode.com/users")
        .then(res=>{
            console.log(res);
            this.loaderStatus = false;
            console.log("ajax call completed")
            /* this.$emit("download", true); */
        }).catch(err=>console.log(err));
    }
  },
  watch : {
    loaderStatus() {
        console.log("in watch::loaderStatus=>"+ this.loaderStatus);
        this.$emit("download", this.loaderStatus);
    }
  } 
});


new Vue({
  el: "#app",
  data: {
   loadSpinner : false
  },
  methods: {
    doSomething(newLoadSpinnerValue) {
        console.log("in doSomething::newLoadSpinnerValue=>" + newLoadSpinnerValue);
        this.loadSpinner = newLoadSpinnerValue;
    }
  },

})

и html часть выглядит так:

<div id="app">


 <app-body :loader=loadSpinner>
     <download-btn @download="doSomething"></download-btn>
   </app-body>
</div>

1 Ответ

0 голосов
/ 13 июня 2019

Проблема в том, что ваш slot монтируется только тогда, когда загрузка не выполняется. Когда загрузка начинается, slot удаляется, что означает, что компонент загрузчика будет отключен, и все, что происходит в нем, не будет запускать никаких наблюдателей или событий. Значение никогда не будет возвращено, и слот не будет повторно активирован.

Вам нужно будет как-то иначе обработать скрытие кнопки загрузки, если вы хотите, чтобы загрузка происходила внутри кнопки.

См. скрипка , где дочерний элемент не удаляется при загрузке, свойства работают правильно.

...