本篇文章记录一下,仿写一个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文章写完啦(手动捂脸哭),不过愚认为一直学习、一直输入、大抵便是不断进步吧