仿饿了么UI搭建自己的组件库——Button

如果对sass不熟的朋友,建议看本博客之前先去看下sass教程,尤其是mixin和@include

sass中文文档

文件结构

├── src
│   ├── styles
│           ├── global.scss //定义全局的颜色之类的
|           ├── mixins //全部mixin文件
|                   ├── m-button.scss  //button的mixin文件
|           ├── button.scss 

自己的思路

颜色:通过传入的type,动态调用class

<button class="[color_type]"></button>
props:{
color:{
type:String,
default:"default"
}
},
computed:{
color_type{
return `color-${type}`}
}
.color-primary{
background:#5385ce;
color:#fff;
}

大体思路就是如此
但是这样写发现样式和尺寸特别好写,但是到了镂空效果的时候就不太好写了,而且样式代码十分冗长,不利于维护。于是果断去看饿了么UI的源码。看了一下午才看懂button

饿了么源码

  <button
    class="el-button"
    @click="handleClick"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :class="[
      type ? 'el-button--' + type : '',
      buttonSize ? 'el-button--' + buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }
    ]"
  >
    <i class="el-icon-loading" v-if="loading"></i>
    <i :class="icon" v-if="icon && !loading"></i>
    <span v-if="$slots.default"><slot></slot></span>
  </button>

大体的思路也都类似,动态绑定class,精华部分在于scss的编写。

1.首先定义全局的button

@include b(button) {
A区域
&.circle{
}
&.round{
}
&.plain{
}
}

//对应的mixin
@mixin b($block) {
  $B: $namespace+'-'+$block !global;

  .#{$B} {
    @content;
  }
}

这个的意思呢,就是我们平常写的

button{
}

@content表示占位符,会把A区域的内容全部放在对应的@content的位置。
.#{$B}这个不是id,而是变量值#{$B}

2.定义bem(自行百度)

说实话要是scss可以像js那样编写,就什么事都没了,直接一个判断完事。自动去匹配对应的样式,有点头疼。这里elem用的是mixin结合@include,button传入不同的参数,底下会有相应的include和它对应。

 @include btn_color(danger){
   background:$color-danger;
 }

 @mixin btn_color($color){
 @at-root{.color-#{$color}{
 @content}}
 }

简单理解就是在include里写对应的样式,然后在mixin中的对应的类下面显示。
@at-root的意思就是我不想要嵌套,具体可以看文档,因为当前类和button是同一级的,size也是如此,但是做镂空的效果就有点难度了。

因为我们无法获取对应按钮的颜色。镂空的效果是不同按钮hover,字体,背景颜色都不一样,很明显不能一套写死。而且颜色之类的都是可以区分不同的类的,而镂空效果的类都是.plain

参考了一下源码,源码的方法是在修改颜色的时候,给设置镂空样式的mixin传入一个颜色值。然后设置对应的.plain

  @include btn_color(danger){
    @include color_var($color-danger)
  }
  //mixin
  @mixin color_var($color){
    background:$color;
    border:1px solid $color;
    color:$color-white;
    &.plain{
      background:transparentize($color, .9);
      color:$color;
      border-color:$color;
      &:hover,
      &:focus {
      background: $color;
      border-color: $color;
      color: $color-white;
    }
    }
    &.disabled{
      opacity: 0.4;
    }
}

这样就完美解决了,可以根据颜色动态改变plain的样式
圆角和圆形也可以参考对应的做法。
disabled主要就是改变光标和背景透明度

&.disabled{
    cursor:not-allowed; 
    opactity:0.4;
}

3. 点击事件

我们使用组件获取点击事件,需要这样使用

<jed-button @click.native=""></jed-button>

显然这样不是很友好,需要设置一下。子组件向父组件传参即可

<button @click="handleClick">jed<button>
handleClick(e){
$emit("click",e)
}

ok完事

猜你喜欢

转载自blog.csdn.net/weixin_44003190/article/details/90722104