# ByToolBar 工具栏组件

提供一个灵活的工具栏,可以配置按钮、输入框、下拉框、单选框组等,并统一处理事件。

# 基础用法

通过 items 属性配置工具栏内容。

<template>
  <by-tool-bar :items="toolbarItems" @action="handleToolBarAction" />
</template>

<script>
import { ToolBarItemType } from '@weitutech/by-components'

export default {
  data() {
    return {
      toolbarItems: [
        {
          type: ToolBarItemType.Button,
          name: 'add',
          label: '新增',
          props: { type: 'primary', icon: 'el-icon-plus' }
        },
        {
          type: ToolBarItemType.Input,
          name: 'keyword',
          props: { placeholder: '请输入关键词' }
        },
        {
          type: ToolBarItemType.Select,
          name: 'status',
          props: {
            placeholder: '请选择状态',
            options: [
              { label: '全部', value: '' },
              { label: '已启用', value: 1 },
              { label: '已禁用', value: 0 }
            ]
          }
        },
        {
          type: ToolBarItemType.Button,
          name: 'delete',
          label: '删除',
          position: 'right', // 放置在右侧
          props: { type: 'danger' }
        }
      ]
    }
  },
  methods: {
    handleToolBarAction({ type, item, payload }) {
      console.log('统一事件接收:', { type, item, payload })
      // input和change事件,统一更新value
      if (type === 'input' || type === 'change') {
        this.$message.info(`触发了【${item.name}】事件, 选中值:${payload}`)
        const targetItem = this.toolBarItems.find(it => it.name === item.name)
        if (targetItem) {
          this.$set(targetItem.props, 'value', payload)
        }
      }
      // click事件
      if (type === 'click') {
        this.$message.info(`点击了【${item.label}】按钮`)
        // ...可以根据 item.name 来处理不同的点击事件
      }
    }
  }
}
</script>

# Select 组件特殊配置

# onlyShowPlaceholder

新增的配置属性,用于控制select组件是否只显示placeholder而不显示选中的值。

{
  type: 'select',
  name: 'status',
  label: '状态',
  props: {
    placeholder: '请选择状态',
    onlyShowPlaceholder: true, // 设置为true时,只显示placeholder,不显示选中值
    options: [
      { label: '启用', value: 1 },
      { label: '禁用', value: 0 }
    ]
  }
}

onlyShowPlaceholder 设置为 true 时:

  • select组件只显示placeholder内容
  • 不会显示选中的值
  • 下拉操作仍然会触发选中回调
  • 不影响原有的选择功能

# API

# Props

属性 说明 类型 默认值
items 工具栏配置数组,详细配置见下方的 Item 配置 Array []

# Item 配置对象

items 数组中的每个对象可以包含以下属性:

属性 说明 类型 是否必须
type 项目类型,可选值:'text', 'button', 'radio-group', 'select', 'input' (推荐通过 ToolBarItemType 枚举获取,如 ToolBarItemType.Button) String
name 项目的唯一标识,用于事件回调中区分项目。当 typeselect 且使用 loadOptions 时,此项必填。 String
label 显示的文本 String
position 项目位置,'right' 会将项目渲染到右侧,默认为左侧 String
hidden 是否隐藏该项目 Boolean
disabled 是否禁用该项目 Boolean
props 传递给内部组件的属性。例如给 el-button 传递 type, icon 等。对于 select, 可通过 options 传递选项,或通过 loadOptions 异步加载。对于 radio-group,通过 radios 传递选项。 Object
slot 自定义渲染的插槽名称。如果定义了此项,组件将渲染一个具名插槽,而不是预设的组件 String

# Select 组件的 props 特殊属性

属性 说明 类型 默认值
onlyShowPlaceholder 是否只显示placeholder而不显示选中的值。设置为 true 时,select组件将始终显示placeholder内容,不会显示选中的值,但仍会触发选中回调。 Boolean false
options 下拉选项数组,每个选项包含 labelvalue 属性 Array []
loadOptions 异步加载选项的函数,返回 Promise,resolve 选项数组 Function -

# Events

事件名 说明 回调参数
action 当工具栏中的组件触发 click, input, change 等事件时触发。 { type, item, payload }
type: 事件类型
item: 项目配置对象
payload: 事件的载荷

# Slots

插槽名 说明
(动态插槽) 通过在 items 配置中指定 slot 属性来创建具名插槽,用于自定义渲染任意内容。

# 高级用法

# 1. Select 组件只显示 Placeholder

