父组件(问题复现)
<template>
<usePalyer :m="musicmessage" />
</template>
<script setup lang="ts">
import { ref, reactive,onMounted,onUnmounted } from 'vue';
import usePalyer from '@/components/musicPlayer.vue'
import { wy} from '@/api/musicapi'
interface playmusic {
name: "",
artlist: "",
url: "",
cover: "",
lrc:""
}
let musicmessage=reactive({})
//歌曲
function searchwykey(value: number) {
let data: searchdata = {
msg: input.value, //歌名
type: "json/xml", //返回格式"json/xml"
n: value// 有n=数字为选歌,无n则为列表。
}
wy(data).then((res) => {
console.log("网易",res)
let response = res.data.data
let getmusic: playmusic={
cover:response.picture,
name:response.songtitle,
artlist:response.songname,
url:response.musicurl,
lrc:response.lrctxt.data
}
if(getmusic.url===undefined){
console.log("msg","URL没有")
}else{
musicmessage=getmusic
console.log("点击歌曲wymsg",musicmessage)
}
})
}
</script>
子组件
<template>
<div id="player">
</div>
</template>
<script setup >
import APlayer from 'aplayer';
import 'aplayer/dist/APlayer.min.css';
import { ref, reactive, watch, onMounted } from 'vue';
import list from '@/hooks/localmusicList.js'
const props = defineProps({
m: {}
})
onMounted(() => {
const ap = new APlayer({
element: document.getElementById('player'),
fixed: true,
listFolded: false,
lrcType: 1,
audio: list
});
watch(props,(newV) => {
console.log("传props", props.m)
if (newV != "Audio name") {
ap.list.add([{
name: props.m.name,
artist: props.m.artlist,
url: props.m.url,
cover: props.m.cover,
lrc: props.m.lrc,
theme: '#ebd0c2'
}]);
}else{
console.log("error")
}
})
})
</script>
修改后的父组件
如果想要代码优雅一点可以改为
原因:reactive不能替换整个对象,由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失。就导致子组件的watch不能及时触发更新
let state = reactive({ count: 0 })
// 上面的 ({ count: 0 }) 引用将不再被追踪
// (响应性连接已丢失!)
state = reactive({ count: 1 })