从0搭建Vue2 UI组件库(一)

1,565 阅读2分钟

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

今天这篇文章来写写如何用vue2.x来从0开始搭建一个UI组件库,感兴趣的童鞋请往下冲~~

系统:win10

手脚架:vue-cli@4.5.12

一、创建项目

vue create zhbx-ui

image.png

选择Manually select features,手动选择需要的插件:

  • Babel
  • CSS Pre-processors
  • Linter / Formatter
  • Unit Testing

image.png

然后选择vue版本,这里选择vue2.x:

image.png 选择sass:

image.png

选择eslint风格:

image.png

选择测试库:选择ESLint + Prettier,

选择配置文件生成位置:

image.png

项目创建成功后删除App.vue文件中关于Helloworld组件的代码,删除components和assets文件夹中的内容。

下面开始封装组件啦~~

二、封装button组件

重点:

  1. 对于自定义的内容使用slot

  2. 查询slot是否有自定义内容用$slots

  3. 获取有相似类名的类可用[class*=j-icon-]

1.参数支持

参数名参数类型参数描述默认值
typestring按钮类型(primary/success/info/warning/danger)primary
plainboolean是否是朴素按钮false
roundboolean是否是圆角按钮false
circleboolean是否是圆形按钮false
disabledboolean是否是禁用按钮false
iconstring图标类名

1.1.获取按钮名称: 用户可以给按钮设置名称,所以我们需要使用插槽slot来获取按钮名称。

<div class="zh-button">
    <span v-if="$slots.default">
      <slot></slot>
    </span>
</div>

1.2. 获取type属性 获取用户设置的属性可以用props,为了避免用户乱传数据,所以我们需要对属性进行校验,限制其只能为String类型。

props: {
    type: {
      type: String,
      default: "primary",
    },
},

将获取到的type属性设置为类名,对不同类名的按钮设置不同的颜色,即可在用户传入不同的type时返回不同颜色的按钮。

<div class="zh-button" :class="[`zh-button--${type}`]">
    <span>
      <slot></slot>
    </span>
</div>

1.3. 获取plain、round、circle属性 这三个属性一样是通过props获取与校验,一样设置为类名,通过不同类名来展示不同状态。

<div class="zh-button" :class="[`zh-button--${type}`, {
    'is-plain': plain, 
    'is-circle': circle, 
    'is-round': round
}]">
    <span>
      <slot></slot>
    </span>
</div>

1.4. 设置disabled属性

disabled属性的获取与上面四个属性一样,都是通过props获取,设置为类名,通过不同类名来展示不同状态。

不过有一个重点是,disabled要真正的被设置到,所以我们还需要加上原生的disabled属性。

<div
    class="zh-button"
    :class="[
      `zh-button--${type}`,
      {
        'is-plain': plain,
        'is-circle': circle,
        'is-round': round,
        'is-disabled': disabled
      }]"
    :disabled="disabled"
  >
    <span v-if="$slots.default"><slot></slot></span>
</div>

1.5. 设置icon属性

  • 从iconfont上下载所需要的图标,放到src/assets/font文件夹中。
  • 将iconfont.css文件中的 .iconfont类名改为[class*="zh-icon-"],这样使用的时候就可以不用加上iconfont类名了。
  • 先在全局(main.js)引入iconfont.css文件。
  • Button组件中设置接收icon:
<div
    class="zh-button"
    :class="[
      `zh-button--${type}`,
      {
        'is-plain': plain,
        'is-circle': circle,
        'is-round': round,
        'is-disabled': disabled
      }]"
    :disabled="disabled"
  >
    <i v-if="icon" :class="icon"></i>
    <span v-if="$slots.default"><slot></slot></span>
</div>

给所有icon后面的文字加上一个间距:

.zh-button [class*="zh-icon-"]+span {
  margin-left: 5px;
}

2.事件支持

事件名事件描述
click点击事件

如果我们没有给button组件添加click事件支持的话,用户在设置click事件时是没有反应的。

所以我们应当给button添加click事件,使用$emit触发用户传入的click事件,返回事件对象e。

<template>
  <div
    class="zh-button"
    :class="[
      `zh-button--${type}`,
      {
        'is-plain': plain,
        'is-circle': circle,
        'is-round': round,
        'is-disabled': disabled
      }]"
    :disabled="disabled"
    @clcik="handleClick"
  >
    <i v-if="icon" :class="icon"></i>
    <span v-if="$slots.default"><slot></slot></span>
  </div>
</template>

<script>
export default {
  name: "ZhButton",
  props: {
    type: {
      type: String,
      default: "default",
    },
    plain: {
      type: Boolean,
      default: false,
    },
    circle: {
      type: Boolean,
      default: false,
    },
    round: {
      type: Boolean,
      default: false,
    },
    icon: {
      type: String,
      default: ""
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    handleClick(e) {
      // 触发用户的click事件,返回事件对象e
      this.$emit('click', e)
    }
  }
};
</script>