Button

3 阅读10分钟

button

<template>
  <button
    class="el-button"
    @click="handleClick"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :class="[
      type ? 'el-button--' + type : '',
      buttonSize ? 'el-button--' + buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }
    ]"
  >
    <!-- 加载状态时显示加载图标 -->
    <i class="el-icon-loading" v-if="loading"></i>
    <!-- 非加载状态且有图标时显示图标 -->
    <i :class="icon" v-if="icon && !loading"></i>
    <!-- 有默认插槽内容时显示 -->
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>
<script>
  export default {
    name: 'ElButton',

    // 注入父组件提供的表单和表单项实例
    inject: {
      elForm: {
        default: ''
      },
      elFormItem: {
        default: ''
      }
    },

    props: {
      // 按钮类型,决定按钮的颜色样式
      type: {
        type: String,
        default: 'default'
      },
      // 按钮尺寸
      size: String,
      // 按钮图标类名
      icon: {
        type: String,
        default: ''
      },
      // 原生按钮的 type 属性
      nativeType: {
        type: String,
        default: 'button'
      },
      // 是否为加载状态
      loading: Boolean,
      // 是否禁用按钮
      disabled: Boolean,
      // 是否为朴素按钮
      plain: Boolean,
      // 是否自动获取焦点
      autofocus: Boolean,
      // 是否为圆角按钮
      round: Boolean,
      // 是否为圆形按钮
      circle: Boolean
    },

    computed: {
      // 获取表单项的尺寸配置
      _elFormItemSize() {
        return (this.elFormItem || {}).elFormItemSize;
      },
      // 计算按钮的实际尺寸
      buttonSize() {
        return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
      },
      // 计算按钮的实际禁用状态
      buttonDisabled() {
        return this.$options.propsData.hasOwnProperty('disabled') ? this.disabled : (this.elForm || {}).disabled;
      }
    },

    methods: {
      // 点击事件处理函数
      handleClick(evt) {
        this.$emit('click', evt);
      }
    }
  };
</script>

button-group

<template>
  <div class="el-button-group">
    <!-- 默认插槽,用于放置 button 子组件 -->
    <slot></slot>
  </div>
</template>
<script>
  export default {
    name: 'ElButtonGroup'
  };
</script>

ElButton 组件教学文档

组件概述

ElButton 是一个功能完善的按钮组件,支持多种类型、尺寸、状态和样式。它由两个子组件组成:

  • ElButton:按钮组件,提供丰富的配置选项
  • ElButtonGroup:按钮组容器,用于组合多个按钮

该组件支持加载状态、禁用状态、图标、圆角、圆形等多种样式,常用于表单提交、操作按钮、导航等场景。通过 inject 机制,按钮可以自动继承表单和表单项的配置,实现统一的尺寸和禁用状态。


一、ElButton 组件详解

1.1 模板部分(Template)

1.1.1 按钮元素
<button
  class="el-button"
  @click="handleClick"
  :disabled="buttonDisabled || loading"
  :autofocus="autofocus"
  :type="nativeType"
  :class="[
    type ? 'el-button--' + type : '',
    buttonSize ? 'el-button--' + buttonSize : '',
    {
      'is-disabled': buttonDisabled,
      'is-loading': loading,
      'is-plain': plain,
      'is-round': round,
      'is-circle': circle
    }
  ]"
>

详细解析

  1. 基础类名

    class="el-button"
    
    • 按钮的基础样式类名
    • 提供默认的按钮样式
  2. 点击事件

    @click="handleClick"
    
    • 绑定点击事件处理函数
    • 触发 click 自定义事件
  3. 禁用状态

    :disabled="buttonDisabled || loading"
    
    • 当按钮禁用或加载时,禁用按钮
    • buttonDisabled:通过计算属性获取的禁用状态
    • loading:加载状态
  4. 自动聚焦

    :autofocus="autofocus"
    
    • 页面加载时自动获取焦点
    • 布尔值,默认为 false
  5. 原生类型

    :type="nativeType"
    
    • 原生按钮的 type 属性
    • 默认为 'button'
    • 可选值:'button''submit''reset'
  6. 动态类名

    :class="[
      type ? 'el-button--' + type : '',
      buttonSize ? 'el-button--' + buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }
    ]"
    

