vue使用element-ui自定义样式思路分享【实操】

前言

在使用第三方组件时,有时候组件提供的默认样式不满足我们的实际需求,需要对默认样式进行调整,这就需要用到样式穿透。本篇文章以vue3使用element-ui的Tabs组件,对Tabs组件的添加按钮样式进行客制化为例。

确定需要修改的组件

组件代码

html 复制代码
<template>
  <el-tabs
      v-model="editableTabsValue"
      type="card"
      class="demo-tabs"
      editable
      @edit="handleTabsEdit"
  >
    <template #add-icon>
      <el-icon><Select/></el-icon>
    </template>
    <el-tab-pane
        v-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为例

html 复制代码
<template>
  <div class="new-tabs">
    <el-tabs
        v-model="editableTabsValue"
        type="card"
        class="demo-tabs"
        editable
        @edit="handleTabsEdit"
    >
      <template #add-icon>
        <el-icon><Select/></el-icon>
      </template>
      <el-tab-pane
          v-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的样式,我们需要边框范围扩大、边框调整成圆形、√图标扩大。于是将heightwidth从20px调整为30px,border-radius调整成15px,font-size调整成16px

此时,我们只对样式进行了临时修改,刷新页面后会恢复原状,还需要对css代码进行调整,见下文

整理&修改样式穿透css

上文在浏览器中对el-tabs__new-tab的修改整理如下

css 复制代码
.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

css 复制代码
<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

html 复制代码
<template>
  <div class="new-tabs">
    <el-tabs
        v-model="editableTabsValue"
        type="card"
        class="demo-tabs"
        editable
        @edit="handleTabsEdit"
    >
      <template #add-icon>
        <el-icon><Select/></el-icon>
      </template>
      <el-tab-pane
          v-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.value
    let activeName = editableTabsValue.value
    if (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 = activeName
    editableTabs.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>
相关推荐
threelab8 分钟前
Three.js 3D 饼图效果 | 三维可视化 / AI 提示词
javascript·人工智能·3d
傻瓜搬砖人29 分钟前
SpringMVC的请求
java·前端·javascript·spring
木易 士心36 分钟前
为什么 Promise 比 setTimeout 先执行?——JavaScript 事件循环与异步顺序完全指南
开发语言·javascript·ecmascript
爱上好庆祝44 分钟前
学习js的第六天(js基础的结束)
开发语言·前端·javascript·学习·ecmascript
yqcoder1 小时前
JS 类型检测双雄:typeof vs instanceof 深度解析
开发语言·javascript·ecmascript
rADu REME1 小时前
SpringBoot + vue 管理系统
vue.js·spring boot·后端
啊哈一半醒2 小时前
React 核心知识点系统总结:从基础语法到高级 API,一篇文章梳理完整学习路线
javascript·学习·react.js
ZC跨境爬虫2 小时前
跟着 MDN 学 HTML day_11:(语义化容器全站重构+独立CSS拆分+字体合规引入)
前端·css·ui·重构·html·edge浏览器
ZC跨境爬虫2 小时前
跟着 MDN 学 HTML day_10:(超链接核心语法+路径规则)
前端·css·笔记·ui·html·edge浏览器
被考核重击2 小时前
Vue响应式原理(下)
前端·javascript·vue.js