TypeError: Cannot read properties of null (reading ‘‘insertBefore’’)
在寫 vue 的時候遇到了這個問題
原本的寫法是這樣的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <script setup lang="ts"> const getStrongKey = computed(() => { return currentSong.value?.Key || 0 + Date.now() + Math.random() }) </script>
<template> <div class="transition-all duration-300" :class="[_bg_class]" @click="changePageToSinging"> <video v-if="currentSong?.Category !== songCategory.Youtube" ref="video" crossorigin="anonymous" class="transition-all duration-300" :loop="loop" :class="[_video_class]" :style="{ height: `${videoHeight}` }" /> <YoutubeVideo v-else :key="`${getStrongKey}`" :video-id="`${youtubeLinkId}`" :class-name="`transition-all duration-300 w-full ${[_video_class]}`" :style="{ height: `${videoHeight}` }" /> </div> </template>
|
我有在 YoutubeVideo 這個 component 裡面加上 key,但是還是會出現這個錯誤
給你們看一下 YoutubeVideo 的寫法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <!-- eslint-disable no-console --> <script setup lang="ts"> import PlayerFactory from 'youtube-player' import type { YouTubePlayer } from 'youtube-player/dist/types'
const props = defineProps<{ videoId: string className: string style: Object }>()
const songStore = useSongStore() const functionStore = useFunctionStore() const pageStore = usePageStore() const { isPlay, isPlayReady } = storeToRefs(functionStore) const {midiSpeedMultiple, midiSpeed} = storeToRefs(songStore)
let player: YouTubePlayer
onMounted(() => { console.log(props) player = PlayerFactory('ytplayer', { videoId: props.videoId || '', height: '100%', width: '100%', playerVars: { autoplay: 1, controls: 0, modestbranding: 1, rel: 0, }, }) songStore.setCurrentTime(0) })
onUnmounted(() => { player.destroy() })
const getStyle = computed(() => { if (currentPageIndex.value === pageNames.Singing) return { ...props.style, width: `${width.value}px` } return { ...props.style } }) </script>
<template> <div :class="className" :style="{ ...getStyle }"> <div id="ytplayer" style="height: 100%; width: 100%;" /> </div> </template>
|
好像是因為 <YoutubeVideo />
在 v-else
的條件已經不成立了
然後你只有元件的 key 改的話
他的子元素還會在
只是會抽換父元素
我自己的猜測啦
有可能就是子元素去指向空的父元素才會出錯
那反正之後我就直接換成 <YoutubeVideo />
外面再包一層 <div />
就好了
然後改的話 key 就變成是改外層的 <div />
的 key
據說是這樣就可以刷新整個 dom subtree
改完之後大概長這樣:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div class="transition-all duration-300" :class="[_bg_class]" @click="changePageToSinging"> <video v-if="currentSong?.Category !== songCategory.Youtube" ref="video" crossorigin="anonymous" class="transition-all duration-300" :loop="loop" :class="[_video_class]" :style="{ height: `${videoHeight}` }" /> <div v-else :key="`${getStrongKey}`"> <YoutubeVideo v-if="currentSong?.Category === songCategory.Youtube" :video-id="`${youtubeLinkId}`" :class-name="`transition-all duration-300 w-full ${[_video_class]}`" :style="{ height: `${videoHeight}` }" /> </div> </template>
|
總之就是能動了
有點通靈…
求 vue 的維護者解釋QQ