美文网首页Web前端之路前端开发那些事
实现一个基于Vue的Button小组件

实现一个基于Vue的Button小组件

作者: jaimor | 来源:发表于2019-07-09 10:38 被阅读5次

概述

原生HTML的button只能保证功能存在,样式都不怎么好看。当然也可以通过编写css样式来改变原生HTML中的button显示,但是现在各个UI框架都很流行,也很方便,很多时候都是直接引入框架就能获得非常好看、好用的样式组件。那么此篇文章使用Vue也来实现一个好看、使用的Button小组件。

实现

  1. button.vue
    首先需要在模板页面将基本button组件需要的元素进行组装
<template>
  <button
    :class="[
      'pm-button', `pm-button--${type}`, `pm-button--${size}`,
      {
        'pm-button--plain': plain,
        'pm-button--disabled': disabled
      },
      `pm-button--${shape}`
    ]"
    :disabled="disabled"
    @click="clickHandler"
  >
    <i v-else-if="icon" :class="['pm-button__icon pm-font', `pm-icon-${icon}`]"></i>
    <slot></slot>
  </button>
</template>

<script>
  const Constant = {
    typeMap: {
      default: "default",
      primary: "primary",
      success: "success",
      warning: "warning",
      danger: "danger"
    },
    buttonSizeMap: {
      large: "large",
      normal: "normal",
      small: "small",
      mini: "mini"
    },
    shapeMap: {
      default: "default",
      round: "round",
      circle: "circle"
    }
  }
  export default {
    name: "PmButton",
    props: {
      type: {
        default: Constant.typeMap.default,
        type: String
      },
      size: {
        default: Constant.buttonSizeMap.normal,
        type: String
      },
      plain: {
        default: false,
        type: Boolean
      },
      icon: String,
      loading: {
        default: false,
        type: Boolean
      },
      shape: {
        default: Constant.shapeMap.default,
        type: String
      },
      disabled: Boolean
    },
    methods: {
      clickHandler(event) {
        this.$emit("click", event);
      }
    }
  }
</script>

  1. button.less
    接下来需要为button添加不同种类的样式,适配使用的时候传入的值,而得到对应种类的button
@import "../common/index.less";    //额外的基础变量

.pm-button {
  position: relative;
  display: inline-block;
  border-radius: @button-border-radius;
  margin: 0;
  padding: 0;
  text-align: center;
  border: @button-border-width solid;
  box-sizing: border-box;
  outline: none;

  &::before {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100%;
    height: 100%;
    background-color: @black;
    border: inherit;
    border-color: @black;
    border-radius: inherit;
    transform: translate(-50%, -50%);
    opacity: 0;
    content: ' ';
  }
  &:active::before {
    opacity: .1;
  }

  &--default {
    color: @button-default-color;
    background-color: @button-default-background-color;
    border-color: @button-default-border-color;
  }
  &--primary {
    color: @button-primary-color;
    background-color: @button-primary-background-color;
    border-color: @button-primary-border-color;
  }
  &--success {
    color: @button-success-color;
    background-color: @button-success-background-color;
    border-color: @button-success-border-color;
  }
  &--warning {
    color: @button-warning-color;
    background-color: @button-warning-background-color;
    border-color: @button-warning-border-color;
  }
  &--danger {
    color: @button-danger-color;
    background-color: @button-danger-background-color;
    border-color: @button-danger-border-color;
  }

  &--large {
    font-size: @button-large-font-size;
    height: @button-large-height;
    line-height: @button-large-line-height;
    padding: @button-large-padding;
  }
  &--normal {
    font-size: @button-normal-font-size;
    height: @button-default-height;
    line-height: @button-default-line-height;
    padding: @button-normal-padding;
  }
  &--small {
    font-size: @button-small-font-size;
    height: @button-small-height;
    line-height: @button-small-line-height;
    padding: @button-small-padding;
    min-width: @button-small-min-width;
  }
  &--mini {
    font-size: @button-mini-font-size;
    height: @button-mini-height;
    line-height: @button-mini-line-height;
    padding: @button-mini-padding;
    min-width: @button-mini-min-width;
  }

  &--plain {
    background-color: @button-plain-background-color;
    &.pm-button--primary {
      color: @button-primary-background-color;
    }
    &.pm-button--success {
      color: @button-success-background-color;
    }
    &.pm-button--warning {
      color: @button-warning-background-color;
    }
    &.pm-button--danger {
      color: @button-danger-background-color;
    }
  }

  &--round {
    &.pm-button--large {
      border-radius: @button-large-height;
    }
    &.pm-button--normal {
      border-radius: @button-default-height;
    }
    &.pm-button--small {
      border-radius: @button-small-height;
    }
    &.pm-button--mini {
      border-radius: @button-mini-height;
    }
  }
  &--circle {
    padding: 0;
    &.pm-button--large {
      width: @button-large-height;
      border-radius: @button-large-height;
    }
    &.pm-button--normal {
      width:@button-default-height;
      border-radius: @button-default-height;
    }
    &.pm-button--small {
      width:@button-mini-height;
      border-radius: @button-small-height;
    }
    &.pm-button--mini {
      width:@button-mini-height;
      border-radius: @button-mini-height;
    }
  }

  &--disabled {
    opacity: .5;
  }

  &__icon {
    position: relative;
    top: .11rem;
  }
}
  1. 测试Button小组件
