手把手教你封装简单的按钮组件


一、效果图

在这里插入图片描述

二、编写工作

1.创建一个vue项目

cmd打开终端输入
vue create 项目名称

在这里插入图片描述
vscode打开项目(略)

2.在项目的component文件夹下新建一个 c-button.vue文件

3.在c-button.vue下编写css代码

(1)使用原生的 button 进行改造

 <button>这是一个按钮</button>

(2)给按钮加上固定样式

指不会变得样式 例如 按钮文字的粗细、按钮文字的中心居中

// 固定样式样式
button{
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 500;
}

这里用到的是 flex 布局,不了解的可以点击flex按钮分析看我写的一篇flex布局案例分析

(3)给定按钮公共样式

指在不同的类型的按钮中都会用到的样式 但却不是每个按钮动能用到

// 按钮公共样式
.defaultTyeStyle{
  color: #fff;
  border-radius: 4px;
  border:none;
}

(4)编写不同大小的按钮大小形式

//中型按钮
.medium{
  width: 93px;
  height: 39px;
  font-size: medium;
}
//小型按钮
.small{
  width: 79px;
  height: 31px;
  font-size: small;
}
//迷你型按钮
.mini{
  width: 79px;
  height: 27px;
  font-size: smaller;
}

(5)编写不同种类的按钮样式

//主要按钮
.primary{
  background-color: #409EFF;
  // border-color: 1px rgb(36, 100, 250) solid;
	/* 注意这里注意注意注意*/
  .defaultTyeStyle() /*混合写法----将上面的公共样式混入 需要用到 css预处理器 less*/
}
//没有样式的按钮(默认)
.null{
  .defaultTyeStyle();
  background-color: rgb(255, 255, 255);
  color: #424040;
  border:1px #909399 solid;
  // border-radius: 4px;
}
//成功按钮
.success{
  background-color:#67C23A;
  // color: #ffffff;
  .defaultTyeStyle()
}
//警告按钮
.warning{
  background-color: #E6A23C;
  // color: #ffffff;
 .defaultTyeStyle()
}
//危险按钮
.danger{
  background-color: #F56C6C;
  // color: #ffffff;
 .defaultTyeStyle()
}

4.在c-button.vue下编写javascript代码

//在实例中加入props属性 方便自定义按钮属性
props:{
//按钮类型
    type:{
    },
//按钮大小    
    size:{
    },
//按钮形状
    shape:{     
    },
//按钮背景    
    back:{
    }
  }

(1)编写属性

type

 type:{
      type:String, //定义数据类型
      default:'null', //设置默认值
      validator(value) { //自定义选项(type值只能在里面选择)
        // The value must match one of these strings
        return ['null','primary','success', 'warning', 'danger'].includes(value)
      }
    },

size

size:{
      type:String,
      default:'medium',
      validator(value) {
        // The value must match one of these strings
        return ['medium','small', 'mini'].includes(value)
      }
    },

shap

shape:{
      type:String,
      default:'square',
      validator(value) {
        // The value must match one of these strings
        return ['square','round'].includes(value)
      }
    },

back

back:{
      type:String,
      default:'solid',
      validator(value) {
        // The value must match one of these strings
        return ['solid','plain'].includes(value)
      }
    }

(2)data定义引用样式

 data(){
    return{
      typeStyle:'', //按钮类型
      sizeStyle:'', //按钮大小
      shapStyle: {
        borderRadius:'30px' //自定义按钮圆角大小
      },
    }
  },

(3)methods编写引用样式方法

methods:{
//引用大小方法
    getSize(){
      switch(this.size) {
          case 'medium':
              this.sizeStyle = 'medium'
              break;
          case 'small':
              this.sizeStyle = 'small'
              break;
          case 'mini':
              this.sizeStyle = 'mini'
              break; 
      } 
    },
    //引用类型发放
    getType(){
      switch(this.type) {
          case 'null':
              this.typeStyle = 'null'
              break;
          case 'primary':
              this.typeStyle = 'primary'
              break;
          case 'success':
              this.typeStyle = 'success'
              break;
          case 'warning':
              this.typeStyle = 'warning'
              break; 
          case 'danger':
              this.typeStyle = 'danger'
              break;  
      }
    },
    //引用形状方法
    getShap(){
      if(this.shape == 'round'){
        this.shapStyle.borderRadius = '30px'
      }else{
        this.shapStyle.borderRadius = '4px'
      }
    } 
  },

(4)button标签样式绑定

<button :style="[shapStyle]" :class="[typeStyle,sizeStyle]">
</button>

(5)使用插槽

<button :style="[shapStyle]" :class="[typeStyle,sizeStyle]">
      <template>
        <div>
          <slot></slot>
        </div>
      </template>
    </button>

(6)引入组件并使用

