• < ElementUi组件库: el-progress 进度条Bug及样式调整 >


    标题图片


    👉 前言

    在 Vue + elementUi 开发中,在使用 Progress 进度条时,往往会因为需求原型太过花里胡哨而烦恼(原本的样式并不能满足需求)。

    为什么呢? 因为这个组件elementUi并没有提供过多的自定义属性及插槽,对的,插槽也没有,不能自定义进度条文本样式。即使在elementUi 的文档里面写了属性,但是实际使用并未生效(怀疑是bug)。

    Tips: 基于 elementUi来说,好像elementUi - Plus升级了,修复了bug,也增加了对应的属性、开放了插槽!

    所以,在这个时候,我们就需要用到样式覆盖来对 Progress 进度条 进行个性化样式设置了! 首先,给小伙伴们看看,经过定义样式后,使用进度条实现的样式!

    效果图

    接下来,进入主题!

    👉 一、实现原理

    > 修改 el-progress 进度条样式 及 渐变进度条样式

    我们可以通过 /deep/、>>>、v-deep 来对 elementUI 中给 el-progress 定义的原样式进行深度覆盖。

    在这里插入图片描述
    并且我们可以通过控制台看见,进度条是由svg标签渲染出来的,如果需要更改进度条样式,可以通过修改原先svg标签的渲染路径即可,若只需要单色,可以直接在elementUi提供的属性 或者 自行进行样式覆盖!

    具体内容如下:

    > HTML

    <div class="progressName"> 
        <el-progress :width="60" :hidden="60" type="circle" :percentage="50">el-progress> 
    div>
     
    <div style="width:0px; height: 0px;"> 
        <svg width="100%" height="100%"> 
            <defs> 
                <linearGradient id="write" x1="0%" y1="0%" x2="100%" y2="0%"> 
                    <stop offset="0%" style="stop-color:#0299E2" stop-opacity="0.8">stop> // offset 设置起始 stop-color 设置起始位置的颜色 
                    <stop offset="100%" style="stop-color:#02E4DC" stop-opacity="1">stop> // offset 设置起始 stop-color 设置起始位置的颜色 
                linearGradient> 
            defs> 
        svg> 
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    > CSS

    // 此处使用的是scss语法
    .progressName {
    	// 这里可以用
    	/deep/ {
    	  .el-progress {
    	    margin: 0 6px;
    	    position: relative;
    	    // 修改进度条文字提示颜色
    	    .el-progress__text {}
    	  }
    	  // 设置渐变进度条,通过重新定义svg标签的url
    	  svg>path:nth-child(2) {
    	  	// #write 此处的id就是定义的svg标签id 做替换即可 
    	    stroke: url(#write); 
    	  }
    	  // 修改进度条背景色
    	  .el-progress path:first-child {
    	    // stroke: #e1e1e1; 
    	  }
    	  // 进度条的图形样式,控制翻转
    	  .el-progress-circle {
    	    transform: rotateY(180deg);
    	  }
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    👉 二、案例代码(前言效果图案例)

    > HTML代码

    <el-card
     class="item"
     v-for="(item, index) in viewOption"
     :key="index"
    >
      <div slot="header" class="clearfix">
        <div class="titleBox">
          <img :src="headerIconSrc" />
          <span class="title">
            {{ item.name || '指标名称' }}
          span>
          <el-popover
            placement="bottom-start"
            width="220"
            trigger="click">
            <strong>用途:strong>{{ item.purpose || '暂无用途' }}
            <i class="el-icon-question" slot="reference">i>
            
          el-popover>
        div>
        <strong>总体权重:{{ item.allWeight || 0 }}strong>
      div>
      <div
        class="viewInfo"
      >
        <div
          class="progressView"
          :style="{ width: progressWidth + 'px', height: progressWidth + 'px', }"
          @click="viewInfoClick(item.name)"
        >
          <el-progress
            type="circle"
            color="#8080bf"
            :width="progressWidth"
            :percentage="item.zbVal || 0"
            :stroke-width="progressWidth/10"
            :show-text="false"
          >el-progress>
          <div class="formatText">
            <p class="label">{{ item.zbName }}p>
            <p class="value">{{ item.zbVal || 0 }}%p>
          div>
        div>
        <el-divider direction="vertical">el-divider>
        <div class="Info">
          <div
            class="textItem"
            v-for="(item_1, index_1) in item.detailList"
            :key="index_1"
          >
            <img :src="viewIconSrc" />
            <span class="text">{{ item_1.name }}(权重:{{ item_1.value || 0 }} )span>
          div>
        div>
      div>
    el-card>
    
    
    <div style="width:0px; height: 0px;"> 
      <svg width="100%" height="100%"> 
        <defs> 
          <linearGradient id="write" x1="0%" y1="0%" x2="100%" y2="0%"> 
            <stop offset="0%" style="stop-color:#02E4DC" stop-opacity="0.9">stop> // offset 设置起始 stop-color 设置起始位置的颜色 
            <stop offset="100%" style="stop-color:#0271e2" stop-opacity="0.7">stop> // offset 设置起始 stop-color 设置起始位置的颜色 
          linearGradient> 
        defs> 
      svg> 
    div>
    
    // el-progress是不能动态调整大小的,这里通过获取可视窗口大小,配置需要的进度条大小(这里用于测量单位,包括内部文本圈圈大小)
    progressWidth: window.innerWidth / 3 / 2 - 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    > CSS代码

    .item {
      width: calc(100% / 3 - 12px);
      height: calc(50% - 12px);
      border-radius: 5px;
      margin: auto;
      .clearfix {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-between;
        strong {
          font-size: 13px;
          color: #4298F3;
        }
        .titleBox {
          width: auto;
          max-width: calc(100% - 85px);
          display: flex;
          align-items: center;
          img {
            width: 30px;
            height: 28px;
            margin-right: 5px;
          }
          .title {
            display: inline-block;
            width: auto;
            max-width: calc(100% - 39px);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-size: 14.5px;
            font-weight: 700;
          }
          .el-icon-question {
            font-size: 15px;
            margin: 3px 0 0 5px;
            cursor: pointer;
            color: #4298F3;
          }
        }
        
        &::after, &::before {
          display: none;
          content: "";
          clear: both
        }
      }
      
      .viewInfo {
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: space-around;
        .progressView {
          cursor: pointer;
          position: relative;
          .formatText {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(calc(-50% + 6px), -50%);
            width: calc(64%);
            height: calc(64%);
            display: flex;
            align-items: center;
            justify-content: center;
            align-content: center;
            flex-wrap: wrap;
            text-align: center;
            font-weight: bold;
            border-radius: 50%;
            -webkit-box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.18);
            box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.18);
            .label {
              width: 100%;
              font-size: clamp(12px, 1.1vw, 18px);
              font-weight: bold;
              margin-bottom: 10px;
            }
            .value {
              width: 100%;
              font-size: clamp(14px, 1.8vw, 24px);
              font-weight: bold;
              color: #083BB5 ;
            }
          }
        }
        .Info {
          width: 50%;
          .textItem {
            width: 100%;
            margin-bottom: 15px;
            display: flex;
            align-items: center;
            img {
              width: 30px;
              height: 28px;
              margin-right: 5px;
            }
            .text {
              width: calc(100% - 35px);
              font-size: 13px;
              color: #666;
              font-weight: 600;
            }
          }
        }
        /deep/ {
          .el-divider--vertical {
            width: 1px;
            height: calc(100% - 40px);
            background-color: #ddd;
            box-shadow: -4.5px 0 12px 3px rgba(0,0,0, .1);
          }
          .el-progress {
            margin: 0 6px;
            position: relative;
            // 修改进度条文字提示颜色
            .el-progress__text {}
          }
          svg>path:nth-child(2) { 
            stroke: url(#write); // #write 此处的id就是定义的svg标签id 做替换即可 
          }
          .el-progress path:first-child { // 修改进度条背景色
            // stroke: #e1e1e1; 
          }
          .el-progress-circle {
            transform: rotateY(180deg);
          }
        }
      }
      /deep/ {
        .el-card__header {
          width: 100%;
          padding: 10px;
        }
        .el-card__body {
          padding: 10px;
          height: calc(100% - 64.8px);
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143

    案例较为粗浅,仅供参考!

    👉 三、效果演示

    效果图


    往期内容 💨

    🔥 < elementUi组件封装: 通过 el-tag、el-popover、vue动画等实现公告轮播 >

    🔥 < element-Ui表格组件:表格多选功能回显勾选时因分页问题,导致无法勾选回显的全部数据 >

    🔥 < 每日闲谈:你真的了解 “ ChatGPT ” 嘛 ? >

    🔥 < 每日算法 - JavaScript解析:搜索旋转排序数组 >

    🔥 < CSS小技巧:类似photoShop的混合模式(mix-blend-mode / background-blend-mode)使用 >

  • 相关阅读:
    pgsql_全文检索_使用空间换时间的方法支持中文搜索
    设计模式(一)——单例模式(Singleton)
    如何在Vuex中处理异步操作?
    Day36 移动端自动化
    FIFO(二) —— 手写同步和异步FIFO
    树莓派 Qt中 QCameraInfo 无法使用
    springBoot--web开发--WebMvcAutoConfiguration原理
    Boost搜索引擎
    三等分功分器[波导]设计详细教程
    谷歌浏览器修改背景色
  • 原文地址:https://blog.csdn.net/MrWen2395772383/article/details/130831389