关于element-ui:elementui源码学习之仿写一个elbadge标记

5次阅读

共计 4032 个字符,预计需要花费 11 分钟才能阅读完成。

本篇文章记录一下,仿写一个 el-badge 标记提醒,有助于大家更好了解,饿了么 ui 的轮子具体工作细节。本文是 elementui 源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在 github 上,大家能够拉下来,npm start 运行跑起来,有助于更好的了解。github 仓库地址如下:https://github.com/shuirongsh…

知识点温习

还是像平常一样,为了便于更好的了解代码,咱们先温习一下,el-badge 组件 中应用的一些曝光度不是十分高的知识点 api

sup 和 sub 标签

  • sup 标签可定义文本上标内容(如平方、立方、未读音讯等 …)
  • sub 标签可定义文本下标内容(个别是迷信公式多一些)

代码举例:

<h5> 未读音讯 <sup style="color:red">99+</sup></h5>
<h5> 水是生命之源,化学分子式为:H<sub style="color:brown">2</sub>O</h5>

效果图:

由此咱们能够明了,sup 标签内写的文字,会主动放在右上方,也能够失常设置款式,所以应用 sup 标签用来做 el-badge 标记组件,确实是比拟适合的。

不过因为须要应用插槽传入定义内容,所以饿了么 UI 中应用 sup 标签不像上述嵌套的,相当于并排的,如:<h5> 未读音讯 </h5><sup style="color:red">99+</sup> 所以饿了么又通过款式定位批改其地位,使其在右上角了

props 中的 validator 校验函数

假如需要:父组件传递给子组件的 age 属性字段的值须要为数字类型的

咱们个别都会这样写:

props: {age: Number,},

或者这样写(额定指定一个默认值):

props: {
  age: {
    type: Number,
    default: 100,
  }
},

这样写个别也就够用了,不过如果要精细化校验,就须要应用 props 校验某个属性字段自带的 validator 函数了。

比方新需要:父传子的 age 属性字段需为数字类型、且不能超过 180

于是乎,咱们应用 validator 函数能够这样写:

props: {
    age: {
      type: Number,
      default: 100,
      validator(val) { // validator 函数接管的参数是父传子此字段的值
        if (val <= 180) {return true; // 返回 true 代表校验通过,不报 [Vue warn] 正告
        } else {return false; // 返回 false 代表校验不通过,报 [Vue warn] 正告,告知用户传值不对
        }
      },
    },
}

这样的话,确实是更不便精细化管制父传子参数了。官网阐明:https://cn.vuejs.org/v2/guide…

仿写效果图

应用代码

<template>
  <div class="wrap">
    <my-badge :value="11" type="primary">
      <h5>primary 类型 </h5>
    </my-badge>
    <br />
    <br />
    <my-badge :value="22" type="success">
      <h5>success 类型 </h5>
    </my-badge>
    <br />
    <br />
    <my-badge value="0" type="warning">
      <h5>warning 类型 </h5>
    </my-badge>
    <br />
    <br />
    <my-badge :value="44" type="info">
      <h5>info 类型 </h5>
    </my-badge>
    <br />
    <br />
    <my-badge :value="55" type="danger">
      <h5>danger 类型 </h5>
    </my-badge>
    <br />
    <br />
    <my-badge :value="188" :max="99">
      <h5> 指定 max 最大值 99</h5>
    </my-badge>
    <br />
    <br />
    <my-badge is-dot>
      <h5> 小圆点 </h5>
    </my-badge>
    <br />
    <br />
    <my-badge value="热点追踪">
      <h5>《震惊!一程序猿青天白日居然... 网友必看!》</h5>
    </my-badge>
    <br />
    <br />
    <my-badge :isShow="isShow" value="^@^">
      <h5> 暗藏 </h5>
    </my-badge>
    <br /><button @click="isShow = !isShow"> 暗藏显示切换 </button>
  </div>
</template>

