vue脚手架+TypeScrpt,实现vue的button组件封装

这是项目目录结构

UIButton.png

本次封装实现了vue组件button的封装,封装的属性包括:
控制大小:small、normal、large、xlarge
控制圆角:tile(直角)、rounded(半圆角)、circle(圆角)
控制静止:disable
控制颜色样式:color

App.vue

<template>
  <div id="app">
    <Home></Home>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Home from '@/Home.vue'
@Component({
  components: {
    Home,
  },
})
export default class App extends Vue {}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

home.vue

<template>
  <div class="container">
    <UiButton @click="onClick" >hello</UiButton>
  </div>

</template>
<script lang='ts'>
  import {Component, Vue} from 'vue-property-decorator'
  import UiButton from './components/UiButton/UiButton.vue'

  @Component({
    components: {
      UiButton,
    },
  })
  export default class Home extends Vue{
    private onClick(even: MouseEvent){
      window.console.log(even)
    }
  }
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
  .container
    .btn-group
      display flex
      margin-top 20px
      .btn
        margin-right 15px
</style>

UIButton.vue

<template>
  <div>
    <button class='ui-btn' @click="btnClick"
    :class="{
      'ui-btn-small': small,
      'ui-btn-normal': normal,
      'ui-btn-large': large,
      'ui-btn-xlarge': xlarge,
      'ui-btn-tile': tile,
      'ui-btn-rounded': rounded,
      'ui-btn-circle': circle,
      'ui-btn-disable': disable
    }"
    :style="`
      --color-tint:${TintColor}
    `"
    >
      <slot>Button</slot>
    </button>
  </div>
</template>
<script lang='ts'>
  // Emit用于发布事件,Prop用于接收参数
  import {Vue, Component, Emit, Prop} from 'vue-property-decorator'

  @Component
  export default class UiButton extends Vue{
    // 会从home获取到boolean值
    @Prop(Boolean) private small: boolean | undefined
    @Prop(Boolean) private normal: boolean | undefined
    @Prop(Boolean) private large: boolean | undefined
    @Prop(Boolean) private xlarge: boolean | undefined
    @Prop(Boolean) private tile: boolean | undefined
    @Prop(Boolean) private rounded: boolean | undefined
    @Prop(Boolean) private circle: boolean | undefined
    @Prop(Boolean) private disable: boolean | undefined
    @Prop(String) private color: string | undefined

    // vue的计算属性
    private get TintColor(){
      if(this.color){
        return this.color
      }else{
        return '#2d8cf0'
      }
    }

    // 执行btnClick调用emitClickEvent函数,并通过emitClickEvent发送click事件并且把参数一并发送出去
    @Emit('click') private emitClickEvent(even: MouseEvent){} // 这一行等价于this.$emit('click')

    private btnClick(even: MouseEvent){
      if(!this.disable){
        this.emitClickEvent(even)
      }
    }
  }
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
  resize(min-width, height, paddingR, fontSize)
    min-width min-width
    height height
    padding 0 paddingR
    font-size fontSize
    &.ui-btn-rounded, &.ui-btn-circle
      border-radius (@height / 2)
    &.ui-btn-circle
      min-width @height
      padding 0px 0px
  .ui-btn
    resize(64px, 36px, 16px, 0.875rem)
    border 0 solid black
    border-radius 4px
    text-align center
    outline none
    font-weight 500
    letter-spacing 0.09em
    background-color var(--color-tint)
    cursor pointer
    user-select none
    &:hover
      // 实现高亮
      filter brightness(120%)
    &:active
      filter brightness(80%)
    &.ui-btn-small
      resize(36px, 20px, 9px, 0.625rem)
    &.ui-btn-large
      resize(78px, 44px, 19px, 0.875rem)
    &.ui-btn-xlarge
      resize(92px, 52px, 23px, 1rem)
    &.ui-btn-tile
      border-radius 0
    &.ui-btn-disable
      cursor not-allowed
      background-color #f5f5f5
      color #c5c8ce
</style>

主要用到这个三个vue文件,引入UIButton之后,下面在Home.vue中的使用例子
<UiButton @click="onClick" xlarge circle disable color='#2dada'>hello</UiButton>
调用不同的属性就可以了,有需要的添加的属性也可以,在UIButton中自定义添加即可

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容