Vue封装组件库-button组件

常见组件封装

使用vue create green-ui命令初始化一个vue项目

勾选如下

选择scss

选择eslint风格

选择保存时校验

选择In package.json

保存

输入项目名

创建项目成功

启动项目

然后把App.vue修改为如下内容

<template>
  <div id="app">
    定制组件
  </div>
</template>

<script>
export default {

}
</script>

<style lang="scss">

</style>

把router文件夹下的index.js修改为

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [

]

const router = new VueRouter({
  routes
})

export default router

然后把项目文件夹删除成如下状态

封装button组件

组件参数及事件

参数支持:

参数名参数描述参数类型默认值
type按钮类型(primary/success/warning/danger/info)stringdefault
plain是否是朴素按钮booleanfalse
round是否是圆角按钮booleanfalse
circle是否是圆形按钮booleanfalse
disabled是否禁用按钮booleanfalse
icon图标类名string

事件支持:

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

基本结构

在components下创建button.vue

<template>
  <button class="g-button">按钮组件</button>
</template>

<script>
export default {
  name: 'GButton'
}
</script>

<style>
</style>

其中name是表示该组件的名字,在引入的时候会用到这个组件名称。

接着在main.js文件中进行注册该组件

刷新浏览器,就可以看到调用的组件了

下面为组件添加样式,其中为插槽slot外套个span元素,可以方便为其设置样式,其中在style标签内写样式

<template>
  <button class="g-button">
    <!-- slot表示插槽,用于要用户自定义的内容 -->
    <span><slot></slot></span>
  </button>
</template>

<script>
export default {
  name: 'GButton'
}
</script>

<style lang="scss" scoped="scoped">
.g-button {
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: #fff;
  border: 1px solid #dcdfe6;
  color: #606266;
  -webkit-apprearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: 0.1s;
  font-weight: 500;
  // 禁止元素的文字被选中
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  padding: 12px 20px;
  font-size: 14px;
  border-radius: 4px;
  &:hover,
  &:focus {
    color: #409eff;
    border-color: #c6e2ff;
    background-color: #ecf5ff;
  }
}
</style>

浏览器查看效果

type属性

传递参数

在element-ui及其他ui组件中都有为按钮设置不同样式

所以需要根据不同的type设置不同的样式,这就涉及到组件通信问题了

学过vue的知道可以通过props来接收传过来的参数,如下代码

打开浏览器控制台后台查看

对props进行约束校验

如果传递是一个数值类型

那么控制台会报错

正确传递参数打印的情况

为不同type的按钮设计不同的样式,动态绑定type到class中进行样式设置

button.vue完整代码如下:

<template>
  <button class="g-button" :class="[`g-button-${type}`]">
    <!-- slot表示插槽,用于要用户自定义的内容 -->
    <span><slot></slot></span>
  </button>
</template>

<script>
export default {
  name: 'GButton',
  // 封装一个通用的组件,会对props做一个约束,即对props进行校验,校验方法参考官网
  props: {
    type: {
      // 数据类型:字符串
      type: String,
      default: 'default'// 不传type值,传默认值
    }
  },
  created () {
    console.log(this.type)
  }
}
</script>

