Проблема: повторная визуализация экземпляра vue, когда данные изменяются с помощью обратного вызова внутри метода - PullRequest
0 голосов
/ 30 марта 2019

Я разрабатываю приложение с электронным использованием vue.js в качестве автономного libray (без CLI), и оно получает довольно странное поведение при повторном рендеринге, когда я изменяю данные с помощью обратного вызова электронного метода внутри vue метод (рендеринг на v-for). Я показываю упрощенный код:


<div class="list-item" v-for="(filePath, index) in playlistArray">
   <div class="audio-file-index"> {{ index + 1 }} </div>
   <div class="audio-file-name"> {{ filePath }} </div>
</div>

const { remote } = require('electron');

let vue = new Vue({
  el: '#app',
  data: {
    playlistArray: ['', '', '', '', '']
    // could just '= Array(5)' but i need '' elements so the v-for renders 5 
    // empty divs right away
  },
  methods: {
    addAudioFile() {

      remote.dialog.showOpenDialog({ // electron.remote method to let user select files

        //... doesn't metter, just a options object....

      }, (pathArray) => {
         // pathArray returns a array with all paths selected by the user

         let j = 0;
         for(i = 0; i < this.playlistArray.length; i++) {
            if(this.playlist[i] == '') {
               this.playlistArray[i] = pathArray[i + j];
               j++;
            }
         }
      })
    }
  }
})

Хорошо, поэтому, когда пользователь выбирает аудиофайлы, div показывают путь и (индекс + 1) каждого пути.

Первое, что я не понимаю: после первого вызова addAudioFile () все элементы '' playlistArray превращаются в неопределенные, поэтому мне пришлось изменить if statemant на:

if(this.playlistArray[i] == '' || this.playlistArray[i] == undefined)

Почему это меняется? (Если в массиве есть элемент с верной строкой, он не изменится на неопределенный). Но хорошо ...

Странное поведение: v-for не выполняет повторную визуализацию при изменении playlistArray ... но ... Если я переключаю инструменты разработчика, закрываю его и нажимаю в любом месте моего приложения, повторная визуализация работает (? ).

Я изменил код, используя другой метод справки и переменную справки:


...

let vue = new Vue({
  el: '#app',
  data: {
    playlistArray: ['', '', '', '', '']
  },
  methods: {
    addAudioFile() {

      remote.dialog.showOpenDialog({

        ...

      }, (pathArray) => {
         let j = 0;
         let newPlaylistArray = [];

         for(i = 0; i < this.playlistArray.length; i++) {
            if(this.playlist[i] == '' || this.playlistArray[i] == undefined) {
               newPlaylistArray[i] = pathArray[0 + j];
               j++;
            }
            else newPlaylistArray[i] = this.playlistArray[i] || '';
         }
         this.updatePlaylist(newPlaylistArray);
      })
    },

     updatePlaylist(playlist) {
        this.playlistArray = playlist;
     }
  }
})

... и теперь все работает правильно. Почему?

1 Ответ

0 голосов
/ 30 марта 2019

Я думаю, из-за реактивности.Как сказано в документации:

Vue не может обнаружить следующие изменения в массиве:

  • Когда вы непосредственно устанавливаете элемент с индексом, например
    vm.items[indexOfItem] = newValue

Источник


Чтобы ваш первый пример работал, вы можете попробовать splice или set методы:

for(i = 0; i < this.playlistArray.length; i++) {
  if(this.playlist[i] == '') {
    this.playlistArray.splice(i, 1, pathArray[i + j])
    // or
    this.$set(this.playlistArray, i, pathArray[i + j])
    j++;
  }
}

Примечание: вы используете это условие if(this.playlist[i] == '').Откуда playlist собственность приходит?Вы имеете в виду playlistArray вместо этого?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...