<template>
  <div>
    <h3>按钮种类</h3>
    <div class="default">
      <pm-button type="default">默认按钮</pm-button>
      <pm-button type="primary">普通按钮</pm-button>
      <pm-button type="success">成功按钮</pm-button>
      <pm-button type="warning">警告按钮</pm-button>
      <pm-button type="danger">危险按钮</pm-button>
    </div>
    <h3>按钮大小</h3>
    <div class="size">
      <pm-button size="large" type="primary">大按钮</pm-button>
      <pm-button size="normal" type="primary">普通按钮</pm-button>
      <pm-button size="small" type="primary">小按钮</pm-button>
      <pm-button size="mini" type="primary">Mini按钮</pm-button>
    </div>
    <h3>镂空按钮</h3>
    <div class="default">
      <pm-button type="primary" plain>普通按钮</pm-button>
      <pm-button type="success" plain>成功按钮</pm-button>
      <pm-button type="warning" plain>警告按钮</pm-button>
      <pm-button type="danger" plain>危险按钮</pm-button>
    </div>
    <h3>圆形按钮</h3>
    <div class="default">
      <pm-button type="primary" shape="round">普通按钮</pm-button>
      <pm-button icon="like-o" shape="circle"></pm-button>
    </div>
    <h3>图标按钮</h3>
    <div class="size">
      <pm-button type="success" icon="like-o"></pm-button>
      <pm-button type="primary" icon="search">搜索按钮</pm-button>
    </div>
    <h3>按钮点击</h3>
    <div class="size">
      <pm-button @click="btnClick" type="success">支付成功</pm-button>
      <pm-button @click="btnClick2">点击我</pm-button>
      <pm-button type="danger" disabled>被禁用</pm-button>
    </div>
  </div>
</template>

<script>
  export default {
    name: "ButtonTest",

    methods: {
      btnClick() {
        this.$toast.success("支付成功");
      },
      btnClick2(e) {
        console.log(e)
      }
    }
  }
</script>

<style scoped>
  .default, .size {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    flex-wrap: wrap;
  }
  button {
    margin: .2rem .6rem;
  }
  button:last-child {
    margin: .2rem 0 .2rem .6rem;
  }
</style>

效果展示

简单几个文件,就完成了组件化的button,当需要使用时,直接引入使用即可,简单方便,可复用。运行测试页面后,会得到这样的效果图。


效果展示

相关文章

网友评论

    本文标题:实现一个基于Vue的Button小组件

    本文链接:https://www.haomeiwen.com/subject/iqvtkctx.html