<style lang="scss" scoped="scoped">
.g-button {
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: #fff;
  border: 1px solid #dcdfe6;
  color: #606266;
  -webkit-apprearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: 0.1s;
  font-weight: 500;
  // 禁止元素的文字被选中
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  padding: 12px 20px;
  font-size: 14px;
  border-radius: 4px;
  &:hover,
  &:focus {
    color: #409eff;
    border-color: #c6e2ff;
    background-color: #ecf5ff;
  }
}
.g-button-primary{
  color:#fff;
  background-color: #409eff;
  border-color: #409eff;
  &:hover,
  &:focus{
    background: #66b1ff;
    background-color: #66b1ff;
    color: #fff;
    }
  }
  .g-button-success{
  color:#fff;
  background-color: #67c23a;
  border-color: #67c23a;
  &:hover,
  &:focus{
    background: #85ce61;
    background-color: #85ce61;
    color: #fff;
    }
  }
  .g-button-info{
  color:#fff;
  background-color: #909399;
  border-color: #909399;
  &:hover,
  &:focus{
    background: #a6a9ad;
    background-color: #a6a9ad;
    color: #fff;
    }
  }
  .g-button-warning{
  color:#fff;
  background-color: #e6a23c;
  border-color: #e6a23c;
  &:hover,
  &:focus{
    background: #ebb563;
    background-color: #ebb563;
    color: #fff;
    }
  }
  .g-button-danger{
  color:#fff;
  background-color: #f56c6c;
  border-color: #f56c6c;
  &:hover,
  &:focus{
    background: #f78989;
    background-color: #f78989;
    color: #fff;
    }
  }
</style>

浏览器查看效果,有其他UI组件的外表了

plain属性

第一步:父组件传递plain值

第二步:子组件接收值

第三步:添加plain样式,由于plain类型是布尔值,所以在类型中我们使用对象的形式来控制样式

动态添加样式

第四步:设置plain的样式

其中plain的CSS样式如下:

// 朴素按钮样式
.g-button.is-plain {

  &:hover,
  &:focus {
    background: #fff;
    border-color: #489eff;
    color: #409eff;
  }
}

.g-button-primary.is-plain {
  color: #409eff;
  background: #ecf5ff;

  &:hover,
  &:focus {
    background: #409eff;
    border-color: #409eff;
    color: #fff;
  }
}

.g-button-success.is-plain {
  color: #67c23a;
  background: #c2e7b0;

  &:hover,
  &:focus {
    background: #67c23a;
    border-color: #67c23a;
    color: #fff;
  }
}

.g-button-info.is-plain {
  color: #909399;
  background: #d3d4d6;

  &:hover,
  &:focus {
    background: #909399;
    border-color: #909399;
    color: #fff;
  }
}

.g-button-warning.is-plain {
  color: #e6a23c;
  background: #f5dab1;

  &:hover,
  &:focus {
    background: #e6a23c;
    border-color: #e6a23c;
    color: #fff;
  }
}

.g-button-danger.is-plain {
  color: #f56c6c;
  background: #fbc4c4;

  &:hover,
  &:focus {
    background: #f56c6c;
    border-color: #f56c6c;
    color: #fff;
  }
}

第五步:查看浏览器效果

round属性

round是设置按钮圆角的

第一步:父组件传值

第二步:子组件接收值,并进行校验

第三步:动态添加class样式

第四步:设置round样式

.g-button.is-round{
  border-radius: 20px;
  padding: 12px 23px;
}

第五步:浏览器查看效果

circle属性

第一步:父组件传参

第二步:子组件通过props来接收参数

第三步:动态添加样式

第四步:设置circle样式

.g-button.is-circle {
  border-radius: 50%;
  padding: 12px;
}

第五步:浏览器查看效果

字体图标

第一步:下载字体图标

字体图标使用阿里巴巴矢量图标库的图标

搜索合适的图标添加到购物车

点击上方的购物车图标

下载下来,将文件复制到assets目录下创建的fonts文件夹中

然后在main.js中导入

第二步:修改图标样式

