1. 今天的需求是封裝一個(gè) Navigation Bar 導(dǎo)航欄組件,目的是給到App幾乎所有的頁面復(fù)用:
??
?
2. 因?yàn)橹暗捻?xiàng)目里使用過Vant組件庫,筆者第一時(shí)間想到了Vant組件庫中的 NavBar 組件,和當(dāng)前App的需求匹配度很高。Vant組件庫的 NavBar 組件:
3. 相信你也發(fā)現(xiàn)了,Vant組件庫默認(rèn)主題色是藍(lán)色,而當(dāng)前App的主題色是綠色,翻看了下Vant組件庫的API文檔,存在 ConfigProvider 全局配置,簡(jiǎn)單修改下樣式即可:
:root {
# 自定義主題色變量
--cp-primary: #16C2A3;
# 覆蓋Vant主題色
--van-primary-color: var(--cp-primary);
}
筆者在?http://t.csdn.cn/cCGFP?文章中介紹過全局引入Vant樣式,這里我把需要修改主題色的代碼放在了項(xiàng)目 src/styles/main.scss 里,不明白的小伙伴可以翻看前文!
4. 準(zhǔn)備工作完成后正式開干,項(xiàng)目 src/components 文件夾下新建 cp-nav-bar.vue 組件,因?yàn)榍拔呐渲眠^按需引入,這里直接使用 <van-nav-bar />?
<template>
<div>
<van-nav-bar
:title="..."
:right-text="..."
left-arrow
fixed
@click-left="..."
@click-right="..."
/>
</div>
</template>
title 標(biāo)題
right-text 右側(cè)文案
left-arrow 是否顯示左側(cè)箭頭
fixed 是否固定在頂部
click-left 點(diǎn)擊左側(cè)按鈕時(shí)觸發(fā)的事件
click-right 點(diǎn)擊右側(cè)按鈕時(shí)觸發(fā)的事件
跑起來觀察后發(fā)現(xiàn),van-nav-bar組件的字號(hào)和當(dāng)前App有些差距,這里使用深度選擇器修改下
<style scoped lang="scss">
:deep() {
.van-nav-bar {
&__arrow {
font-size: 18px;
}
&__text {
font-size: 15px;
}
}
}
</style>
vue3深度選擇器不熟悉的同學(xué),可以查看筆者的另一篇軟文?http://t.csdn.cn/NkDbl
5. cp-nav-bar組件需要支持的功能:
①?支持??title??rightText? 屬性,父?jìng)髯訉?shí)現(xiàn) (標(biāo)題和右側(cè)文字的自定義)
② 支持 click-right 事件,子傳父實(shí)現(xiàn) (右側(cè)點(diǎn)擊事件的拋出)
????????注:右側(cè)按鈕對(duì)應(yīng)要做的事情,應(yīng)該是自己定義的,所以我們要支持事件,讓他有自己的實(shí)現(xiàn)邏輯
③ 支持返回上一頁功能????????
????????注: vue2和vue3獲取路由方式有區(qū)別
????????????????this.$router => useRouter()
?????????????????this.$route => useRoute()
6.?標(biāo)題和右側(cè)文字的自定義
# 當(dāng)前組件里
<script lang="ts" setup>
withDefaults(
defineProps<{
title?: string
rightText?: string
}>(),
{
title: '標(biāo)題',
rightText: '按鈕'
}
)
</script>
# 使用組件時(shí)
<cp-nav-bar title="凡大來了" right-text="他真的來了" />
7.?右側(cè)點(diǎn)擊事件的拋出
# 當(dāng)前組件里
<script lang="ts" setup>
const emits = defineEmits<{
(e: 'click-right'): void
}>()
const onClickRight = () => {
emits('click-right')
}
</script>
<template>
<div>
<van-nav-bar
:title="title"
:right-text="rightText"
left-arrow
fixed
@click-right="onClickRight"
/>
</div>
</template>
# 使用組件時(shí)
<template>
<div>
<cp-nav-bar
title="凡大來了"
right-text="他真的來了"
@click-right="handleClickRight"
/>
</div>
</template>
<script lang="ts" setup>
const handleClickRight = () => {
console.log('兒子的右側(cè)按鈕被點(diǎn)擊了,父親你要做點(diǎn)什么嗎?')
}
</script>
8.?返回上一頁功能
# 當(dāng)前組件里
<script lang="ts" setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const onClickLeft = () => {
# 無腦回退是不嚴(yán)謹(jǐn)?shù)? # 如果back字段是個(gè)null,強(qiáng)制拉回我們項(xiàng)目的首頁,反之回退
# history不熟悉的,看下這里 https://developer.mozilla.org/zh-CN/docs/Web/API/History
if (history.state.back) {
router.back()
} else {
router.push('/')
}
}
</script>
<template>
<div>
<van-nav-bar
:title="title"
:right-text="rightText"
left-arrow
fixed
@click-left="onClickLeft"
@click-right="onClickRight"
/>
</div>
</template>
# 使用組件時(shí)
<cp-nav-bar />標(biāo)簽不需要任何操作,@click-left并沒有拋出,只要引用了組件,都具有back功能
9. 有同學(xué)可能會(huì)有疑問:為什么可以直接使用組件,不導(dǎo)入不注冊(cè)?
因?yàn)楣P者在前文中 配置了 unplugin-vue-components 插件,該插?默認(rèn)會(huì)把項(xiàng)目 src/compoenents 目錄下的組件自動(dòng)導(dǎo)入注冊(cè),是不是爽歪歪?。?!
再次附上前文地址?http://t.csdn.cn/cCGFP
10.?cp-nav-bar 組件類型配置
寫到這里咱們的 cp-nav-bar 組件基本完成,還剩下最后一個(gè)痛點(diǎn)是缺失屬性提示、事件提示、鼠標(biāo)放上去也沒有類型提示,這該怎么解決呢?
前文里我在?vite.config.js 文件中做了如下配置:
...
export default {
plugins: [
vue(),
Components({
# 不生成類型聲明文件自己寫
dts: false
...
})
]
}
對(duì)!沒錯(cuò)!我取消了自動(dòng)生成類型聲明文件,實(shí)際上你配置了也沒卵用!為了解決缺失提示的痛點(diǎn),筆者在 src目錄下 \ types目錄下 \ 新建 components.d.ts文章來源:http://www.zghlxwxcb.cn/news/detail-417467.html
# 怎么給全局的組件提供類型?
# 寫一個(gè)類型聲明文件,declare module 'vue' 聲明一個(gè) vue 類型模塊
# 然后 interface GlobalComponents 書寫全局組件的類型
# key組件名稱支持大駝峰, value是組件類型, 通過 typeof 組件實(shí)例得到
import CpNavBar from '@/components/cp-nav-bar.vue'
declare module 'vue' {
interface GlobalComponents {
CpNavBar: typeof CpNavBar
}
}
End-------------------文章來源地址http://www.zghlxwxcb.cn/news/detail-417467.html
到了這里,關(guān)于基于Vant組件庫二次封裝組件(TS+Vue3.x環(huán)境)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!