#javascript #vue.js #electron
#javascript #vue.js #electron
Вопрос:
Я разрабатываю приложение с electron, используя vue.js как автономный libray (без использования CLI), и он получает довольно странное поведение повторного рендеринга, когда я изменяю данные обратным вызовом метода electron внутри метода 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 ;
}
}
})
}
}
})
Хорошо, итак, когда пользователь выбирает аудиофайлы, divs показывают путь и (индекс 1) каждого пути.
Первое, чего я не получаю: после первого вызова addAudioFile( ) все ‘ ‘ элементы playlistArray становятся неопределенными, поэтому мне пришлось изменить параметр состояния if на:
if(this.playlistArray[i] == '' || this.playlistArray[i] == undefined)
Почему это меняется? (Если в массиве есть элемент с правдивой строкой, он не меняется на неопределенный). Но ладно…
Поведение wird: 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:
Я предполагаю, что из-за реактивности. Как говорится в документации:
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
вместо этого?
Комментарии:
1. Спасибо! Это работает. И да, здесь я допустил ошибку, я имел в виду playlistArray.