// 意思是只要类名中包括g-icon就调用该样式
[class*='g-icon'] {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

第三步:父组件传icon值

其中g-icon是上面的图标样式的设置,而icon-guanzhu是下载下来的图标名称

第四步:子组件接收值

接收一个string值,默认为空。

第五步:添加显示标签

设置icon中图标和文字之间的间隔样式

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

文字和图标的间隔有了,但是只有图标显示的时候却没有居中了,作如下处理

可以通过this.$slots获取到所有的插槽。本段代码通过v-if来判断如果有文本则显示文本,如果没有文本则不显示

查看效果

click事件

在使用组件时,直接给组件定义事件是不会被触发的。我们需要在组件中定义一个点击事件,这个点击事件不进行其他操作,只出发父组件中的点击事件。

第一步:在子组件中定义事件

第二步:父组件定义处理函数

第三步:浏览器查看效果

disabled属性

第一步:父组件传值

<g-button disabled @click="getType" icon="g-icon icon-guanzhu" round plain type="danger"></g-button>

第二步:子组件接收值

第三步:绑定属性

其中'is-disabled':disabled是绑定当按钮处于disabled状态时的CSS样式,而:disabled="disabled"是将按钮置于disabled状态。

第四步:设置样式

// disabled样式
.g-button.is-disabled{
   cursor: no-drop;
}

完整代码

button.vue的完整代码

<template>
  <button class="g-button" :class="[`g-button-${type}`, {
    'is-plain': plain,
    'is-round': round,
    'is-circle': circle,
    'is-disabled': disabled
  }]" @click="handleClick" :disabled="disabled">
    <!-- slot表示插槽,用于要用户自定义的内容 -->
    <!-- 传了icon才使用图标,没有传icon属性则不使用 -->
    <i v-if="icon" :class="icon"></i>
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>

<script>
export default {
  name: 'GButton',
  // 封装一个通用的组件,会对props做一个约束,即对props进行校验,校验方法参考官网
  props: {
    type: {
      // 数据类型:字符串
      type: String,
      default: 'default'// 不传type值,传默认值
    },
    plain: {
      type: Boolean,
      default: false
    },
    round: {
      type: Boolean,
      default: false
    },
    circle: {
      type: Boolean,
      default: false
    },
    icon: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    handleClick (e) {
      this.$emit('click', e)
    }
  }
}
</script>

<style lang="scss" scoped="scoped">
.g-button {
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: #fff;
  border: 1px solid #dcdfe6;
  color: #606266;
  -webkit-apprearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: 0.1s;
  font-weight: 500;
  // 禁止元素的文字被选中
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  padding: 12px 20px;
  font-size: 14px;
  border-radius: 4px;

  &:hover,
  &:focus {
    color: #409eff;
    border-color: #c6e2ff;
    background-color: #ecf5ff;
  }
}

.g-button-primary {
  color: #fff;
  background-color: #409eff;
  border-color: #409eff;

  &:hover,
  &:focus {
    background: #66b1ff;
    background-color: #66b1ff;
    color: #fff;
  }
}

.g-button-success {
  color: #fff;
  background-color: #67c23a;
  border-color: #67c23a;

  &:hover,
  &:focus {
    background: #85ce61;
    background-color: #85ce61;
    color: #fff;
  }
}

.g-button-info {
  color: #fff;
  background-color: #909399;
  border-color: #909399;

  &:hover,
  &:focus {
    background: #a6a9ad;
    background-color: #a6a9ad;
    color: #fff;
  }
}

.g-button-warning {
  color: #fff;
  background-color: #e6a23c;
  border-color: #e6a23c;

  &:hover,
  &:focus {
    background: #ebb563;
    background-color: #ebb563;
    color: #fff;
  }
}

.g-button-danger {
  color: #fff;
  background-color: #f56c6c;
  border-color: #f56c6c;

  &:hover,
  &:focus {
    background: #f78989;
    background-color: #f78989;
    color: #fff;
  }
}

// 朴素按钮样式
.g-button.is-plain {

  &:hover,
  &:focus {
    background: #fff;
    border-color: #489eff;
    color: #409eff;
  }
}

.g-button-primary.is-plain {
  color: #409eff;
  background: #ecf5ff;

  &:hover,
  &:focus {
    background: #409eff;
    border-color: #409eff;
    color: #fff;
  }
}

.g-button-success.is-plain {
  color: #67c23a;
  background: #c2e7b0;

  &:hover,
  &:focus {
    background: #67c23a;
    border-color: #67c23a;
    color: #fff;
  }
}

