一、簡述
前段時間將我的開源項目visualization-collection進行了重構,該項目目前有2.6k的star數,有很多的做Vue開發的同學問有沒有Vue版本,所以就對著之前React版本的重新開發并發布了一個Vue版本的,對于Vue我也是現學現用,在開發過程中也遇到很多阻礙和坑,并且將容易踩坑的地方及解決辦法都記錄下來,今天在這里進行一個技術分享。
二、踩坑分享
style樣式中不能使用:global,否則運行會報錯(找問題調試半天)。
父組件的樣式會影響子組件中最外層第一個元素的樣式(該元素的class與父組件中的class名稱一樣時),即使兩個組件的style標簽中都加了scoped,解決辦法就是在最外層再套一層div或者改用不一樣的class名。
當組件中props參數使用默認值時,不能直接在組件中元素的style中直接使用,這樣樣式直接無效,解決辦法就是將元素所需的style對象用computed方法返回。
比如:
interface SwitchProps {
width?: number;
height?: number;
}
const {
width = 90,
height = 40,
} = defineProps<SwitchProps>();
<template>
<div :style="{ width: `${width}px`, height: `${height}px` }" />
</template>
需改為
import { computed } from "vue";
interface SwitchProps {
width?: number;
height?: number;
}
const {
width = 90,
height = 40,
} = defineProps<SwitchProps>();
const containerStyle = computed(()=>{
return { width: `${width}px`, height: `${height}px` }
});
<template>
<div :style="containerStyle" />
</template>
類型為boolean的且不是必傳的props屬性值,在使用時且沒有傳值時,拿到的值一直是false,并不是和react中一樣為undefined,所以不能寫是否等于undefined來處理業務邏輯。
如果使用了echarts庫,那么在拿到echarts.init()后的對象后一定要用markRaw轉一下,將echarts圖表標記為不可被轉為代理,否則會導致如果echarts的配置中的tooltip.trigger為"axis"時,tooltip無法顯示,且tooltip.valueFormatter也不會執行。
import { markRaw } from "vue";
chartInstance.value = markRaw(echarts.init(chartRef.value, undefined, { renderer: "canvas" }));
vite.config.ts配置文件中的默認的publicDir屬性值為"public", 之前如果要引入public中的文件,在react中寫的 <video><source src="public/dance.mp4"></source></video>,而在vue中則必須寫成<video><source src="/dance.mp4"></source></video>,這樣在本地運行時會找public中的dance.mp4文件,但是使用vite打包后,public中的文件會被復制到outDir的根目錄中,所以如果還是和react中一樣的寫法就不對了,打包時會報錯,因為打包后的根目錄中沒有public文件夾。
watch(xxx, ()=>{ if(boxRef){} }, { immediate: true })中的回調函數在執行第一次時是在onMounted之前執行,也就意味著這和React中的useEffect不一樣,在回調函數中是拿不到boxRef實例的,解決辦法就是寫成watch([xxx, boxRef], ()=>{ if(boxRef){} }, { immediate: true })
三、結語
對于一個Vue新手,如果我的解決辦法有問題或大家有更好的解決辦法,可以進行留言討論,再次感謝各位的支持。
最后用一道我自己在學習Vue時琢磨出的一個關于Vue生命周期與API執行順序的面試題,搞懂了這個,那Vue執行順序相關的題就不在話下了:
問:該組件第一次渲染后console.log打印什么?點擊一次按鈕后打印什么?
更多個人文章