[Element Plus 源码解析] Button 按钮

2,761 阅读1分钟

一、组件介绍

官网链接:Button 组件 | Element (gitee.io)

Button组件是最常用的组件之一,是常用的操作按钮。

1.1 属性

展示类:

  • size: string类型,设置按钮的尺寸,可选值为medium / small / mini ,不传时为默认尺寸;不传时实际尺寸会受全局设置的size及ElForm父组件设置的size影响;
  • type: string类型,设置按钮的类型,可选值为primary / success / warning / danger / info / text;
  • plain: boolean类型,设置为朴素按钮,默认值为false;
  • round: boolean类型,设置为圆角按钮,默认值为false;
  • circle: boolean类型,设置为圆形按钮,默认值为false;
  • icon: string类型,设置按钮中展示的图标;

状态类:

  • loading: boolean类型,设置加载状态,默认值为false;
  • disabled: boolean类型,设置禁用状态,默认值为false,不设置时受ElForm父组件的禁用状态影响;

原生属性类:

  • autofocus: boolean类型,设置是否默认聚焦,默认值为false;
  • native-type: string类型,设置原生 type 属性,可选值为: button / submit / reset,默认值为button。

1.2 事件

  • click: 按钮点击事件

二、源码分析

2.1 tempalte

<template>
  <button
    :class="[
      'el-button',
      type ? 'el-button--' + type : '',
      buttonSize ? 'el-button--' + buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }
    ]"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    @click="handleClick"
  >
    <i v-if="loading" class="el-icon-loading"></i>
    <i v-if="icon && !loading" :class="icon"></i>
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>

2.2 script

setup(props: IButtonProps, { emit }) {
    // 获取全局设置
    const $ELEMENT = useGlobalConfig()
    
    // 注入elForm/elFormItem 提供的数据
    const elForm = inject(elFormKey, {} as ElFormContext)
    const elFormItem = inject(elFormItemKey, {} as ElFormItemContext)

    const buttonSize = computed(() => {
      // size取值:props传入 > 父ElFormItem组件设置 > 全局设置
      return props.size || elFormItem.size || $ELEMENT.size
    })
    const buttonDisabled = computed(() => {
      // disabled取值:props传入 > 父ElForm组件设置
      return props.disabled || elForm.disabled
    })

    //methods
    const handleClick = (evt: MouseEvent) => {
      emit('click', evt)
    }

    return {
      buttonSize,
      buttonDisabled,
      handleClick,
    }
  }

2.3 总结

  1. 需要考虑全局设置的size;
  2. Button组件可能用在Form组件中,需要考虑ElForm/ElFormItem上的设置,这些设置通过provide/inject的方式向Button组件提供,