.g-button-info.is-plain {
  color: #909399;
  background: #d3d4d6;

  &:hover,
  &:focus {
    background: #909399;
    border-color: #909399;
    color: #fff;
  }
}

.g-button-warning.is-plain {
  color: #e6a23c;
  background: #f5dab1;

  &:hover,
  &:focus {
    background: #e6a23c;
    border-color: #e6a23c;
    color: #fff;
  }
}

.g-button-danger.is-plain {
  color: #f56c6c;
  background: #fbc4c4;

  &:hover,
  &:focus {
    background: #f56c6c;
    border-color: #f56c6c;
    color: #fff;
  }
}
.g-button.is-round{
  border-radius: 20px;
  padding: 12px 23px;
}
.g-button.is-circle {
  border-radius: 50%;
  padding: 12px;
}
// 意思是只要类名中包括g-icon就调用该样式
[class*='g-icon'] {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.g-button [class*=g-icon]+span {
  margin-left: 5px;
}
// disabled样式
.g-button.is-disabled{
   cursor: no-drop;
}
</style>

App.vue测试代码

<template>
  <div id="app">
    <div>
      <h1>type属性</h1>
      <g-button>按钮</g-button>
      <g-button type="primary">按钮</g-button>
      <g-button type="success">按钮</g-button>
      <g-button type="info">按钮</g-button>
      <g-button type="warning">按钮</g-button>
      <g-button type="danger">按钮</g-button>
    </div>
    <div>
      <h1>plain属性</h1>
      <g-button plain>按钮</g-button>
      <g-button plain type="primary">按钮</g-button>
      <g-button plain type="success">按钮</g-button>
      <g-button plain type="info">按钮</g-button>
      <g-button plain type="warning">按钮</g-button>
      <g-button plain type="danger">按钮</g-button>
    </div>
    <div>
      <h1>round属性</h1>
      <g-button round>按钮</g-button>
      <g-button round type="primary">按钮</g-button>
      <g-button round type="success">按钮</g-button>
      <g-button round type="info">按钮</g-button>
      <g-button round type="warning">按钮</g-button>
      <g-button round type="danger">按钮</g-button>
    </div>
    <div>
      <h1>circle属性</h1>
      <g-button circle>按钮</g-button>
      <g-button circle type="primary">按钮</g-button>
      <g-button circle type="success">按钮</g-button>
      <g-button circle type="info">按钮</g-button>
      <g-button circle type="warning">按钮</g-button>
      <g-button circle type="danger">按钮</g-button>
    </div>
    <div>
      <h1>icon属性</h1>
      <g-button icon="g-icon icon-guanzhu">按钮</g-button>
      <g-button icon="g-icon icon-guanzhu" type="primary">按钮</g-button>
      <g-button icon="g-icon icon-guanzhu" type="success">按钮</g-button>
      <g-button icon="g-icon icon-guanzhu" type="info">按钮</g-button>
      <g-button icon="g-icon icon-guanzhu" type="warning">按钮</g-button>
      <g-button icon="g-icon icon-guanzhu" type="danger">按钮</g-button>
    </div>
    <div>
      <h1>disabled属性</h1>
      <g-button disabled>按钮</g-button>
      <g-button disabled type="primary">按钮</g-button>
      <g-button disabled type="success">按钮</g-button>
      <g-button disabled type="info">按钮</g-button>
      <g-button disabled type="warning">按钮</g-button>
      <g-button disabled type="danger">按钮</g-button>
    </div>
    <div>
      <h1>click事件</h1>
      <g-button @click="getType">按钮</g-button>
      <g-button @click="getType" type="primary">按钮</g-button>
      <g-button @click="getType" type="success">按钮</g-button>
      <g-button @click="getType" type="info">按钮</g-button>
      <g-button @click="getType" type="warning">按钮</g-button>
      <g-button @click="getType" type="danger">按钮</g-button>
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    getType () {
      console.log('type')
    }
  }
}
</script>

<style lang="scss">

</style>

测试效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值