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变量以利于后续代码的维护和在其他项目中的迁移。

相关推荐
GIS开发特训营7 分钟前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood33 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
一个处女座的程序猿O(∩_∩)O3 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
燃先生._.10 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
2401_8576009513 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_8576009513 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL13 小时前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js
轻口味13 小时前
Vue.js 核心概念:模板、指令、数据绑定
vue.js
2402_8575834913 小时前
基于 SSM 框架的 Vue 电脑测评系统:照亮电脑品质之路
前端·javascript·vue.js
java_heartLake14 小时前
Vue3之性能优化
javascript·vue.js·性能优化