zoukankan      html  css  js  c++  java
  • element-ui Progress、Badge、Alert组件源码分析整理笔记(四)

    Progress进度条组件

    <template>
        <!--最外层-->
      <div
        class="el-progress"
        :class="[
          'el-progress--' + type,
          status ? 'is-' + status : '',
          {
            'el-progress--without-text': !showText,
            'el-progress--text-inside': textInside,
          }
        ]"
        role="progressbar"
        :aria-valuenow="percentage"
        aria-valuemin="0"
        aria-valuemax="100"
      >
          <!--线形进度条-->
        <div class="el-progress-bar" v-if="type === 'line'">
          <!--进度条外部背景;strokeWidth:文档中说是宽度,这里是高度呀-->
          <div class="el-progress-bar__outer" :style="{height: strokeWidth + 'px'}">
            <!--进度条内部百分比-->
            <div class="el-progress-bar__inner" :style="barStyle">
                <!--线形进度条内部文字-->
              <div class="el-progress-bar__innerText" v-if="showText && textInside">{{percentage}}%</div>
            </div>
          </div>
        </div>
          <!--环形进度条-->
        <div class="el-progress-circle" :style="{height: width + 'px',  width + 'px'}" v-else>
          <svg viewBox="0 0 100 100">
            <path class="el-progress-circle__track" :d="trackPath" stroke="#e5e9f2" :stroke-width="relativeStrokeWidth" fill="none"></path>
            <path class="el-progress-circle__path" :d="trackPath" stroke-linecap="round" :stroke="stroke" :stroke-width="relativeStrokeWidth" fill="none" :style="circlePathStyle"></path>
          </svg>
        </div>
          <!--进度条外面文字内容-->
        <div class="el-progress__text" v-if="showText && !textInside" :style="{fontSize: progressTextSize + 'px'}">
            <!--进度条当前状态status值不存在时,显示百分比-->
          <template v-if="!status">{{percentage}}%</template>
            <!--进度条当前状态status值存在时-->
          <template v-else>
              <!--status为text,将文本内容插入显示-->
            <slot v-if="status === 'text'"></slot>
              <!--status为其他值时,显示对应的图标-->
            <i v-else :class="iconClass"></i>
          </template>
        </div>
      </div>
    </template>
    <script>
      export default {
        name: 'ElProgress',
        props: {
          type: { //进度条类型
            type: String,
            default: 'line',
            validator: val => ['line', 'circle'].indexOf(val) > -1
          },
          percentage: { //百分比(必填)
            type: Number,
            default: 0,
            required: true,
            validator: val => val >= 0 && val <= 100
          },
          status: { //进度条当前状态
            type: String,
            validator: val => ['text', 'success', 'exception'].indexOf(val) > -1
          },
          strokeWidth: { //进度条的宽度,单位 px
            type: Number,
            default: 6
          },
          textInside: { //进度条显示文字内置在进度条内(只在 type=line 时可用)
            type: Boolean,
            default: false
          },
           { //环形进度条画布宽度(只在 type=circle 时可用)
            type: Number,
            default: 126
          },
          showText: { //是否显示进度条文字内容
            type: Boolean,
            default: true
          },
          color: { //进度条背景色(会覆盖 status 状态颜色)
            type: String,
            default: ''
          }
        },
        computed: {
          //进度条内部百分比和背景颜色显示
          barStyle() {
            const style = {};
            style.width = this.percentage + '%';
            style.backgroundColor = this.color;
            return style;
          },
          relativeStrokeWidth() {
            return (this.strokeWidth / this.width * 100).toFixed(1);
          },
          trackPath() {
            const radius = parseInt(50 - parseFloat(this.relativeStrokeWidth) / 2, 10);
    
            return `M 50 50 m 0 -${radius} a ${radius} ${radius} 0 1 1 0 ${radius * 2} a ${radius} ${radius} 0 1 1 0 -${radius * 2}`;
          },
          perimeter() {
            const radius = 50 - parseFloat(this.relativeStrokeWidth) / 2;
            return 2 * Math.PI * radius;
          },
          circlePathStyle() {
            const perimeter = this.perimeter;
            return {
              strokeDasharray: `${perimeter}px,${perimeter}px`,
              strokeDashoffset: (1 - this.percentage / 100) * perimeter + 'px',
              transition: 'stroke-dashoffset 0.6s ease 0s, stroke 0.6s ease'
            };
          },
          stroke() {
            let ret;
            if (this.color) {
              ret = this.color;
            } else {
              switch (this.status) {
                case 'success':
                  ret = '#13ce66';
                  break;
                case 'exception':
                  ret = '#ff4949';
                  break;
                default:
                  ret = '#20a0ff';
              }
            }
            return ret;
          },
          iconClass() {
            if (this.type === 'line') {
              return this.status === 'success' ? 'el-icon-circle-check' : 'el-icon-circle-close';
            } else {
              return this.status === 'success' ? 'el-icon-check' : 'el-icon-close';
            }
          },
          //  进度条外文字的大小
          progressTextSize() {
            return this.type === 'line'
              ? 12 + this.strokeWidth * 0.4
              : this.width * 0.111111 + 2 ;
          }
        }
      };
    </script>
    
    

    Badge标记组件

    <template>
      <div class="el-badge">
        <slot></slot>
        <transition name="el-zoom-in-center">
            <!--is-fixed类用来定位上面数字的显示-->
          <sup
            v-show="!hidden && (content || content === 0 || isDot)"
            v-text="content"
            class="el-badge__content"
            :class="[
              'el-badge__content--' + type,
              {
                'is-fixed': $slots.default,
                'is-dot': isDot
              }
            ]">
          </sup>
        </transition>
      </div>
    </template>
    
    <script>
    export default {
      name: 'ElBadge',
    
      props: {
        value: {}, //显示值
        max: Number, //最大值,超过最大值会显示 '{max}+',要求 value 是 Number 类型
        isDot: Boolean, //小圆点
        hidden: Boolean, //隐藏 badge
        type: { //类型
          type: String,
          validator(val) {
            return ['primary', 'success', 'warning', 'info', 'danger'].indexOf(val) > -1;
          }
        }
      },
    
      computed: {
        // 返回显示的数据
        content() {
          //  如果是显示小圆点,直接返回
          if (this.isDot) return;
          const value = this.value;
          const max = this.max;
          if (typeof value === 'number' && typeof max === 'number') {
            // 如果显示值比最大值则显示'{max}+'
            return max < value ? `${max}+` : value;
          }
          return value;
        }
      }
    };
    </script>
    

    Alert 警告组件

    <template>
      <transition name="el-alert-fade">
          <!--最外层包裹标签-->
        <div
          class="el-alert"
          :class="[typeClass, center ? 'is-center' : '']"
          v-show="visible"
          role="alert"
        >
          <!--通过设置show-icon属性来显示 Alert 的 icon,这能更有效地向用户展示你的显示意图-->
          <i class="el-alert__icon" :class="[ iconClass, isBigIcon ]" v-if="showIcon"></i>
            <!--内容部分包含:提示的文案、描述、关闭按钮-->
          <div class="el-alert__content">
              <!--提示的文字-->
            <span class="el-alert__title" :class="[ isBoldTitle ]" v-if="title || $slots.title">
              <slot name="title">{{ title }}</slot>
            </span>
              <!--设置的辅助性文字-->
            <slot>
              <p class="el-alert__description" v-if="description">{{ description }}</p>
            </slot>
              <!--关闭按钮-->
            <i class="el-alert__closebtn" :class="{ 'is-customed': closeText !== '', 'el-icon-close': closeText === '' }" v-show="closable" @click="close()">{{closeText}}</i>
          </div>
        </div>
      </transition>
    </template>
    
    <script type="text/babel">
      const TYPE_CLASSES_MAP = {
        'success': 'el-icon-success',
        'warning': 'el-icon-warning',
        'error': 'el-icon-error'
      };
      export default {
        name: 'ElAlert',
    
        props: {
          title: { //标题
            type: String,
            default: ''
          },
          description: { //辅助性文字,也可通过默认 slot 传入
            type: String,
            default: ''
          },
          type: { //主题
            type: String,
            default: 'info'
          },
          closable: {  //是否可关闭
            type: Boolean,
            default: true
          },
          closeText: { //关闭按钮自定义文本
            type: String,
            default: ''
          },
          showIcon: Boolean, //是否显示图标
          center: Boolean  //文字是否居中
        },
    
        data() {
          return {
            visible: true
          };
        },
    
        methods: {
          close() {
            this.visible = false;
            this.$emit('close');
          }
        },
    
        computed: {
          // 根据type返回对应的类,主要用来显示alert组件背景色和文字的颜色
          typeClass() {
            return `el-alert--${ this.type }`;
          },
          // 根据type返回显示的图标
          iconClass() {
            return TYPE_CLASSES_MAP[this.type] || 'el-icon-info';
          },
          // 如果description存在显示大图标
          isBigIcon() {
            return this.description || this.$slots.default ? 'is-big' : '';
          },
          // 如果description存在,title加粗显示
          isBoldTitle() {
            return this.description || this.$slots.default ? 'is-bold' : '';
          }
        }
      };
    </script>
    
    
  • 相关阅读:
    10.C语言_Switch语句
    9.C语言_运算符和表达式分支语句
    问题是:js是如何实现鼠标移动到不同栏位切换对应的显示内容的?
    初识JavaScript,Ajax,jQuery,并比较三者关系
    使用母板页的内容页中js脚本应该放在什么位置,怎么调用
    如何让图片太大时自动缩小显示?
    网页视频播放器代码大全 + 21个为您的网站和博客提供的免费视频播放器
    flvplayer.swf flv视频播放器使用方法
    FileUpload检查上传文件扩展名,限制大小,创建路径存储
    几种代码生成器的叙述
  • 原文地址:https://www.cnblogs.com/fangnianqin/p/10043364.html
Copyright © 2011-2022 走看看