前言
在使用第三方組件時,有時候組件提供的默認樣式不滿足我們的實際需求,需要對默認樣式進行調整,這就需要用到樣式穿透。本篇文章以vue3使用element-ui的Tabs組件,對Tabs組件的添加按鈕樣式進行客制化為例。
確定需要修改的組件
組件代碼
<template><el-tabsv-model="editableTabsValue"type="card"class="demo-tabs"editable@edit="handleTabsEdit"><template #add-icon><el-icon><Select/></el-icon></template><el-tab-panev-for="item in editableTabs":key="item.name":label="item.title":name="item.name">{{ item.content }}</el-tab-pane></el-tabs></template>
預覽&確認修改目標
例如修改新聞標簽下Tabs
組件的添加按鈕樣式,計劃將邊框范圍擴大、邊框調整成圓形、√圖標擴大
新建div以及自定義class
新建一個div
,將el-tabs
組件包住,并聲明一個語義清晰的自定義class name
,此處以new-tabs
為例
<template><div class="new-tabs"><el-tabsv-model="editableTabsValue"type="card"class="demo-tabs"editable@edit="handleTabsEdit"><template #add-icon><el-icon><Select/></el-icon></template><el-tab-panev-for="item in editableTabs":key="item.name":label="item.title":name="item.name">{{ item.content }}</el-tab-pane></el-tabs></div>
</template>
在瀏覽器調整樣式
定位需要調整的組件
在瀏覽器打開開發者模式,開啟元素檢查模式
定位需要調整的添加按鈕,關注離選擇元素最接近的class
,此處為el-tabs__new-tab
,我們可以在右側觀察到el-tabs__new-tab中需要調整的樣式,以及剛才新增的自定義樣式new-tabs
在瀏覽器中調整&預覽樣式
關注右側el-tabs__new-tab
的樣式,我們需要邊框范圍擴大、邊框調整成圓形、√圖標擴大。于是將height
和width
從20px調整為30px,border-radius
調整成15px,font-size
調整成16px
此時,我們只對樣式進行了臨時修改,刷新頁面后會恢復原狀,還需要對css代碼進行調整,見下文
整理&修改樣式穿透css
上文在瀏覽器中對el-tabs__new-tab
的修改整理如下
.el-tabs__new-tab {height: 30px;width: 30px;border-radius: 15px;font-size: 16px;
}
在<style scoped>
中申明樣式穿透(scoped能夠限制自定義樣式只會影響當前頁面),以我們自定義的classnew-tabs
開頭,使用:deep()
(vue3推薦),參數為上文定位的el-tabs__new-tab
<style scoped>
/* 新聞 */
.new-tabs :deep(.el-tabs__new-tab){height: 30px;width: 30px;border-radius: 15px;font-size: 16px;
}
</style>
確認修改效果
刷新,觀察頁面渲染,定位到按鈕后,觀察樣式,可知道自定義樣式生效,成功覆蓋了默認樣式
頁面完整代碼
碼云https://gitee.com/pinetree-cpu/hello_vue3
<template><div class="new-tabs"><el-tabsv-model="editableTabsValue"type="card"class="demo-tabs"editable@edit="handleTabsEdit"><template #add-icon><el-icon><Select/></el-icon></template><el-tab-panev-for="item in editableTabs":key="item.name":label="item.title":name="item.name">{{ item.content }}</el-tab-pane></el-tabs></div>
</template><script setup lang="ts" name="News">
import axios from "axios";
import { ref } from 'vue'
import { Select } from '@element-plus/icons-vue'
import type { TabPaneName } from 'element-plus'
let tabIndex = 2
const editableTabsValue = ref('2')
const editableTabs = ref([{title: 'Tab 1',name: '1',content: 'Tab 1 news content',},{title: 'Tab 2',name: '2',content: 'Tab 2 news content',},
])const handleTabsEdit = (targetName: TabPaneName | undefined,action: 'remove' | 'add'
) => {if (action === 'add') {const newTabName = `${++tabIndex}`editableTabs.value.push({title: 'New Tab',name: newTabName,content: 'New Tab content',})editableTabsValue.value = newTabName} else if (action === 'remove') {const tabs = editableTabs.valuelet activeName = editableTabsValue.valueif (activeName === targetName) {tabs.forEach((tab, index) => {if (tab.name === targetName) {const nextTab = tabs[index + 1] || tabs[index - 1]if (nextTab) {activeName = nextTab.name}}})}editableTabsValue.value = activeNameeditableTabs.value = tabs.filter((tab) => tab.name !== targetName)}
}
</script><style scoped>
/* 新聞 */
.new-tabs :deep(.el-tabs__new-tab){height: 30px;width: 30px;border-radius: 15px;font-size: 16px;
}
</style>