element组件库系列(四)-- 实际项目中弹出层组件的样式改造

导读

这是element组件库系列文章,主要是平时使用element组件库的一些过程和心得,文章篇幅不定,有长有短,但主打一个实用(可能实用不一定是对你实用,不实用请轻喷)。废话少说,本篇将谈谈笔者在大屏等项目中如何改造一些弹出层组件的样式,并保证其可移植性的。

package version
element-plus 2.2.15
Vue3 3.3.4

正文部分

全局导入common.scss文件,各组件的样式单独写入新的scss文件,并在common.scss导入,例如`@import "el-select";。

下拉组件(el-select)

el-select.scss文件中,定义如下样式。

scss 复制代码
.zt-select{
    $border-color:rgba(0, 202, 255, 0.2);
    $bg-color:$border-color;
    $text-color:#fff;
    $active-border-color:rgba(0, 202, 255, 0.6);
    $hover-border-color:rgba(0, 202, 255, 0.4);
    $font-size:16px;
    --el-select-input-focus-border-color:#{$active-border-color};
    --el-select-border-color-hover: #{$active-border-color};
    --el-select-disabled-border: var(--el-disabled-border-color);
    --el-select-font-size: var(--el-font-size-base);
    --el-select-close-hover-color: #{$hover-border-color};
    --el-select-input-color: var(--el-text-color-placeholder);
    --el-select-multiple-input-color: var(--el-text-color-regular);
    --el-select-input-focus-border-color: #{$active-border-color};
    --el-select-input-font-size: #{$font-size};
    --el-select-width: 100%;
    .el-select__wrapper{
        color: #{$text-color};
        background-color: #{$bg-color}!important;
    }
    .el-select__placeholder{
        color: #{$text-color};
    }
    .el-input{
        --el-input-border-color: #{$border-color}!important;
        --el-input-hover-border-color: #{$text-color}!important;
        --el-input-bg-color: #{$bg-color}!important;
        --el-input-border: none!important;
        --el-input-text-color: #{$text-color}!important;
        &.is-focus .el-input__wrapper{
            border-color:#{$border-color} !important;
        }
        font-size: #{$font-size};
    }
    .el-icon{
        color:#{$text-color} !important;
        svg{
            fill: #{$text-color} !important;
        }
    }
}
​
//下拉框弹出层样式覆盖
.zt-select-popper{
    z-index: 9999!important;
    $popper-border-color:#12CEFC;
    $popper-bg-overlay-color:rgba(0, 202, 255, 0.8);
    $popper-bg-color:rgba(28, 90, 127, 0.8);
    $popper-text-color:#fff;
    $popper-active-bg-color:rgba(0, 202, 255, 0.33);
    $popper-active-text-color:#e3e13d;
    --el-text-color-secondary:#{$popper-text-color}!important;
    --el-border-color-light:#{$popper-border-color}!important;
    --el-bg-color-overlay:#{$popper-bg-overlay-color}!important;
    background: #{$popper-bg-color} !important;
    color:#{$popper-text-color};
    .el-select-dropdown__list{
    }
    .el-select-dropdown__item{
        color:#{$popper-text-color};
        &.is-selected,&.is-hovering{
            background: #{$popper-active-bg-color} !important;
            color: #{$popper-active-text-color}!important;
        }
        font-size: 16px;
    }
}

使用方法如上图所示,分别指定classpopper-class的值,即分别指定组件本身的类名和弹出层的类名,在类名中覆盖样式(注意合理使用 !important),覆盖规则都是笔者调试者工具获取到的,或者可以观察组件本身的css变量(都是语义化命名,看几遍就大概知道其作用了。)

为了方便后续迁移到新的项目或者是UI稿有调整,我把需要修改的部分再以sass变量再次命名,并放入代码的顶部,方便后续的快速修改。

同理的,以下组件的样式覆盖也遵循这些原则。

日期选择器(el-date-picker)

el-date-picker.scss文件代码:

scss 复制代码
.zt-date-picker{
    $text-color: #fff;
    $border-color:#385D77;
    $active-border-color:#12CEFC;
    --el-input-border-color: #{$border-color}!important;
    --el-input-focus-border-color: #{$active-border-color}!important;
    --el-input-bg-color: transparent!important;
    --el-input-text-color: #{$text-color}!important;
    --el-text-color-regular:#{$text-color};
    .el-icon{
        color:#{$text-color};
    }
    svg{
        fill: #{$text-color}!important;
    }
}
​
.zt-date-picker-popper{
    $popper-border-color:#12CEFC;
    $popper-text-color:#fff;
    $popper-text-hover-color:#e3e13d;
    $popper-text-active-color:#e3e13d;
    $popper-overlay-color:rgba(28, 90, 127, 0.8);
    $popper-current-bg-color:rgba(0, 202, 255, 0.33);
    $inrange-bg-color:rgba(0, 202, 255, 0.33);
    $inrange-hover-bg-color: rgba(0, 202, 255, 0.50);;
    $inrange-text-color:#e3e13d;
    --el-text-color-regular:#{$popper-text-color};
    --el-bg-color-overlay:#{$popper-overlay-color};
    .el-icon{
        color:$popper-text-color;
        svg{
            fill: #{$popper-text-color};
        }
        &:hover{
            color:#{$popper-text-hover-color};
            svg{
                fill: #{$popper-text-hover-color};
            }
        }
    }
    td.in-range{
        color:#{$inrange-text-color}!important;
    }
    .el-date-range-picker{
        --el-datepicker-text-color: #{$popper-text-color};
        --el-datepicker-off-text-color: #{$popper-text-color};
        --el-datepicker-header-text-color: #{$popper-text-color};
        --el-datepicker-icon-color: #{$popper-text-color};
        --el-datepicker-border-color: #{$popper-border-color};
        --el-datepicker-inner-border-color: #{$popper-border-color};
        --el-datepicker-inrange-bg-color: #{$inrange-bg-color};
        --el-datepicker-inrange-hover-bg-color: #{$inrange-hover-bg-color};
        --el-datepicker-active-color: var(--el-color-primary);
        --el-datepicker-hover-text-color: #{$popper-text-hover-color};
    }
}

使用时代码:

html 复制代码
<el-date-picker class="zt-date-picker" popper-class="zt-date-picker-popper" type="daterange" v-model="dateVal"></el-date-picker>

消息提示(el-message)

el-message.scss代码:

scss 复制代码
.zt-info-message{
    --el-message-bg-color: rgba(28, 90, 127, 0.8);
    --el-message-border-color: #12CEFC;
    --el-message-text-color: #fff;
}

使用时:

js 复制代码
ElMessage.info({
    message:'提示信息',
    duration:0,
    customClass:'zt-info-message'
  })

消息弹窗(el-message-box)

对于消息弹窗,element-plus官方提供的基础样式可能无法满足实际项目的需求,但好在官方给我们提供丰富的配置项来支持我们自定义传入我们需要的内容部分和自定义样式覆盖。参考配置项,笔者将分别使用custom-classcancel-button-classconfirm-button-classmessage属性来实现。

首先,由于message支持VNode和返回一个VNodefunction,可以使用函数式组件来实现,于是对ElMessageBox.confirm做一层封装,实现自定义的createConfirmBox函数。有以下代码:

jsx 复制代码
import { ElMessageBox } from "element-plus";
​
/**
 * 使用确认弹窗(基于ElMessageBox样式改造)
 * @param message 提示消息
 * @param title 标题
 * @param {import('element-plus').ElMessageBoxOptions} options 选项,默认值为空
 * @return {Promise<import('element-plus').MessageBoxData>}
 */
export function createConfirmBox(message, title, options = {}) {
  return ElMessageBox.confirm(message, title, {
       cancelButtonText: "否",
      confirmButtonText: "是",
      ...options,
    customClass: "zt-message-box",
    cancelButtonClass: "zt-message-cancel-btn",
    confirmButtonClass: "zt-message-confirm-btn",
    message: () => <RenderMessage message={message} />
  });
}
​
function RenderMessage({ message }) {
  return (
    <span>
      <img
        style={{ position: "absolute", left: 0, top: 0 }}
        src={require("@/assets/img/popWindow/bg_tanchuangtitle.png")}
        alt=""
      />
      <div class="zy-messagebox-message">{message}</div>
    </span>
  );
}
​

RenderMessage即是笔者定义的函数式组件,并在createConfirmBox函数的JSDOC部分引入element-plus声明的类型,以方便使用其时能够有类型提示:

同样地,我们也需要定义一份scss文件el-message-box.scss

scss 复制代码
//自定义的el-message-box覆盖类名
$message-text-color:#fff;
.zt-message-box{
    position: relative;
    $close-icon-size:30px; //关闭按钮的图标大小
    font-family: "MF YueYuan";
    --el-bg-color: rgba(24, 50, 70, 0.85);
    --el-border-color-lighter: #12CEFC;
    --el-messagebox-title-color:#fff!important;
    --el-messagebox-font-size: 14px;
    .el-message-box__header{
        padding:0px 5px 0 20px;
        margin-top:-5px;
        z-index: 999;
        .el-message-box__title{
            font-size: 20px;
        }
    }
    .el-message-box__headerbtn{
        top:5px;
        right: 5px;
    }
    .el-message-box__close{
        width: $close-icon-size;
        height: $close-icon-size;
        svg{
            width: $close-icon-size;
            height: $close-icon-size;
        }
    }
    .el-message-box__container{
        position: unset;
        padding-bottom: 30px;
    }
    .el-message-box__status{
    }
}
.zt-message-confirm-btn{
    color: $message-text-color!important;
    --el-button-bg-color: rgba(18,206,252,0.6)!important;
    --el-button-hover-bg-color: rgba(18,206,252,1)!important;
    --el-button-active-bg-color: rgba(18,206,252,1)!important;
    --el-button-border-color:rgba(18,206,252,0.6)!important;
    --el-button-hover-border-color: rgba(18,206,252,1)!important;
}
.zt-message-cancel-btn{
    color: $message-text-color!important;
    --el-button-bg-color: rgba(245,95,95,0.6)!important;
    --el-button-hover-bg-color: rgba(245,95,95,1)!important;
    --el-button-active-bg-color: rgba(245,95,95,1)!important;
    --el-button-border-color:rgba(245,95,95,0.6)!important;
    --el-button-hover-border-color: rgba(245,95,95,1)!important;
}
.zt-messagebox-message{
    color:$message-text-color;
    font-family: "MF YueYuan";
    position: absolute;
    top:calc(50% - 2px);
    transform: translateY(-50%);
    font-size: 22px!important;
    z-index: 1;
}

具体的效果如图所示:

通知(Notification)

同理地,对于通知组件,element-plus官方也给我们提供的customClass属性来实现自定义类的传入,参考配置项

jsx 复制代码
 ElNotification.info({
    customClass:"zt-warn-info-notification",
    title: "气体监测报警",
    duration:0,
    message:(<div style={{height:'100px',color:'white',fontSize:"18px",marginTop:"30px"}}>我是消息内容</div>)
  })

样式文件el-notification.scss

scss 复制代码
.zt-warn-info-notification {
  $notification-overlay-color: rgba(28, 90, 127, 0.8);
  $notification-border-color: #12cefc;
  --el-bg-color-overlay: #{$notification-overlay-color};
  --el-notification-border-color: #{$notification-border-color} !important;
  --el-notification-title-color: #fff !important;
  --el-notification-close-color: #fff !important;
  --el-notification-close-hover-color: #{$notification-border-color} !important;
  --el-notification-width: 400px !important;
  --el-notification-padding: 0 !important;
.el-notification__group{
    margin:0 !important;
    width: 100%;
}
  //标题样式覆盖
  .el-notification__title {
    position: absolute;
    top: 0;
    left: 20px;
    z-index: 1;
    padding-top: 3px;
  }
  //关闭按钮样式覆盖
  .el-notification__closeBtn {
    top: 8px !important;
    font-size: 20px !important;
  }
}
​

效果图:

总结

在本篇中,以此介绍了el-selectel-date-pickerel-messageel-message-boxel-notification等弹出层组件结合具体需求通过自定义类实现样式覆盖,并将自定义类抽取为公共的scss文件,定义相关的scss变量以利于后续代码的维护和在其他项目中的迁移。

相关推荐
梵得儿SHI3 小时前
Vue 模板语法深度解析:从文本插值到 HTML 渲染的核心逻辑
前端·vue.js·html·模板语法·文本插值·v-text指令·v-html指令
listhi5204 小时前
Vue.js 3的组合式API
android·vue.js·flutter
WYiQIU5 小时前
高级Web前端开发工程师2025年面试题总结及参考答案【含刷题资源库】
前端·vue.js·面试·职场和发展·前端框架·reactjs·飞书
夏之小星星5 小时前
Springboot结合Vue实现分页功能
vue.js·spring boot·后端
韩立学长5 小时前
【开题答辩实录分享】以《自动售货机刷脸支付系统的设计与实现》为例进行答辩实录分享
vue.js·spring boot·后端
静西子5 小时前
Vue标签页切换时的异步更新问题
前端·javascript·vue.js
时间的情敌5 小时前
Vue 3.0 源码导读
前端·javascript·vue.js
天天向上10248 小时前
vue 网站导航栏
前端·javascript·vue.js
JIngJaneIL12 小时前
财务管理|基于SprinBoot+vue的个人财务管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·财务管理系统
qq_3380329212 小时前
VUE的生命周期钩子,vue2和vue3的生命周期钩子的核心差异
前端·javascript·vue.js