<template>
  <!-- 按钮组件的封装 -->
  <div style="padding: 10px;">
    <CButtonVue  @click.native="okk"> 原始按钮 </CButtonVue>
    <CButtonVue type="primary" @click.native="okk">主要按钮</CButtonVue>
    <CButtonVue type="success" @click.native="okk">成功按钮</CButtonVue>
    <CButtonVue type="warning" @click.native="okk">警告按钮</CButtonVue>
    <CButtonVue type="danger"  @click.native="okk">危险按钮</CButtonVue>

    <br>

    <CButtonVue type="danger" @click.native="okk">默认按钮</CButtonVue>
    <CButtonVue type="primary" size="medium" @click.native="okk">中型按钮</CButtonVue>
    <CButtonVue type="success" size="small" @click.native="okk">小型按钮</CButtonVue>
    <CButtonVue type="warning" size="mini" @click.native="okk">迷你按钮</CButtonVue>
    
    <br>
    <CButtonVue type="primary" shape="round" @click.native="okk">主要按钮</CButtonVue>
    <CButtonVue type="success" shape="round" @click.native="okk">成功按钮</CButtonVue>
    <CButtonVue type="warning" shape="round" @click.native="okk">警告按钮</CButtonVue>
    <CButtonVue type="danger"  shape="round" @click.native="okk">危险按钮</CButtonVue>

  </div>
</template>

<script>
import CButtonVue from './c-button.vue';
export default{
  components:{
    CButtonVue
  },
  methods:{
    okk(){
      alert('sbi')
    }
  }
}
</script>

<style lang="less" scoped>

</style>

三、最终代码

<template>
  <!-- 按钮组件的封装 -->
  <div>
    <button :style="[shapStyle]" :class="[typeStyle,sizeStyle]">
      <template>
        <div>
          <slot></slot>
        </div>
      </template>
    </button>
  </div>
</template>

<script>
export default{
  props:{
    type:{
      type:String,
      default:'null',
      validator(value) {
        // The value must match one of these strings
        return ['null','primary','success', 'warning', 'danger'].includes(value)
      }
    },
    size:{
      type:String,
      default:'medium',
      validator(value) {
        // The value must match one of these strings
        return ['medium','small', 'mini'].includes(value)
      }
    },
    shape:{
      type:String,
      default:'square',
      validator(value) {
        // The value must match one of these strings
        return ['square','round'].includes(value)
      }
    },
    back:{
      type:String,
      default:'solid',
      validator(value) {
        // The value must match one of these strings
        return ['solid','plain'].includes(value)
      }
    }
  },
  data(){
    return{
      typeStyle:'',
      sizeStyle:'',
      shapStyle: {
        borderRadius:'30px'
      },
    }
  },
  methods:{
    getSize(){
      switch(this.size) {
          case 'medium':
              this.sizeStyle = 'medium'
              break;
          case 'small':
              this.sizeStyle = 'small'
              break;
          case 'mini':
              this.sizeStyle = 'mini'
              break; 
      } 
    },
    getType(){
      switch(this.type) {
          case 'null':
              this.typeStyle = 'null'
              break;
          case 'primary':
              this.typeStyle = 'primary'
              break;
          case 'success':
              this.typeStyle = 'success'
              break;
          case 'warning':
              this.typeStyle = 'warning'
              break; 
          case 'danger':
              this.typeStyle = 'danger'
              break;  
      }
    },
    getShap(){
      if(this.shape == 'round'){
        this.shapStyle.borderRadius = '30px'
      }else{
        this.shapStyle.borderRadius = '4px'
      }
    } 
  },
  mounted(){
    this.getSize()
    this.getType()
    this.getShap()
  }
}
</script>

<style lang="less" scoped>
@defaultBoder:'none';
// 按钮公共样式
.defaultTyeStyle{
  color: #fff;
  border-radius: 4px;
  border:none;
}

.medium{
  width: 93px;
  height: 39px;
  font-size: medium;
}

.small{
  width: 79px;
  height: 31px;
  font-size: small;
}

.mini{
  width: 79px;
  height: 27px;
  font-size: smaller;
}

// 基础样式
button{
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 500;
}

.primary{
  background-color: #409EFF;
  // border-color: 1px rgb(36, 100, 250) solid;
  .defaultTyeStyle()
}

.null{
  .defaultTyeStyle();
  background-color: rgb(255, 255, 255);
  color: #424040;
  border:1px #909399 solid;
  // border-radius: 4px;
}
.success{
  background-color:#67C23A;
  // color: #ffffff;
  .defaultTyeStyle()
}
.warning{
  background-color: #E6A23C;
  // color: #ffffff;
 .defaultTyeStyle()
}
.danger{
  background-color: #F56C6C;
  // color: #ffffff;
 .defaultTyeStyle()
}
</style>

总结

多了解 less 真的超好用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值