Асинхронная задача не является реактивной в представлении vuejs - PullRequest
0 голосов
/ 16 октября 2018

По умолчанию загружаемое изображение равно true, после завершения загрузки загружаемое изображение равно false, но после обновления загружаемый объект не отображается, всегда отображается полоса загрузки.

Где моя ошибка, помогите всем,

Примечание: также попробуйте этим. Функция $ nextTick (), тот же вывод;

в консоли полученное нами обновление, но без эффекта в поле зрения

Vue.config.devtools=false;
Vue.config.productionTip = false;

new Vue({
  el:"#app",
  data: {
    isloadingImage: [],
    property:{
      images:[]
    }
  },
  methods: {

    addFiles() {
      this.$refs.files.click();
    },

    handleFilesUpload() {
      let uploadedFiles = this.$refs.files.files;
      let maxLength = uploadedFiles.length <= 4 ? uploadedFiles.length : 4;
      for (let i = 0; i < maxLength; i++) {
        uploadedFiles[i].url = URL.createObjectURL(uploadedFiles[i]);
        this.property.images.push(uploadedFiles[i]);
      }
      this.uploadImages();
    },

    removeFile(key) {
      this.property.images.splice(key, 1);
      delete this.isloadingImage[key];
    },
    async uploadImages(){
      this.property.images.forEach((value, key) => {
        if (!this.isloadingImage[key]) {
          this.isloadingImage[key] = true;
          let myFormData = new FormData();
          myFormData.append('title', value);
          axios.post('http://localhost:800/uploadimage',
                     myFormData).then(response => {
            this.isloadingImage[key] = false;
           
          }).catch(error=> {
            
            this.isloadingImage[key] = false;
            console.log(this.isloadingImage);
          })
        }
      });
    }
  }
});
.small-image {
        max-height: 200px;
        max-width: 200px;
    }

    .post-image button {
        padding: 0 5px;
    }

    .post-image-preview {
        max-height: 105px;
    }

    .post-image .caption {
        max-width: 198px;
        height: 27px;
    }

    .lds-facebook {
        display: inline-block;
        position: relative;
        width: 64px;
        height: 50px;
    }

    .lds-facebook div {
        display: inline-block;
        position: absolute;
        left: 6px;
        width: 10px;
        background: #bfbebe;
        animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
    }

    .lds-facebook div:nth-child(1) {
        left: 6px;
        animation-delay: -0.24s;
    }

    .lds-facebook div:nth-child(2) {
        left: 26px;
        animation-delay: -0.12s;
    }

    .lds-facebook div:nth-child(3) {
        left: 45px;
        animation-delay: 0s;
    }

    @keyframes lds-facebook {
        0% {
            top: 6px;
            height: 51px;
        }
        50%, 100% {
            top: 19px;
            height: 26px;
        }
    }
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
    <div class="field-title"><h5>Pictures</h5></div>

    <div class="form-group post-image">
        <div class="col-md-12">
            <div class="upload-btn-wrapper">
                <button class="add-photo" v-on:click="addFiles()"><i
                        class="fas fa-camera"></i></button>
                <input type="file" multiple id="file" ref="files"
                       v-on:change="handleFilesUpload()">
            </div>
            <div class="brows-image-text"><p>You can upload up to<br>4 pictures per
                listing</p></div>
        </div>

        <div class="row">
            <div v-for="(file, key) in property.images" class="col-md-3">
                <div class="lds-facebook" v-if="isloadingImage[key]">
                    <div></div>
                    <div></div>
                    <div></div>
                </div>
                <div v-else>
                    <button v-on:click="removeFile( key )" type="button">
                        <i class="fas fa-times text-danger"></i>
                    </button>
                    <img :src="file.url" class="small-image post-image-preview">
                </div>
            </div>
        </div>

    </div>
</div>

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

См. Правило № 2 здесь https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating

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

Пример:

axios.post('http://localhost:800/uploadimage', myFormData)
  .then(response => {
    this.isloadingImage[key] = false;
    this.isloadingImage = this.isloadingImage.slice(0);
    // ^^^ this line
  }).catch(error=> {
    console.log('error', key, error)
    this.isloadingImage[key] = false;
    this.isloadingImage = this.isloadingImage.slice(0);
    // ^^^ and  line
  });
0 голосов
/ 16 октября 2018

Используйте данные как функцию, а не как объект.

new Vue({
  el:"#app",
  data () {
    return {
      imageIsLoading: ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...