Badge 标记

逻辑分析

Badge组件相对来说比较简单,只有几个props入参,经过整理,我们可以得到如下的思维导图:

Badge逻辑分析

组件开发

对于简单的Badge组件来说,我们直接一步到位,不需要拆分基础实现和完善。

准备

在开发之前我们需要做一些前期的准备工作,按照我们在准备中提到的目录结构和规则,我们需要做以下步骤:

src/base目录下新建badge目录,并在新建的src/base/badge目录中,再新建两个文件,分别是index.jsbadge.vue

# 新建 badge目录
$ mkdir badge

# 新建index.js和badge.vue文件
$ cd badge
$ touch index.js
$ touch badge.vue

新建完毕后,src/base目录结构如下

|-- base
|   |-- star
|   |   |-- index.js
|   |   |-- star.vue
|   |-- badge
|   |   |-- index.js
|   |   |-- badge.vue

同时我们为badge.vue文件,撰写以下基础代码:

组件注册部分请参考Star组件。

<template>
  <div class="mooc-badge">
    badge
  </div>
</template>
<script>
export default {
  name: 'MoocBadge'
}
</script>

在以上步骤都正确完成后,我们在任意已经注册路由过的页面,使用mooc-badge组件,当出现badge文本内容即意味着Badge组件已经全局注册成功了。

开发

按照Badge组件逻辑分析部分,我们可以看到Badge组件只有几个props入参:

  • value: 标记的内容。
  • max:标记的最大值。
  • isDot: 是否小圆点。
  • type: 标记的类型。
  • hidden: 是否隐藏。

所以我们对于Badge组件的html结构划分如下:

<div class="mooc-badge">
  <slot></slot>
  <span
    v-show="showContent"
    class="mooc-badge-content"
    :class="[
      `mooc-badge-content-${type}`,
      {
        'is-absolute': $slots.default,
        'is-dot': isDot
      }
    ]"
    v-text="content"
  ></span>
</div>

javascript代码如下:

import { baseType } from 'assets/js/mooc.config.js'
export default {
  name: 'MoocBadge',
  props: {
    value: [String, Number],
    max: Number,
    isDot: {
      type: Boolean,
      default: false
    },
    hidden: {
      type: Boolean,
      default: false
    },
    type: {
      type: String,
      default: 'danger',
      validator (val) {
        return baseType.includes(val)
      }
    }
  },
  computed: {
    content () {
      if (this.isDot) {
        return ''
      }
      let value = +this.value
      if (Number.isNaN(value)) {
        return value
      }
      return value > this.max ? `${this.max}+` : value
    },
    showContent () {
      return !this.hidden && (this.content || +this.content === 0 || this.isDot)
    }
  }
}

分析

javascript代码分析:

  • validator验证:在props中,对于type参数我们使用了自定义validator,这是Vue中已经提供的内容。其中baseType为组件的公共状态,当用户传递的type值不是baseType数组中的任意一个时就提示错误。我们将其定义在src/assets/js/mooc.config.js文件中,代码如下:
// 基础类型
export const baseType = ['primary', 'success', 'warning', 'danger', 'info']
  • content内容content内容我们定义为一个计算属性,其具体的内容值根据isDotmax等控制。其中当maxvalue同为Number类型时,如果当前的value > max,则会以${value}+的形式显示。

html结构分析:

  • 模板语法:我们都知道,在js中可以使用模板语法,例如:${name},${age}中的内容,会被变量nameage替换,最终输出为一个字符串。而在Vue模板结构中,我们同样可以使用模板语法,通常在绑定一些样式或者其它内容的时候会非常有用,就像Badge组件中的模板语法,它最终会根据type的值为我们绑定不同的样式。例如:mooc-badge-content-dangermooc-badge-content-success

  • 绑定样式:在Vue官网中,它提供了几种绑定样式的方式,例如变量绑定、数组绑定和对象绑定,在以上代码中,我们有如下的一段代码:

:class="[
  `mooc-badge-content-${type}`,
  {
    'is-absolute': $slots.default,
    'is-dot': isDot
  }
]"

在以上代码中,我们在数组中又添加了一个对象,这是Vue所允许的,它将最终会解析成三个class

样式封装

在处理完Badge组件的html部分和javascript部分后,我们需要撰写css代码。其中第一步,我们需要提取Badge组件中关于变量的定义,并撰写在src/assets/theme/src/badge-variables.styl文件中,如果你没有这个文件,则需要新建,其代码如下:

$badge-veritcal-padding = 0
$badge-horizontal-padding = 6px
$badge-size = 18px
$badge-border-radius = 10px
$badge-border-width = 1px
$badge-border-style = solid
$badge-border-color = #fff
$badge-font-size = 12px
$badge-color = #fff
$badge-dot-size = 8px
$badge-dot-absolute-right = 5px