类名详解

  • 类型类名el-button--type

    • el-button--primary:主要按钮(蓝色)
    • el-button--success:成功按钮(绿色)
    • el-button--warning:警告按钮(橙色)
    • el-button--danger:危险按钮(红色)
    • el-button--info:信息按钮(灰色)
    • el-button--text:文本按钮(无边框)
  • 尺寸类名el-button--size

    • el-button--medium:中等尺寸
    • el-button--small:小尺寸
    • el-button--mini:超小尺寸
  • 状态类名

    • is-disabled:禁用状态
    • is-loading:加载状态
    • is-plain:朴素按钮
    • is-round:圆角按钮
    • is-circle:圆形按钮
1.1.2 加载图标
<i class="el-icon-loading" v-if="loading"></i>

作用:显示加载状态的旋转图标。

条件

  • v-if="loading":只有当 loadingtrue 时显示

说明

  • 使用 Element UI 提供的加载图标
  • 自动旋转动画
  • 加载状态下不显示普通图标和文字
1.1.3 普通图标
<i :class="icon" v-if="icon && !loading"></i>

作用:显示按钮的图标。

条件

  • v-if="icon && !loading":有图标且不在加载状态时显示

说明

  • icon:图标类名
  • 加载状态下不显示图标
  • 图标显示在文字左侧
1.1.4 按钮文字
<span v-if="$slots.default"><slot></slot></span>

作用:显示按钮的文字内容。

条件

  • v-if="$slots.default":有默认插槽内容时显示

说明

  • 使用 <span> 包裹文字
  • 允许父组件传入任意内容
  • 可以是纯文本或其他元素

为什么使用 $slots.default

  • 检查是否有插槽内容
  • 避免渲染空的 <span> 元素
  • 优化 DOM 结构

1.2 脚本部分(Script)

