【VUE】封装Button组件思路及实现

引言

像平时前端开发中,我们经常使用elementUIiviewUI,移动端vantmint等等。那么他们的封装是如何实现的呢。

使用到的知识点

整体用到的vue的相关知识为:
prop
官方:Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。
通俗:父组件引用子组件并给子组件增加一个属性,并可以传递数据
插槽
官方:Vue 实现了一套内容分发的 API,将 slot元素作为承载分发内容的出口。
通俗:给一个组件传递一些内容
$emit
官方:监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
通俗:子组件可以使用 $emit 触发父组件的自定义事件,传递数据

举例

接下来就用常用的Button组件做例子。
要求及思路:

  1. 封装的组件要有基本的自定义功能,颜色,形状,类型等,并通过自定义属性进行传值(使用父传子prop的功能实现 )
  2. 对于样式的处理(先写好使用的样式,然后通过自定义属性去判断使用哪个样式)
  3. 使用$emit将能够使用到的事件传递出去

封装步骤

新建文件夹专门放封装的组件

Button.vue放封装的主体,建议再建一个js文件,export输出出去,因为以后可能同类封装的组件不知一个,如element对于Button还有一个button-group的组件
文件夹

封装Button组件
<template>
  <button
    @click="handleClick"
    :class="[
    // 此步为重要的步骤,主要是控制class来控制显示不同的按钮样式
    type ? 'ice-button--' + type : '',
    'button_init',
    {
    
    
      'is-plain': plain,
      'is-circle': circle
    }
    ]"
  >
    //使用插槽
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>

<script>
export default {
    
    
  name: 'Button',
  // 使用prop自定义属性
  props: {
    
    
    // type来定义button的类型
    type: {
    
    
      type: String,
      default: "normal",
    },
    // 是否为背景白色,边框和字体同颜色的简朴按钮
    plain: Boolean,
    // 是否为圆角按钮(在这里我是做了圆角处理不是完全圆)
    circle: Boolean,
  },
  computed: {
    
    },
  methods: {
    
    
    handleClick(evt) {
    
    
      this.$emit("click", evt);
    },
  },
};
</script>
样式

这里我简单写了几个三类样式

/* base */
.button_init {
    
    
  display: inline-block;
  margin: 10px;
  width: 90px;
  height: 45px;
  font-size: 12px;
  position: relative;
}
.button_init:active::after {
    
    
  content: "";
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 5%);
}
/* 普通按钮 */
.ice-button--normal {
    
    
  background: #474747;
  border: 1px solid #474747;
  color: #ffffff;
}
.ice-button--normal.is-plain {
    
    
  background: #fff;
  border: 1px solid #474747;
  color: #474747;
}
.ice-button--normal.is-plain.is-circle {
    
    
  background: #fff;
  border: 1px solid #474747;
  color: #474747;
  border-radius: 10px;
}
.ice-button--normal.is-circle {
    
    
  background: #474747;
  border: 1px solid #474747;
  color: #ffffff;
  border-radius: 10px;
}
/* 默认按钮 */
.ice-button--default {
    
    
  background: #1989fa;
  border: 1px solid #1989fa;
  color: #ffffff;
}
.ice-button--default.is-plain {
    
    
  background: #fff;
  border: 1px solid #1989fa;
  color: #1989fa;
}
.ice-button--default.is-plain.is-circle {
    
    
  background: #fff;
  border: 1px solid #1989fa;
  color: #1989fa;
  border-radius: 10px;
}
.ice-button--default.is-circle {
    
    
  background: #1989fa;
  border: 1px solid #1989fa;
  color: #ffffff;
  border-radius: 10px;
}
/* 警告按钮 */
.ice-button--error {
    
    
  background: #eb2f06;
  border: 1px solid #eb2f06;
  color: #ffffff;
}
.ice-button--error.is-plain {
    
    
  background: #fff;
  border: 1px solid #eb2f06;
  color: #eb2f06;
}
.ice-button--error.is-plain.is-circle {
    
    
  background: #fff;
  border: 1px solid #eb2f06;
  color: #eb2f06;
  border-radius: 10px;
}
.ice-button--error.is-circle {
    
    
  background: #eb2f06;
  border: 1px solid #eb2f06;
  color: #ffffff;
  border-radius: 10px;
}
/* 主要按钮 */
.ice-button--success {
    
    
  background: #2ecc71;
  border: 1px solid #2ecc71;
  color: #ffffff;
}
.ice-button--success.is-plain {
    
    
  background: #fff;
  border: 1px solid #2ecc71;
  color: #2ecc71;
}
.ice-button--success.is-plain.is-circle {
    
    
  background: #fff;
  border: 1px solid #2ecc71;
  color: #2ecc71;
  border-radius: 10px;
}
.ice-button--success.is-circle {
    
    
  background: #2ecc71;
  border: 1px solid #2ecc71;
  color: #ffffff;
  border-radius: 10px;
}
/* 警告按钮 */
.ice-button--warning {
    
    
  background: #f39c12;
  border: 1px solid #f39c12;
  color: #ffffff;
}
.ice-button--warning.is-plain {
    
    
  background: #fff;
  border: 1px solid #f39c12;
  color: #f39c12;
}
.ice-button--warning.is-plain.is-circle {
    
    
  background: #fff;
  border: 1px solid #f39c12;
  color: #f39c12;
  border-radius: 10px;
}
.ice-button--warning.is-circle {
    
    
  background: #f39c12;
  border: 1px solid #f39c12;
  color: #ffffff;
  border-radius: 10px;
}
js输出
import Button from './Button.vue'
export{
    
    
    Button
}

外部Vue使用:(简写)

    import {
    
     Button } from '@/components/Button/index'
    <div>
      <p class="explain_title">按钮类型</p>
      <Button type="normal">普通按钮</Button>
      <Button type="default">默认按钮</Button>
      <Button type="error">警告按钮</Button>
      <Button type="success">主要按钮</Button>
      <Button type="warning">警告按钮</Button>
    </div>
    <div>
      <p class="explain_title">朴素按钮</p>
      <Button plain type="normal">普通按钮</Button>
      <Button plain type="default">默认按钮</Button>
      <Button plain type="error">警告按钮</Button>
      <Button plain type="success">主要按钮</Button>
      <Button plain type="warning">警告按钮</Button>
    </div>
    <div>
      <p class="explain_title">圆角按钮</p>
      <Button circle plain type="normal">普通按钮</Button>
      <Button circle plain type="default">默认按钮</Button>
      <Button circle type="error">警告按钮</Button>
      <Button circle type="success">主要按钮</Button>
      <Button circle plain type="warning">警告按钮</Button>
    </div>
展示:

封装完成

结束

根据这个思路,还可以给封装的Button组件加上icon。比如element封装的Button
在这里插入图片描述
然后像其他的组件都可以使用此思路进行细致的封装,这里我只是简单的封装了下,具体也可以去找element或者其他库的源码去看看,学习一下。

猜你喜欢

转载自blog.csdn.net/ICe_sea753/article/details/108576401
今日推荐