使用 onlyShowPlaceholder: true 可以让 select 组件只显示 placeholder,不显示选中的值。

<template>
  <by-tool-bar :items="toolbarItems" @action="handleAction" />
</template>

<script>
export default {
  data() {
    return {
      toolbarItems: [
        {
          type: 'select',
          name: 'filter',
          label: '筛选条件',
          props: {
            placeholder: '请选择筛选条件',
            onlyShowPlaceholder: true, // 只显示placeholder,不显示选中值
            options: [
              { label: '全部', value: 'all' },
              { label: '已启用', value: 'enabled' },
              { label: '已禁用', value: 'disabled' }
            ]
          }
        }
      ]
    }
  },
  methods: {
    handleAction({ type, item, payload }) {
      if (type === 'change' && item.name === 'filter') {
        console.log('筛选条件:', payload)
        // 处理筛选逻辑,但select组件不会显示选中的值
      }
    }
  }
}
</script>

# 2. 异步加载下拉框选项

通过 props.loadOptions 函数可以实现异步加载 select 的选项。

<template>
  <by-tool-bar :items="toolbarItems" @action="handleAction" />
</template>

<script>
export default {
  data() {
    return {
      toolbarItems: [
        {
          type: 'select',
          name: 'user-select', // 使用loadOptions时,name是必须的
          props: {
            placeholder: '搜索用户',
            loadOptions: this.loadUsers
          }
        }
      ]
    }
  },
  methods: {
    loadUsers() {
      // 模拟API请求
      return new Promise(resolve => {
        setTimeout(() => {
          resolve([
            { label: '张三', value: 'zhangsan' },
            { label: '李四', value: 'lisi' }
          ])
        }, 1000)
      })
    },
    handleAction({ item, payload }) {
      if (item.name === 'user-select') {
        console.log('Selected user:', payload)
      }
    }
  }
}
</script>

# 3. 使用自定义插槽

如果你想在工具栏中嵌入非标准组件或者完全自定义某一项的渲染,可以使用 slot

<template>
  <by-tool-bar :items="toolbarItems">
    <template #custom-upload>
      <el-upload action="#" :show-file-list="false">
        <el-button size="small" type="primary">点击上传</el-button>
      </el-upload>
    </template>
  </by-tool-bar>
</template>

<script>
export default {
  data() {
    return {
      toolbarItems: [
        {
          type: 'button',
          label: '常规按钮'
        },
        {
          slot: 'custom-upload' // 对应 template 中的 #custom-upload
        }
      ]
    }
  }
}
</script>

# 完整示例

<template>
  <by-tool-bar :items="toolbarItems" @action="handleAction" />
</template>

<script>
import { ToolBarItemType } from '@weitutech/by-components'

export default {
  data() {
    return {
      toolbarItems: [
        {
          type: ToolBarItemType.Button,
          name: 'add',
          label: '新增',
          props: {
            type: 'primary',
            icon: 'el-icon-plus'
          }
        },
        {
          type: ToolBarItemType.Input,
          name: 'keyword',
          props: {
            placeholder: '请输入关键词'
          }
        },
        {
          type: ToolBarItemType.Select,
          name: 'status',
          label: '状态',
          props: {
            placeholder: '请选择状态',
            onlyShowPlaceholder: true, // 只显示placeholder
            options: [
              { label: '启用', value: 1 },
              { label: '禁用', value: 0 }
            ]
          }
        },
        {
          type: ToolBarItemType.Select,
          name: 'category',
          label: '分类',
          position: 'right',
          props: {
            placeholder: '请选择分类',
            onlyShowPlaceholder: false, // 默认行为,显示选中值
            options: [
              { label: '分类1', value: 'cat1' },
              { label: '分类2', value: 'cat2' }
            ]
          }
        },
        {
          type: ToolBarItemType.Button,
          name: 'export',
          label: '导出',
          position: 'right',
          props: {
            type: 'success'
          }
        }
      ]
    }
  },
  methods: {
    handleAction({ type, item, payload }) {
      if (type === 'change') {
        if (item.name === 'status') {
          console.log('状态选择:', payload)
          // 处理状态选择逻辑
        } else if (item.name === 'category') {
          console.log('分类选择:', payload)
          // 处理分类选择逻辑
        }
      } else if (type === 'click') {
        this.$message.info(`点击了: ${item.label}`)
      } else if (type === 'input') {
        this.$message.info(`输入了: ${payload}`)
      }
    }
  }
}
</script>
最后更新时间: 7/18/2025, 11:37:24 AM