<script>
export default {data() {return { isShow: true} },
};
</script>

<style lang="less" scoped> .wrap {width: 100%; height: 100%; padding: 24px;} </style>

仿写封装代码

<template>
  <div class="my-badge">
    <slot></slot>
    <!-- 应用 sup 上标,让 sup 标签内的文字内容渲染在的右上角(须要嵌套),然而
    这里的写法不会让 sup 标签的文字间接渲染到右上角,还需定位挪动管制一下款式 -->
    <transition name="el-zoom-in-center">
      <!-- el-zoom-in-center 过渡动画是自带的哦,咱们间接加上就能用啦 -->
      <sup
        v-show="showSup"
        :class="['fixedRightTop',
          typeArr.includes(type) ? type : '',  /** 类型数组是否蕴含传进来的类型,蕴含就利用此类型款式,不蕴含就不利用类型款式 */
          isDot ? 'isDotClass' : '',  /** isDot 为 true 就加上小圆点款式类型 */
        ]"v-text="showValue"
      ></sup>
    </transition>
  </div>
</template>

<script>
// 定义这五种类型
const typeArr = ["primary", "success", "warning", "info", "danger"];
export default {
  name: "myBadge",
  props: {value: [String, Number],
    type: {
      type: String,
      validator(val) {// console.log("校验参数", val);
        // props 也能够退出类型校验函数,vue 自带的哦,不合乎就抛出正告
        if (typeArr.includes(val)) {return true;} else {return false;}
      },
    },
    max: {
      type: Number,
      validator(val) { // 校验最大值要是数字
        if (val) {if (typeof val === "number") {return true;} else {return false;}
        } else {return true;}
      },
    },
    isDot: Boolean,
    isShow: {
      // 默认展现
      type: Boolean,
      default: true,
    },
  },
  data() { return { typeArr} },
  computed: {showValue() {
      // 如果是小圆点,就不必返回值
      if (this.isDot) {return;}
      // 如果告知最大值,就做一个判断
      if (this.max) {return this.value > this.max ? `${this.max}+` : this.value;
      }
      // 其余的状况,无论是数字或者自定义文字,就失常显示即可
      else {return this.value;}
    },
    showSup() {
      // isShow 为 false 就暗藏喽
      if (!this.isShow) {return false;}
      // 内容为空,也暗藏咯
      if (this.value === "") {return false;}
      // 其余失常显示
      return true;
    },
  },
};
</script>

<style lang="less" scoped>
.my-badge {
  position: relative;
  vertical-align: middle;
  display: inline-block; // 把块元素转换成行内块元素,如此,宽度便由内容撑开了
  // 通过定位,把上标定位到右上角的哦
  .fixedRightTop {
    position: absolute; // 因为上方 display: inline-block; 了
    top: 0; // 所以定位才正好在插槽内容的右上方了,否则块元素默认宽度 100%,那定位就在最右侧了
    right: 3px; // 然而还须要 transform 平移一下
  }
  sup {
    color: #fff;
    background-color: #f56c6c; // 默认淡红色
    border-radius: 10px; // 加个圆角难看些
    padding: 1px 4px;
    font-size: 12px; // 上标字体要设置最小
    transform: translate(100%, -50%); // 要挪动一下才行
    white-space: nowrap; // 自定义文字内容会换行,通过 css 管制,使之不换行
  }
  // 五种类型配色,这里间接抄官网的
  .primary {background-color: #409eff;}
  .success {background-color: #67c23a;}
  .warning {background-color: #e6a23c;}
  .info {background-color: #909399;}
  .danger {background-color: #f56c6c;}
  // 小圆点加款式
  .isDotClass {height: 8px; width: 8px; right: 1px; border-radius: 50%;}
}
</style>

总结

好了,一篇 water 文章 写完啦(手动捂脸哭),不过愚认为一直学习、一直输入、大抵便是不断进步吧

正文完
 0