Skip to content

Button 按钮组件

按钮用于开始一个即时操作。

学习目标

  • 掌握 Element Plus Button 组件的各种类型和属性
  • 了解按钮的基本设计原则和使用场景
  • 学习按钮的状态管理和交互效果
  • 掌握按钮组合和布局技巧

基础用法

使用 typeplainroundcircle 来定义按钮的样式。

基础按钮
使用 type 属性来定义按钮的类型。
vue
<template>
  <div class="button-demo">
    <el-button>默认按钮</el-button>
    <el-button type="primary">主要按钮</el-button>
    <el-button type="success">成功按钮</el-button>
    <el-button type="info">信息按钮</el-button>
    <el-button type="warning">警告按钮</el-button>
    <el-button type="danger">危险按钮</el-button>
  </div>
</template>

<style scoped>
.button-demo {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
</style>

朴素按钮

朴素按钮同样设置了 type 属性,它们的表现与常规按钮不同,边框和文字颜色都是彩色的。

朴素按钮
vue
<template>
  <div class="plain-button-demo">
    <el-button plain>朴素按钮</el-button>
    <el-button type="primary" plain>主要按钮</el-button>
    <el-button type="success" plain>成功按钮</el-button>
    <el-button type="info" plain>信息按钮</el-button>
    <el-button type="warning" plain>警告按钮</el-button>
    <el-button type="danger" plain>危险按钮</el-button>
  </div>
</template>

圆角按钮

通过 round 属性来确定按钮是否为圆角按钮。

圆角按钮
vue
<template>
  <div class="round-button-demo">
    <el-button round>圆角按钮</el-button>
    <el-button type="primary" round>主要按钮</el-button>
    <el-button type="success" round>成功按钮</el-button>
    <el-button type="info" round>信息按钮</el-button>
    <el-button type="warning" round>警告按钮</el-button>
    <el-button type="danger" round>危险按钮</el-button>
  </div>
</template>

图标按钮

使用图标为按钮添加更多的含义。你也可以单独使用图标不添加文字来节省显示区域占用。

图标按钮


vue
<template>
  <div class="icon-button-demo">
    <!-- 带图标的按钮 -->
    <el-button type="primary" :icon="Edit">编辑</el-button>
    <el-button type="primary" :icon="Share">分享</el-button>
    <el-button type="primary" :icon="Delete">删除</el-button>
    <el-button type="primary" :icon="Search">搜索</el-button>
    
    <!-- 只有图标的按钮 -->
    <el-button type="primary" :icon="Edit" circle />
    <el-button type="success" :icon="Check" circle />
    <el-button type="info" :icon="Message" circle />
    <el-button type="warning" :icon="Star" circle />
    <el-button type="danger" :icon="Delete" circle />
  </div>
</template>

<script setup>
import {
  Edit,
  Share,
  Delete,
  Search,
  Check,
  Message,
  Star
} from '@element-plus/icons-vue'
</script>

<style scoped>
.button-group-demo {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
</style>

按钮尺寸

Button 组件提供除了默认值以外的三种尺寸,可以在不同场景下选择合适的按钮尺寸。

按钮尺寸
vue
<template>
  <div class="size-button-demo">
    <el-row>
      <el-button size="large">大型按钮</el-button>
      <el-button>默认按钮</el-button>
      <el-button size="small">小型按钮</el-button>
    </el-row>
    <el-row>
      <el-button size="large" round>大型按钮</el-button>
      <el-button round>默认按钮</el-button>
      <el-button size="small" round>小型按钮</el-button>
    </el-row>
    <el-row>
      <el-button size="large" :icon="Search" circle />
      <el-button :icon="Search" circle />
      <el-button size="small" :icon="Search" circle />
    </el-row>
  </div>
</template>

<script setup>
import { Search } from '@element-plus/icons-vue'
</script>

<style scoped>
.size-button-demo .el-row {
  margin-bottom: 20px;
}
.size-button-demo .el-row:last-child {
  margin-bottom: 0;
}
</style>

禁用状态

你可以使用 disabled 属性来定义按钮是否被禁用。

禁用状态
vue
<template>
  <div class="disabled-button-demo">
    <el-row>
      <el-button disabled>默认按钮</el-button>
      <el-button type="primary" disabled>主要按钮</el-button>
      <el-button type="success" disabled>成功按钮</el-button>
      <el-button type="info" disabled>信息按钮</el-button>
      <el-button type="warning" disabled>警告按钮</el-button>
      <el-button type="danger" disabled>危险按钮</el-button>
    </el-row>
    
    <el-row>
      <el-button plain disabled>朴素按钮</el-button>
      <el-button type="primary" plain disabled>主要按钮</el-button>
      <el-button type="success" plain disabled>成功按钮</el-button>
      <el-button type="info" plain disabled>信息按钮</el-button>
      <el-button type="warning" plain disabled>警告按钮</el-button>
      <el-button type="danger" plain disabled>危险按钮</el-button>
    </el-row>
  </div>
</template>

链接按钮

链接按钮用于创建类似链接的按钮样式。

链接按钮
vue
<template>
  <div class="link-button-demo">
    <el-button type="primary" link>基础链接按钮</el-button>
    <el-button type="primary" link disabled>禁用链接按钮</el-button>
  </div>
</template>

文字按钮

没有边框和背景色的按钮。

文字按钮
vue
<template>
  <div class="text-button-demo">
    <el-button type="primary" text>文字按钮</el-button>
    <el-button type="primary" text bg>背景文字按钮</el-button>
    <el-button type="primary" text disabled>禁用文字按钮</el-button>
  </div>
</template>

加载状态

点击按钮来加载数据,并向用户反馈加载状态。

加载状态
vue
<template>
  <div class="loading-button-demo">
    <el-button type="primary" loading>加载中</el-button>
    <el-button type="primary" :loading="loading" @click="handleClick">
      点击加载
    </el-button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const loading = ref(false)

const handleClick = () => {
  loading.value = true
  setTimeout(() => {
    loading.value = false
  }, 2000)
}
</script>

自定义颜色

您可以自定义按钮的颜色,我们将自动计算按钮处于 hover 和 active 状态时的颜色。

自定义颜色
vue
<template>
  <div class="custom-color-demo">
    <el-button color="#95d475">#95d475</el-button>
    <el-button color="#95d475" plain>#95d475</el-button>
    <el-button color="#95d475" round plain>圆角按钮</el-button>
    <el-button color="#95d475" round>圆角按钮</el-button>
  </div>
</template>

自定义元素标签

您可以自定义元素标签,例如按钮、div、路由链接、nuxt链接。

自定义元素标签
div
span
vue
<template>
  <div class="custom-tag-demo">
    <el-button tag="div" role="button" tabindex="0">div</el-button>
    <el-button tag="span" role="button" tabindex="0">span</el-button>
  </div>
</template>

自动插入空格

当按钮内容为两个中文字符时,可以自动在字符之间插入空格。

自动插入空格
vue
<template>
  <div class="auto-space-demo">
    <el-button auto-insert-space>按钮</el-button>
    <el-button :auto-insert-space="false">按钮</el-button>
  </div>
</template>

按钮组

以按钮组的方式出现,常用于多项类似操作。

按钮组


vue
<template>
  <div class="button-group-demo">
    <el-button-group>
      <el-button type="primary" :icon="ArrowLeft">上一页</el-button>
      <el-button type="primary" :icon="ArrowRight">下一页</el-button>
    </el-button-group>
    <br><br>
    <el-button-group>
      <el-button type="primary" :icon="Edit" />
      <el-button type="primary" :icon="Share" />
      <el-button type="primary" :icon="Delete" />
    </el-button-group>
  </div>
</template>

<script setup>
import {
  ArrowLeft,
  ArrowRight,
  Edit,
  Share,
  Delete
} from '@element-plus/icons-vue'
</script>

<style scoped>
.button-group-demo {
  display: flex;
  gap: 20px;
}
</style>

综合示例

按钮工具栏

按钮工具栏

状态指示器

状态指示器
运行中
警告
错误
停止

Button API

Button Attributes

属性名说明类型可选值默认值
size尺寸stringlarge / default / small
type类型stringprimary / success / warning / danger / info
plain是否朴素按钮booleanfalse
text ^(2.2.0)是否文字按钮booleanfalse
bg ^(2.2.0)是否显示文字按钮背景颜色booleanfalse
link ^(2.2.1)是否链接按钮booleanfalse
round是否圆角按钮booleanfalse
circle是否圆形按钮booleanfalse
loading是否加载中状态booleanfalse
loading-icon自定义加载中状态图标组件string / ComponentLoading
disabled是否禁用状态booleanfalse
icon图标组件string / Component
autofocus是否默认聚焦booleanfalse
native-type原生 type 属性stringbutton / submit / resetbutton
auto-insert-space自动在两个中文字符之间插入空格booleanfalse
color自定义按钮颜色, 并自动计算 hover 和 active 触发后的颜色string
darkdark 模式, 意味着自动设置 color 为 dark 模式的颜色booleanfalse
tag ^(2.3.4)自定义元素标签string / Componentbutton

Button Events

事件名说明回调参数
click点击时触发(evt: MouseEvent)

Button Slots

插槽名说明
default自定义默认内容
loading自定义加载中组件
icon自定义图标组件

Button Exposes

方法名说明类型
ref按钮 html 元素Ref<HTMLButtonElement>
size按钮尺寸ComputedRef<string>
type按钮类型ComputedRef<string>
disabled按钮是否禁用ComputedRef<boolean>
shouldAddSpace是否在两个字符之间添加空格ComputedRef<boolean>

Button Exposes 使用示例

通过模板引用可以访问按钮组件暴露的属性和方法:

vue
<template>
  <div class="button-exposes-demo">
    <h3>Button Exposes 示例</h3>
    
    <!-- 按钮组件 -->
    <div class="button-section">
      <el-button 
        ref="primaryButtonRef"
        type="primary" 
        :size="buttonSize"
        :disabled="isDisabled"
        @click="handleButtonClick"
      >
        主要按钮
      </el-button>
      
      <el-button 
        ref="successButtonRef"
        type="success" 
        size="large"
        auto-insert-space
      >
        成功按钮
      </el-button>
    </div>
    
    <!-- 控制面板 -->
    <div class="control-panel">
      <h4>控制面板</h4>
      <div class="control-item">
        <label>按钮尺寸:</label>
        <el-select v-model="buttonSize" style="width: 120px">
          <el-option label="Large" value="large" />
          <el-option label="Default" value="default" />
          <el-option label="Small" value="small" />
        </el-select>
      </div>
      
      <div class="control-item">
        <el-checkbox v-model="isDisabled">禁用按钮</el-checkbox>
      </div>
      
      <div class="control-item">
        <el-button @click="getButtonInfo">获取按钮信息</el-button>
        <el-button @click="focusButton">聚焦按钮</el-button>
      </div>
    </div>
    
    <!-- 信息显示 -->
    <div class="info-panel">
      <h4>按钮信息</h4>
      <div class="info-item">
        <strong>主要按钮尺寸:</strong> {{ primaryButtonInfo.size }}
      </div>
      <div class="info-item">
        <strong>主要按钮类型:</strong> {{ primaryButtonInfo.type }}
      </div>
      <div class="info-item">
        <strong>主要按钮禁用状态:</strong> {{ primaryButtonInfo.disabled }}
      </div>
      <div class="info-item">
        <strong>成功按钮是否添加空格:</strong> {{ successButtonInfo.shouldAddSpace }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, nextTick } from 'vue'

// 模板引用
const primaryButtonRef = ref()
const successButtonRef = ref()

// 响应式数据
const buttonSize = ref('default')
const isDisabled = ref(false)

// 按钮信息
const primaryButtonInfo = reactive({
  size: '',
  type: '',
  disabled: false
})

const successButtonInfo = reactive({
  shouldAddSpace: false
})

// 获取按钮信息
const getButtonInfo = () => {
  if (primaryButtonRef.value) {
    primaryButtonInfo.size = primaryButtonRef.value.size
    primaryButtonInfo.type = primaryButtonRef.value.type
    primaryButtonInfo.disabled = primaryButtonRef.value.disabled
  }
  
  if (successButtonRef.value) {
    successButtonInfo.shouldAddSpace = successButtonRef.value.shouldAddSpace
  }
}

// 聚焦按钮
const focusButton = async () => {
  await nextTick()
  if (primaryButtonRef.value?.ref) {
    primaryButtonRef.value.ref.focus()
  }
}

// 按钮点击事件
const handleButtonClick = () => {
  console.log('按钮被点击了')
  getButtonInfo() // 点击时自动更新信息
}

// 初始化信息
nextTick(() => {
  getButtonInfo()
})
</script>

<style scoped>
.button-exposes-demo {
  padding: 20px;
}

.button-section {
  margin-bottom: 20px;
  padding: 15px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  background-color: var(--el-bg-color);
}

.button-section .el-button {
  margin-right: 10px;
}

.control-panel {
  margin-bottom: 20px;
  padding: 15px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  background-color: var(--el-fill-color-lighter);
}

.control-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.control-item label {
  width: 80px;
  margin-right: 10px;
  font-weight: 500;
}

.control-item .el-button {
  margin-right: 10px;
}

.info-panel {
  padding: 15px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  background-color: var(--el-fill-color-extra-light);
}

.info-item {
  margin-bottom: 8px;
  color: var(--el-text-color-primary);
}

.info-item strong {
  color: var(--el-color-primary);
}
</style>

高级用法:动态按钮管理

vue
<template>
  <div class="advanced-button-demo">
    <h3>动态按钮管理</h3>
    
    <!-- 动态按钮列表 -->
    <div class="button-list">
      <el-button
        v-for="(button, index) in buttons"
        :key="button.id"
        :ref="el => setButtonRef(el, index)"
        :type="button.type"
        :size="button.size"
        :disabled="button.disabled"
        :loading="button.loading"
        @click="handleDynamicButtonClick(button, index)"
      >
        {{ button.text }}
      </el-button>
    </div>
    
    <!-- 操作控制 -->
    <div class="operations">
      <el-button @click="addButton">添加按钮</el-button>
      <el-button @click="removeLastButton">移除最后一个</el-button>
      <el-button @click="toggleAllButtons">切换全部状态</el-button>
      <el-button @click="getAllButtonsInfo">获取所有按钮信息</el-button>
    </div>
    
    <!-- 按钮信息展示 -->
    <div class="buttons-info" v-if="buttonsInfo.length > 0">
      <h4>按钮信息列表</h4>
      <div 
        v-for="(info, index) in buttonsInfo" 
        :key="index"
        class="button-info-item"
      >
        <strong>按钮 {{ index + 1 }}:</strong>
        类型: {{ info.type }}, 
        尺寸: {{ info.size }}, 
        禁用: {{ info.disabled }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, nextTick } from 'vue'

// 按钮数据
const buttons = ref([
  { id: 1, text: '按钮 1', type: 'primary', size: 'default', disabled: false, loading: false },
  { id: 2, text: '按钮 2', type: 'success', size: 'default', disabled: false, loading: false },
  { id: 3, text: '按钮 3', type: 'warning', size: 'default', disabled: false, loading: false }
])

// 按钮引用数组
const buttonRefs = ref([])

// 按钮信息
const buttonsInfo = ref([])

// 设置按钮引用
const setButtonRef = (el, index) => {
  if (el) {
    buttonRefs.value[index] = el
  }
}

// 添加按钮
const addButton = () => {
  const newId = Math.max(...buttons.value.map(b => b.id)) + 1
  const types = ['primary', 'success', 'warning', 'danger', 'info']
  const randomType = types[Math.floor(Math.random() * types.length)]
  
  buttons.value.push({
    id: newId,
    text: `按钮 ${newId}`,
    type: randomType,
    size: 'default',
    disabled: false,
    loading: false
  })
}

// 移除最后一个按钮
const removeLastButton = () => {
  if (buttons.value.length > 1) {
    buttons.value.pop()
    buttonRefs.value.pop()
  }
}

// 切换所有按钮状态
const toggleAllButtons = () => {
  buttons.value.forEach(button => {
    button.disabled = !button.disabled
  })
}

// 动态按钮点击事件
const handleDynamicButtonClick = async (button, index) => {
  // 设置加载状态
  button.loading = true
  
  // 模拟异步操作
  setTimeout(() => {
    button.loading = false
    console.log(`点击了按钮: ${button.text}`)
  }, 1000)
  
  // 获取当前按钮信息
  await nextTick()
  if (buttonRefs.value[index]) {
    const buttonRef = buttonRefs.value[index]
    console.log('按钮信息:', {
      type: buttonRef.type,
      size: buttonRef.size,
      disabled: buttonRef.disabled
    })
  }
}

// 获取所有按钮信息
const getAllButtonsInfo = async () => {
  await nextTick()
  buttonsInfo.value = buttonRefs.value.map(buttonRef => {
    if (buttonRef) {
      return {
        type: buttonRef.type,
        size: buttonRef.size,
        disabled: buttonRef.disabled
      }
    }
    return null
  }).filter(Boolean)
}
</script>

<style scoped>
.advanced-button-demo {
  padding: 20px;
}

.button-list {
  margin-bottom: 20px;
  padding: 15px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  background-color: var(--el-bg-color);
}

.button-list .el-button {
  margin: 0 10px 10px 0;
}

.operations {
  margin-bottom: 20px;
  padding: 15px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  background-color: var(--el-fill-color-lighter);
}

.operations .el-button {
  margin-right: 10px;
}

.buttons-info {
  padding: 15px;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  background-color: var(--el-fill-color-extra-light);
}

.button-info-item {
  margin-bottom: 8px;
  padding: 8px;
  background-color: var(--el-bg-color);
  border-radius: var(--el-border-radius-small);
  color: var(--el-text-color-primary);
}

.button-info-item strong {
  color: var(--el-color-primary);
}
</style>

ButtonGroup Attributes

属性名说明类型可选值默认值
size用于控制该按钮组内按钮的大小stringlarge / default / small
type用于控制该按钮组内按钮的类型stringprimary / success / warning / danger / info

ButtonGroup Slots

插槽名说明子标签
default自定义按钮组内容Button

实践练习

练习 1:创建按钮组合

创建一个包含不同类型、尺寸和状态的按钮组合:

  1. 实现一个工具栏,包含主要操作按钮
  2. 添加按钮的加载状态和禁用状态
  3. 使用按钮组创建分页控件
  4. 实现响应式按钮布局

练习 2:按钮交互效果

练习按钮的交互和状态管理:

  1. 实现按钮的点击反馈效果
  2. 创建动态加载状态的按钮
  3. 实现按钮的条件禁用
  4. 添加按钮的确认对话框

练习 3:自定义按钮样式

基于 Element Plus 按钮创建自定义样式:

  1. 定义自己的按钮主题色彩
  2. 创建特殊形状的按钮
  3. 实现按钮的动画效果
  4. 适配移动端的按钮样式

学习资源

作业

  1. 完成所有实践练习
  2. 创建一个完整的按钮展示页面,包含所有类型和状态
  3. 实现一个带有确认功能的删除按钮组件
  4. 研究其他 UI 框架的按钮设计,对比分析优缺点

下一步学习计划

接下来我们将学习 表单组件,包括:

  • Input 输入框组件
  • Select 选择器组件
  • Checkbox 复选框组件
  • Radio 单选框组件

Element Plus Study Guide