1.2.1 组件定义
export default {
  name: 'ElButton',

作用:定义组件名称。

1.2.2 inject 注入
inject: {
  elForm: {
    default: ''
  },
  elFormItem: {
    default: ''
  }
}

作用:注入父组件提供的表单和表单项实例。

详细解析

  1. elForm

    • 注入表单组件实例
    • 用于获取表单的禁用状态
    • 默认值为空字符串
  2. elFormItem

    • 注入表单项组件实例
    • 用于获取表单项的尺寸配置
    • 默认值为空字符串

为什么需要 inject

  • 按钮可以放在表单或表单项中
  • 自动继承表单的配置
  • 实现统一的尺寸和禁用状态
  • 避免手动传递 props

数据流向

ElForm (provide: { elForm: this })
    ↓
ElFormItem (provide: { elFormItem: this })
    ↓
ElButton (inject: ['elForm', 'elFormItem'])
    ↓
获取表单配置

优势

  • 简化组件使用
  • 自动继承配置
  • 统一表单样式
  • 减少重复代码
1.2.3 Props 属性
type
type: {
  type: String,
  default: 'default'
}

作用:设置按钮的类型,决定按钮的颜色样式。

类型:字符串

默认值'default'

可选值

  • default:默认按钮(白色)
  • primary:主要按钮(蓝色)
  • success:成功按钮(绿色)
  • warning:警告按钮(橙色)
  • danger:危险按钮(红色)
  • info:信息按钮(灰色)
  • text:文本按钮(无边框)

使用示例

<!-- 默认按钮 -->
<el-button>默认按钮</el-button>

<!-- 主要按钮 -->
<el-button type="primary">主要按钮</el-button>

<!-- 成功按钮 -->
<el-button type="success">成功按钮</el-button>

<!-- 警告按钮 -->
<el-button type="warning">警告按钮</el-button>

<!-- 危险按钮 -->
<el-button type="danger">危险按钮</el-button>

<!-- 文本按钮 -->
<el-button type="text">文本按钮</el-button>

应用场景

  • default:普通操作
  • primary:主要操作(如提交、确认)
  • success:成功状态、正向操作
  • warning:警告提示、谨慎操作
  • danger:危险操作(如删除)
  • info:信息提示、次要操作
  • text:轻量级操作、链接样式
size
size: String

作用:设置按钮的尺寸。

类型:字符串

可选值

  • medium:中等尺寸
  • small:小尺寸
  • mini:超小尺寸

使用示例

<el-button size="medium">中等按钮</el-button>
<el-button size="small">小按钮</el-button>
<el-button size="mini">超小按钮</el-button>

优先级

  1. 按钮的 size 属性
  2. 表单项的 elFormItemSize
  3. 全局配置 this.$ELEMENT.size
icon
icon: {
  type: String,
  default: ''
}

作用:设置按钮的图标类名。

类型:字符串

默认值''(空字符串)

使用示例

<!-- 使用 Element UI 图标 -->
<el-button icon="el-icon-search">搜索</el-button>
<el-button icon="el-icon-edit">编辑</el-button>
<el-button icon="el-icon-delete">删除</el-button>

<!-- 只显示图标 -->
<el-button icon="el-icon-plus"></el-button>

说明

  • 图标显示在文字左侧
  • 加载状态下不显示图标
  • 可以只显示图标,不显示文字
nativeType
nativeType: {
  type: String,
  default: 'button'
}

作用:设置原生按钮的 type 属性。

类型:字符串

默认值'button'

可选值

  • button:普通按钮
  • submit:提交按钮(触发表单提交)
  • reset:重置按钮(重置表单)

使用示例

<!-- 普通按钮 -->
<el-button native-type="button">取消</el-button>

<!-- 提交按钮 -->
<el-button native-type="submit" type="primary">提交</el-button>

<!-- 重置按钮 -->
<el-button native-type="reset">重置</el-button>

注意事项

  • 在表单中使用时,submitreset 会触发表单的相应行为
  • 默认为 button,不会触发表单提交
  • 避免在表单外使用 submitreset
loading
loading: Boolean

作用:设置按钮的加载状态。

类型:布尔值

默认值false

使用示例

<template>
  <el-button :loading="loading" @click="handleSubmit">提交</el-button>
</template>

<script>
export default {
  data() {
    return {
      loading: false
    }
  },
  methods: {
    async handleSubmit() {
      this.loading = true;
      try {
        await this.submitData();
      } finally {
        this.loading = false;
      }
    }
  }
}
</script>

效果

  • 显示加载图标(旋转动画)
  • 按钮变为禁用状态
  • 不显示普通图标和文字
  • 防止重复点击

应用场景

  • 异步操作(如提交表单)
  • 数据加载
  • 避免重复提交
disabled
disabled: Boolean

作用:设置按钮的禁用状态。

类型:布尔值

默认值false

使用示例

<!-- 禁用按钮 -->
<el-button :disabled="true">禁用按钮</el-button>

<!-- 动态禁用 -->
<el-button :disabled="!canSubmit">提交</el-button>

效果

  • 按钮变为灰色
  • 无法点击
  • 鼠标样式变为禁用状态

优先级

  • 如果按钮明确设置了 disabled 属性,使用该值
  • 否则继承表单的 disabled 状态
plain
plain: Boolean

作用:设置按钮为朴素样式。

类型:布尔值

默认值false

使用示例

<!-- 朴素按钮 -->
<el-button plain>朴素按钮</el-button>
<el-button type="primary" plain>主要按钮</el-button>
<el-button type="success" plain>成功按钮</el-button>

效果

  • 背景色变为透明
  • 边框保留
  • 文字颜色变为对应类型的颜色

应用场景

  • 需要强调但不突出的操作
  • 次要操作
  • 与彩色按钮搭配使用
autofocus
autofocus: Boolean

作用:页面加载时自动获取焦点。

类型:布尔值

默认值false

使用示例

<el-button autofocus>自动聚焦</el-button>

效果

  • 页面加载后按钮自动获得焦点
  • 用户可以直接按 Enter 键触发点击

注意事项

  • 一个页面通常只有一个元素使用 autofocus
  • 移动端可能不适用
  • 可能影响用户体验(慎用)
round
round: Boolean

作用:设置按钮为圆角样式。

类型:布尔值

默认值false

使用示例

<!-- 圆角按钮 -->
<el-button round>圆角按钮</el-button>
<el-button type="primary" round>主要按钮</el-button>

效果

  • 按钮边框变为圆角
  • 更柔和的视觉效果

应用场景

  • 现代化设计风格
  • 需要柔和视觉效果的场景
circle
circle: Boolean

作用:设置按钮为圆形样式。

类型:布尔值

默认值false

使用示例

<!-- 圆形按钮 -->
<el-button circle icon="el-icon-search"></el-button>
<el-button circle icon="el-icon-edit"></el-button>
<el-button circle icon="el-icon-delete"></el-button>

效果

  • 按钮变为正圆形
  • 通常只显示图标,不显示文字
  • 尺寸由 size 属性决定

应用场景

  • 图标按钮
  • 工具栏按钮
  • 紧凑的布局
1.2.4 Computed 计算属性
_elFormItemSize
_elFormItemSize() {
  return (this.elFormItem || {}).elFormItemSize;
}

作用:获取表单项的尺寸配置。

说明

  • 从注入的 elFormItem 实例中获取 elFormItemSize
  • 如果 elFormItem 不存在,返回空对象
  • 安全的属性访问,避免报错

为什么使用可选链

(this.elFormItem || {}).elFormItemSize
  • 如果 elFormItemnullundefined,使用空对象
  • 访问空对象的属性返回 undefined
  • 避免访问 null.elFormItemSize 导致报错
buttonSize
buttonSize() {
  return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
}

作用:计算按钮的实际尺寸。

优先级

  1. this.size:按钮的 size 属性(最高优先级)
  2. this._elFormItemSize:表单项的尺寸配置
  3. (this.$ELEMENT || {}).size:全局配置(最低优先级)

说明

  • 使用逻辑或运算符 || 实现优先级
  • 从左到右依次判断,返回第一个真值
  • 实现尺寸的继承机制

示例

<!-- 按钮明确设置了 size,使用按钮的 size -->
<el-form-item size="small">
  <el-button size="medium">按钮</el-button>
</el-form-item>
<!-- 实际尺寸:medium -->

<!-- 按钮未设置 size,继承表单项的 size -->
<el-form-item size="small">
  <el-button>按钮</el-button>
</el-form-item>
<!-- 实际尺寸:small -->

<!-- 都未设置,使用全局配置 -->
<el-button>按钮</el-button>
<!-- 实际尺寸:全局配置的 size -->
buttonDisabled
buttonDisabled() {
  return this.$options.propsData.hasOwnProperty('disabled') ? this.disabled : (this.elForm || {}).disabled;
}

作用:计算按钮的实际禁用状态。

逻辑

  1. 检查按钮是否明确设置了 disabled 属性
    • 使用 this.$options.propsData.hasOwnProperty('disabled') 判断
    • 如果设置了,使用按钮的 disabled
  2. 如果未设置,继承表单的 disabled 状态
    • 使用 (this.elForm || {}).disabled 获取
    • 如果表单不存在,返回 undefined

为什么使用 hasOwnProperty

this.$options.propsData.hasOwnProperty('disabled')
  • 区分"未设置"和"设置为 false"
  • 如果未设置 disabledhasOwnProperty 返回 false
  • 如果设置了 disabled="false"hasOwnProperty 返回 true
  • 避免误判

在 Vue.js 中,this.$options 是一个实例属性,它包含了当前 Vue 组件实例的初始化选项对象(即你在 export default { ... } 中定义的那些选项,如 datapropsmethodscomputed 等)。


具体到代码:

buttonDisabled() {
  return this.$options.propsData.hasOwnProperty('disabled')
    ? this.disabled
    : (this.elForm || {}).disabled;
}

这里使用了 this.$options.propsData,它的作用是:

判断父组件是否显式传递了某个 prop(比如 disabled)给当前组件。


为什么不用 this.disabled !== undefined

因为 disabled 是一个 有默认值的 prop(虽然你的代码里没写默认值,但即使没有,默认也是 undefined),而 Vue 会自动把未传入的 prop 设为 undefined 或其默认值。所以你无法仅通过 this.disabled == null 来判断“父组件到底有没有传这个 prop”。

this.$options.propsData 是一个只包含父组件实际传入的 props 的对象(不包括未传递的 prop,哪怕它们有默认值)。

举个例子:
  • 如果父组件这样用:

    <ElButton />
    

    那么 this.$options.propsData{}没有 disabled 属性 → 说明父组件没传 disabled

  • 如果父组件这样用:

    <ElButton :disabled="false" />
    

    那么 this.$options.propsData{ disabled: false }disabled 属性,即使值是 false


所以这段逻辑的含义是:

// 如果父组件显式传了 disabled(无论 true 还是 false)
if (父组件传了 disabled) {
  // 就用父组件传的值(this.disabled)
  return this.disabled;
} else {
  // 否则,继承 el-form 表单的禁用状态
  return (this.elForm || {}).disabled;
}

这是一种受控优先 + 表单上下文继承的设计模式,常见于 Element UI 这类组件库:

  • 如果用户明确设置了 disabled,就尊重用户的设置;
  • 如果没设置,就看它是否在 <el-form disabled> 里面,如果是,就自动禁用。

补充:this.$options 还能用来做什么?

  • 获取组件名:this.$options.name
  • 获取原始的 data 函数:this.$options.data()
  • 动态处理混入(mixin)逻辑等

但在日常开发中,直接使用 this.$options 的场景较少,属于偏底层或高级用法。Element UI 这里是为了实现更智能的 prop 继承逻辑才用到它。


表达式含义
this.disabled当前 prop 的值(可能是默认值或父组件传的)
this.$options.props = { disabled: ... }❌ 错误!Vue 2 中不是这样
this.$options.propsData✅ Vue 2 中父组件实际传入的 props 对象(不含未传的 prop)
this.$options.propsData.hasOwnProperty('disabled')判断父组件是否显式传递了 disabled

⚠️ 注意:propsDataVue 2 特有 的属性,在 Vue 3 中已被移除。Vue 3 要实现类似逻辑需用其他方式(如 defineProps + 上下文判断)。 示例

<!-- 按钮明确设置了 disabled,使用按钮的 disabled -->
<el-form :disabled="false">
  <el-button :disabled="true">按钮</el-button>
</el-form>
<!-- 实际状态:disabled -->

<!-- 按钮未设置 disabled,继承表单的 disabled -->
<el-form :disabled="true">
  <el-button>按钮</el-button>
</el-form>
<!-- 实际状态:disabled -->

<!-- 按钮设置为 false,不继承表单的 disabled -->
<el-form :disabled="true">
  <el-button :disabled="false">按钮</el-button>
</el-form>
<!-- 实际状态:enabled -->
1.2.5 Methods 方法
handleClick
handleClick(evt) {
  this.$emit('click', evt);
}

作用:处理按钮点击事件。

说明

  • 接收原生事件对象 evt
  • 触发自定义 click 事件
  • 将事件对象传递给父组件

使用示例

<template>
  <el-button @click="handleClick">点击我</el-button>
</template>

<script>
export default {
  methods: {
    handleClick(evt) {
      console.log('按钮被点击', evt);
    }
  }
}
</script>

为什么需要包装

  • 统一的事件处理入口
  • 可以在触发前添加逻辑
  • 便于扩展和维护

二、ButtonGroup 组件详解

2.1 模板部分(Template)

2.1.1 容器元素
<div class="el-button-group">

作用:按钮组的根容器。

说明

  • 使用 el-button-group 类名
  • 提供按钮组的布局样式
  • 使内部的按钮组合在一起
2.1.2 默认插槽
<slot></slot>

作用:放置 el-button 子组件。

说明

  • 使用默认插槽,允许父组件传入任意数量的按钮
  • 按钮会自动组合在一起
  • 第一个和最后一个按钮会有特殊的圆角处理

2.2 脚本部分(Script)

2.2.1 组件定义
export default {
  name: 'ElButtonGroup'
};

作用:定义组件名称。

说明

  • 按钮组组件非常简单
  • 不需要 props、methods 等复杂逻辑
  • 主要通过 CSS 实现样式效果

三、组件使用示例

3.1 基础用法

<template>
  <el-button>默认按钮</el-button>
  <el-button type="primary">主要按钮</el-button>
  <el-button type="success">成功按钮</el-button>
  <el-button type="warning">警告按钮</el-button>
  <el-button type="danger">危险按钮</el-button>
</template>

说明:使用不同的类型显示不同颜色的按钮。

3.2 朴素按钮

<template>
  <el-button plain>朴素按钮</el-button>
  <el-button type="primary" plain>主要按钮</el-button>
  <el-button type="success" plain>成功按钮</el-button>
</template>

说明:使用 plain 属性显示朴素样式。

3.3 圆角按钮

<template>
  <el-button round>圆角按钮</el-button>
  <el-button type="primary" round>主要按钮</el-button>
  <el-button type="success" round>成功按钮</el-button>
</template>

说明:使用 round 属性显示圆角样式。

3.4 图标按钮

<template>
  <el-button icon="el-icon-search">搜索</el-button>
  <el-button icon="el-icon-edit">编辑</el-button>
  <el-button icon="el-icon-delete">删除</el-button>
  <el-button icon="el-icon-download">下载</el-button>
</template>

说明:使用 icon 属性添加图标。

3.5 加载状态

<template>
  <el-button :loading="loading" @click="handleClick">加载中</el-button>
</template>

<script>
export default {
  data() {
    return {
      loading: false
    }
  },
  methods: {
    handleClick() {
      this.loading = true;
      setTimeout(() => {
        this.loading = false;
      }, 2000);
    }
  }
}
</script>

说明:使用 loading 属性显示加载状态。

3.6 禁用状态

<template>
  <el-button disabled>禁用按钮</el-button>
  <el-button :disabled="!canSubmit">提交</el-button>
</template>

<script>
export default {
  data() {
    return {
      canSubmit: false
    }
  }
}
</script>

说明:使用 disabled 属性禁用按钮。

3.7 文本按钮

<template>
  <el-button type="text">文本按钮</el-button>
  <el-button type="text" disabled>禁用文本</el-button>
</template>

说明:使用 type="text" 显示无边框的文本按钮。

3.8 按钮尺寸

<template>
  <el-button>默认按钮</el-button>
  <el-button size="medium">中等按钮</el-button>
  <el-button size="small">小按钮</el-button>
  <el-button size="mini">超小按钮</el-button>
</template>

说明:使用 size 属性设置按钮尺寸。

3.9 图标按钮(圆形)

<template>
  <el-button circle icon="el-icon-search"></el-button>
  <el-button circle icon="el-icon-edit"></el-button>
  <el-button circle icon="el-icon-delete"></el-button>
</template>

说明:使用 circle 属性显示圆形图标按钮。

3.10 按钮组

<template>
  <el-button-group>
    <el-button type="primary" icon="el-icon-arrow-left">上一页</el-button>
    <el-button type="primary">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
  </el-button-group>

  <el-button-group>
    <el-button type="primary" icon="el-icon-edit"></el-button>
    <el-button type="primary" icon="el-icon-share"></el-button>
    <el-button type="primary" icon="el-icon-delete"></el-button>
  </el-button-group>
</template>

说明:使用 el-button-group 组合多个按钮。

3.11 配合表单使用

<template>
  <el-form :disabled="formDisabled">
    <el-form-item label="用户名">
      <el-input v-model="username"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" native-type="submit">提交</el-button>
      <el-button>取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
export default {
  data() {
    return {
      username: '',
      formDisabled: false
    }
  }
}
</script>

说明:按钮自动继承表单的禁用状态。

3.12 动态配置

<template>
  <el-button
    :type="buttonType"
    :size="buttonSize"
    :icon="buttonIcon"
    :loading="loading"
    :disabled="disabled"
    @click="handleClick">
    {{ buttonText }}
  </el-button>
</template>

<script>
export default {
  data() {
    return {
      buttonType: 'primary',
      buttonSize: 'medium',
      buttonIcon: 'el-icon-check',
      buttonText: '提交',
      loading: false,
      disabled: false
    }
  },
  methods: {
    async handleClick() {
      this.loading = true;
      try {
        await this.submitData();
      } finally {
        this.loading = false;
      }
    }
  }
}
</script>

说明:动态配置按钮的属性。


四、核心知识点总结

4.1 Vue 组件开发

  1. Props 定义

    • 类型检查:type: String
    • 默认值:default: 'default'
    • 布尔值简写:loading: Boolean
  2. 计算属性(Computed)

    • 封装复杂的计算逻辑
    • 实现属性的优先级
    • 响应式更新
  3. 事件处理

    • @click 绑定点击事件
    • $emit 触发自定义事件
    • 传递事件对象
  4. 动态类名

    • 数组语法:['class1', 'class2']
    • 对象语法:{ 'class-name': condition }
    • 条件类名:condition ? 'class' : ''

4.2 依赖注入(Provide/Inject)

  1. Provide

    • 父组件提供数据
    • 向下传递实例
  2. Inject

    • 子组件注入数据
    • 跨层级访问
  3. 应用场景

    • 表单组件
    • 按钮组件
    • 统一配置

4.3 属性优先级

  1. 尺寸优先级

    • 组件属性 > 表单项 > 全局配置
  2. 禁用优先级

    • 组件属性 > 表单配置
  3. 实现方式

    • 使用逻辑或运算符 ||
    • 使用 hasOwnProperty 判断

4.4 原生属性

  1. type 属性

    • button:普通按钮
    • submit:提交按钮
    • reset:重置按钮
  2. autofocus 属性

    • 自动获取焦点
    • 提升用户体验
  3. disabled 属性

    • 禁用按钮
    • 防止操作

4.5 插槽使用

  1. 默认插槽

    • 使用 <slot></slot>
    • 允许父组件传入内容
  2. 条件渲染

    • 使用 $slots.default 检查
    • 避免渲染空元素
  3. 内容分发

    • 灵活的内容展示
    • 支持任意内容

五、常见问题

5.1 为什么按钮不显示图标?

可能原因

  1. icon 属性值不正确
  2. 处于加载状态
  3. 图标类名不存在

解决方法

<!-- 正确:使用有效的图标类名 -->
<el-button icon="el-icon-search">搜索</el-button>

<!-- 错误:图标类名不正确 -->
<el-button icon="search">搜索</el-button>

<!-- 加载状态:图标不显示 -->
<el-button icon="el-icon-search" :loading="true">搜索</el-button>

5.2 如何实现按钮的禁用状态?

方法:使用 disabled 属性。

<!-- 静态禁用 -->
<el-button disabled>禁用按钮</el-button>

<!-- 动态禁用 -->
<el-button :disabled="!canSubmit">提交</el-button>

<!-- 继承表单的禁用状态 -->
<el-form :disabled="true">
  <el-button>按钮</el-button>
</el-form>

5.3 如何实现加载状态?

方法:使用 loading 属性。

<template>
  <el-button :loading="loading" @click="handleSubmit">提交</el-button>
</template>

<script>
export default {
  data() {
    return {
      loading: false
    }
  },
  methods: {
    async handleSubmit() {
      this.loading = true;
      try {
        await this.submitData();
      } finally {
        this.loading = false;
      }
    }
  }
}
</script>

5.4 如何自定义按钮样式?

方法:通过 CSS 覆盖默认样式。

<template>
  <el-button class="custom-button">自定义按钮</el-button>
</template>

<style>
.custom-button {
  background-color: #ff6b6b;
  border-color: #ff6b6b;
  color: #fff;
}

.custom-button:hover {
  background-color: #ff5252;
  border-color: #ff5252;
}
</style>

5.5 为什么按钮的尺寸不生效?

可能原因

  1. size 属性值不正确
  2. 被表单项或全局配置覆盖

解决方法

<!-- 明确设置 size -->
<el-button size="medium">按钮</el-button>

<!-- 检查表单项配置 -->
<el-form-item size="small">
  <el-button>按钮</el-button>
</el-form-item>
<!-- 实际尺寸:small -->

<!-- 检查全局配置 -->
Vue.prototype.$ELEMENT = { size: 'mini' };

5.6 如何实现按钮组?

方法:使用 el-button-group 组件。

<template>
  <el-button-group>
    <el-button type="primary">按钮1</el-button>
    <el-button type="primary">按钮2</el-button>
    <el-button type="primary">按钮3</el-button>
  </el-button-group>
</template>

六、扩展建议

6.1 功能扩展

  1. 长按事件:添加 @longpress 事件
  2. 双击事件:添加 @dblclick 事件
  3. 右键菜单:添加 @contextmenu 事件
  4. 快捷键:支持键盘快捷键触发
  5. 确认对话框:添加 confirm 属性

6.2 样式扩展

  1. 渐变背景:支持渐变色
  2. 阴影效果:添加阴影样式
  3. 自定义圆角:添加 border-radius 属性
  4. 动画效果:添加过渡动画
  5. 主题定制:支持多种主题

6.3 交互扩展

  1. 悬停提示:添加 Tooltip
  2. 水波纹效果:添加点击波纹动画
  3. 加载进度:显示加载进度条
  4. 触摸手势:支持移动端手势
  5. 拖拽功能:支持拖拽按钮

七、与其他组件的配合

7.1 配合 Form 组件

<template>
  <el-form>
    <el-form-item label="用户名">
      <el-input v-model="username"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" native-type="submit">提交</el-button>
      <el-button>取消</el-button>
    </el-form-item>
  </el-form>
</template>

7.2 配合 Input 组件

<template>
  <el-input v-model="search" placeholder="搜索">
    <el-button slot="append" icon="el-icon-search"></el-button>
  </el-input>
</template>

7.3 配合 Dialog 组件

<template>
  <el-dialog title="提示" :visible.sync="dialogVisible">
    <p>确定要删除吗?</p>
    <span slot="footer">
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="handleDelete">确定</el-button>
    </span>
  </el-dialog>
</template>

7.4 配合 Dropdown 组件

<template>
  <el-dropdown>
    <el-button type="primary">
      更多操作<i class="el-icon-arrow-down el-icon--right"></i>
    </el-button>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item>编辑</el-dropdown-item>
      <el-dropdown-item>删除</el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
</template>

7.5 配合 Icon 组件

<template>
  <el-button icon="el-icon-search">搜索</el-button>
  <el-button>
    <el-icon class="el-icon--left"><edit /></el-icon>
    编辑
  </el-button>
  <el-button>
    下载
    <el-icon class="el-icon--right"><download /></el-icon>
  </el-button>
</template>

八、总结

Button 是一个功能完善的按钮组件,由两个子组件组成。通过学习这个组件,我们掌握了:

  1. Vue 组件基础:Props、Computed、Methods、Slots
  2. 依赖注入:Provide/Inject 的使用
  3. 属性优先级:实现属性继承和覆盖
  4. 事件处理:原生事件和自定义事件
  5. 动态类名:灵活的样式绑定方式

这个组件的设计思路和实现方式展示了 Vue 组件开发的最佳实践,特别是:

  • 使用 inject 实现跨层级通信
  • 通过计算属性实现属性优先级
  • 使用 $slots 检查插槽内容
  • 注重用户体验(加载状态、禁用状态)