Badge组件css代码如下:

@import '~assets/theme/variables.styl';
@import '~assets/theme/src/badge-variables.styl';
.mooc-badge
  position: relative
  display: inline-block;
  vertical-align: middle;
  .mooc-badge-content
    display: inline-block;
    padding: $badge-veritcal-padding $badge-horizontal-padding;
    height: $badge-size;
    line-height: $badge-size;
    border-radius: $badge-border-radius;
    border: $badge-border-width $badge-border-style $badge-border-color;
    background-color: $base-danger;
    font-size: $badge-font-size;
    color: $badge-color;
    &-primary
      background-color: $base-primary;
    &-success
      background-color: $base-success;
    &-warning
      background-color: $base-warning;
    &-danger
      background-color: $base-danger;
    &-info
      background-color: $base-info;
    &.is-absolute
      position: absolute;
      top: 0;
      right: unit($badge-size / 2 + 1, 'px');
      transform: translate(100%, -50%);
      &.is-dot
        right: $badge-dot-absolute-right;
    &.is-dot
      position: absolute;
      top: 0;
      right: 0;
      padding: 0;
      width: $badge-dot-size;
      height: $badge-dot-size;
      border-radius: $base-border-radius-circle;

我们可以看到,Badge组件关于css几个状态的书写,是相同的结构。我们可以把这部分内容使用mixin的形式提取出来,放置到在src/assets/theme/mixin/badge-mixin.styl文件中,像下面这样:

badge-status($primaryColor, $successColor, $warningColor, $dangerColor, $infoColor)
  &-primary
    background-color: $primaryColor;
  &-success
    background-color: $successColor;
  &-warning
    background-color: $warningColor;
  &-danger
    background-color: $dangerColor;
  &-info
    background-color: $infoColor;

接下来在Badge组件中引用badge-mixin.stylBadge完整代码如下(改动参考高亮部分):



 














 
















@import '~assets/theme/variables.styl';
@import '~assets/theme/src/badge-variables.styl';
@import '~assets/theme/mixin/badge-mixin.styl';
.mooc-badge
  position: relative
  display: inline-block;
  vertical-align: middle;
  .mooc-badge-content
    display: inline-block;
    padding: $badge-veritcal-padding $badge-horizontal-padding;
    height: $badge-size;
    line-height: $badge-size;
    border-radius: $badge-border-radius;
    border: $badge-border-width $badge-border-style $badge-border-color;
    background-color: $base-danger;
    font-size: $badge-font-size;
    color: $badge-color;
    badge-status($base-primary, $base-success, $base-warning, $base-danger, $base-info);
    &.is-absolute
      position: absolute;
      top: 0;
      right: unit($badge-size / 2 + 1, 'px');
      transform: translate(100%, -50%);
      &.is-dot
        right: $badge-dot-absolute-right;
    &.is-dot
      position: absolute;
      top: 0;
      right: 0;
      padding: 0;
      width: $badge-dot-size;
      height: $badge-dot-size;
      border-radius: $base-border-radius-circle;

组件测试

在完成以上步骤后,我们完整的Badge组件已经开发完成了,接下来我们需要对组件进行必要的测试,测试代码如下:

<mooc-badge type="primary" :value="10">
  <div class="mooc-button">消息</div>
</mooc-badge>
<mooc-badge type="success" :value="100" :max="99">
  <div class="mooc-button">消息</div>
</mooc-badge>
<mooc-badge :value="100" :is-dot="true">
  <div class="mooc-button">消息</div>
</mooc-badge>
<mooc-badge value="hot">
  <div class="mooc-button">消息</div>
</mooc-badge>
<mooc-badge value="hot" :hidden="true">
  <div class="mooc-button">消息</div>
</mooc-badge>
.mooc-button {
  width: 60px;
  height: 36px;
  text-align: center;
  line-height: 36px;
  border: 1px solid #58a;
  color: #58a;
  border-radius: 4px;
}
.mooc-badge {
  margin-right: 30px;
}

Badge组件测试结果如下: Badge组件测试

组件文档

在以上Badge组件完善以后,我们将得到一个比较完整的星级评分组件,但仅仅只是有组件对我们来说并不是十分足够的,我们还需要撰写一份关于Badge组件的使用文档,组件文档结构按照以下内容来撰写:

  • 用法:Badge组件的用法以及对应的案例。
  • 属性:Badge组件每一个props属性的描述,包含类型,默认值以及说明。

Badge组件对应的文档地址为Star组件文档,你可以点击这个地址查看更对内容。

最后更新时间: 11/13/2019, 12:00:20 AM