如何在 VueJs 中再次加载(重新加载)组件或销毁它并再次加载?
How to load again(reload) component in VueJs or destroy it and load again?
我在 VueJs 中有一个组件,例如 Aplayer(或任何其他组件),用于播放音频和管理播放列表。
现在我需要在不改变路由的情况下改变播放列表时重新加载它。有什么方法可以重新加载组件或销毁它然后立即加载它?
我想在this组件播放音乐的时候改变播放列表,但是有时会播放之前播放列表的音乐,不知道为什么。
HTML 细分:
<aplayer autoplay
ref="remote"
:music="music_list[0]"
:list="music_list"
:float="float"
:mutex="mutex"
repeat="list"
:mini="mini"
preload="auto"
@ended="onEnd"
@loadstart="playCMD"
@playing="onStart"
:listFolded="listFolded"
:controls="controls"
:muted.sync="muted"
:volume.sync="volume"
slot="display"
/>
JavaScript 细分:
export default {
components: {
Aplayer
},
data: () => ({
float: false,
autoplay: true,
mutex: true,
muted: false,
volume: 0.8,
mini: false,
listFolded: false,
controls: true,
music_list: [..]
}),
methods: {
onEnd: function () {
// Doing a series of jobs that leads to raising an event then
this.music_list = [new music list after event trigger]
}
}
}
您的更改未被采纳的原因是您(或播放器组件) 没有正确利用 Vue 的反应系统。您应该使用 the appropriate array mutation method so that array reactivity 进行维护。 Vue 不会拾取直接对数组元素所做的更改。
意思是,当您执行以下操作时:
this.myArray[1] = "some new value";
Vue 将不会采用这些更改。
在Vue中操作数组的正确方法
使用您的 onEnd
方法,尝试将代码更改为此....
onEnd: function () {
// Assumption: resultOfSomeJob is an array of songs for the playlist
// Clear our playlist
this.music_list = [];
// Push elements to our music_list using the Vue array method "push"
this.music_list.push(...resultOfSomeJob);
}
编辑:
我看了一下 aplayer
组件代码。我的答案之所以有效,是因为它采用了您提供的 :list
,以及 computes a new property、musicList
。
(这里是代码,以备日后修改)
musicList () {
return this.list
}
我发现 Vue 文档 this excerpt 对理解这里发生的事情很有帮助...
computed properties are cached based on their reactive dependencies. A computed property will only re-evaluate when some of its reactive dependencies have changed.
因此,当您更改数组而不使用适当的方法来保持反应性,然后将其传递给 a-player
组件时,计算的 属性 不会更新。因此,您的旧播放列表仍然存在 :)
最简单的技巧,只需使用 v-if
:
<aplayer v-if='loaded' />
脚本
export default {
components: { Aplayer },
data: () => ({
loaded: true,
}),
methods: {
onEnd: function () {
// when you want to reload the component just make `loaded = false`
this.loaded = false;
// load agin with `setTimeout` or promise
// or with your logic - whenever the component is ready to show
setTimeout(() => {
this.loaded = true
}, 500); // delay in ms
}
}
}
我在 VueJs 中有一个组件,例如 Aplayer(或任何其他组件),用于播放音频和管理播放列表。
现在我需要在不改变路由的情况下改变播放列表时重新加载它。有什么方法可以重新加载组件或销毁它然后立即加载它?
我想在this组件播放音乐的时候改变播放列表,但是有时会播放之前播放列表的音乐,不知道为什么。
HTML 细分:
<aplayer autoplay
ref="remote"
:music="music_list[0]"
:list="music_list"
:float="float"
:mutex="mutex"
repeat="list"
:mini="mini"
preload="auto"
@ended="onEnd"
@loadstart="playCMD"
@playing="onStart"
:listFolded="listFolded"
:controls="controls"
:muted.sync="muted"
:volume.sync="volume"
slot="display"
/>
JavaScript 细分:
export default {
components: {
Aplayer
},
data: () => ({
float: false,
autoplay: true,
mutex: true,
muted: false,
volume: 0.8,
mini: false,
listFolded: false,
controls: true,
music_list: [..]
}),
methods: {
onEnd: function () {
// Doing a series of jobs that leads to raising an event then
this.music_list = [new music list after event trigger]
}
}
}
您的更改未被采纳的原因是您(或播放器组件) 没有正确利用 Vue 的反应系统。您应该使用 the appropriate array mutation method so that array reactivity 进行维护。 Vue 不会拾取直接对数组元素所做的更改。
意思是,当您执行以下操作时:
this.myArray[1] = "some new value";
Vue 将不会采用这些更改。
在Vue中操作数组的正确方法
使用您的 onEnd
方法,尝试将代码更改为此....
onEnd: function () {
// Assumption: resultOfSomeJob is an array of songs for the playlist
// Clear our playlist
this.music_list = [];
// Push elements to our music_list using the Vue array method "push"
this.music_list.push(...resultOfSomeJob);
}
编辑:
我看了一下 aplayer
组件代码。我的答案之所以有效,是因为它采用了您提供的 :list
,以及 computes a new property、musicList
。
(这里是代码,以备日后修改)
musicList () {
return this.list
}
我发现 Vue 文档 this excerpt 对理解这里发生的事情很有帮助...
computed properties are cached based on their reactive dependencies. A computed property will only re-evaluate when some of its reactive dependencies have changed.
因此,当您更改数组而不使用适当的方法来保持反应性,然后将其传递给 a-player
组件时,计算的 属性 不会更新。因此,您的旧播放列表仍然存在 :)
最简单的技巧,只需使用 v-if
:
<aplayer v-if='loaded' />
脚本
export default {
components: { Aplayer },
data: () => ({
loaded: true,
}),
methods: {
onEnd: function () {
// when you want to reload the component just make `loaded = false`
this.loaded = false;
// load agin with `setTimeout` or promise
// or with your logic - whenever the component is ready to show
setTimeout(() => {
this.loaded = true
}, 500); // delay in ms
}
}
}