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

相关推荐
别拿曾经看以后~44 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
Devil枫7 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
GIS程序媛—椰子8 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
毕业设计制作和分享9 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
程序媛小果9 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot
从兄10 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
凉辰10 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
薛一半12 小时前
PC端查看历史消息,鼠标向上滚动加载数据时页面停留在上次查看的位置
前端·javascript·vue.js
MarcoPage12 小时前
第十九课 Vue组件中的方法
前端·javascript·vue.js