按钮组件
介绍
Buttons是基于naive-ui的按钮组件封装的组件,主要区别是使用配置渲染组件
功能如下:
- 只需传入一个配置项
config,即可生成按次序排列的按钮; - 可以设置按钮的显隐、权限、点击事件等;
- 点击事件增加了配置与事件分离的配置方式。
属性说明:
Buttons有config、btnType、param、spaceProps四个自定义属性,同时可传入naive-ui的button的所有属性
- config:按钮配置,必传(
BtnItem[]),BtnItem里有以下七个自定义属性,同时可配置naive-ui的button的所有属性:- label:按钮文字(
string) - icon:图标(
Component) - vif:是否显示(
boolean | ((param?: any) => boolean)) - disabled:是否禁用(
boolean | ((param?: any) => boolean)) - auth:权限(
string[]) - eventName:点击事件名称(
string) - btnType:按钮类型(
'tableBtn' | 'other')
- label:按钮文字(
- btnType:按钮类型(
'tableBtn' | 'other') - param:vif函数和点击事件的参数
- spaceProps:
n-space组件的属性
基础使用
项目里该组件已全局注册,可直接使用。
<template>
<Buttons :config="config" :param="row" btnType="tableBtn" @edit="edit" @delete="del"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '编辑',
type: 'primary',
auth: ['BTN00460'],
eventName: 'edit'
},
{
label: '删除',
type: 'error',
auth: ['BTN00459'],
eventName: 'delete'
}
]
function edit(row: any) {
console.log('编辑')
}
function del(row: any) {
console.log('删除')
}
</script>图标icon
config.icon,设置按钮图标,直接传入图标组件即可。
<template>
<Buttons :config="config"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
import { CashOutline, AddCircle, CloseCircle } from '@vicons/ionicons5'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
icon: CashOutline,
onClick: () => console.log('详情')
},
{
label: '编辑',
type: 'primary',
icon: AddCircle,
onClick: () => console.log('编辑')
},
{
label: '删除',
type: 'error',
icon: CloseCircle,
onClick: () => console.log('删除')
}
]
</script>点击事件
方式一:onClick
通过@click绑定,配置格式为onClick: Function
<template>
<Buttons :config="config"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
onClick: () => console.log('详情')
},
{
label: '编辑',
type: 'primary',
onClick: () => console.log('编辑')
},
{
label: '删除',
type: 'error',
onClick: () => console.log('删除')
}
]
</script>方式二:eventName
自定义事件:将事件通过v-on传递给组件,在配置里用eventName指定自定义事件的名称。
组件内部将
eventName指定的事件绑定到对应按钮的点击事件上。
该方式目的:使配置和事件逻辑分开,方便代码归类整理。
<template>
<Buttons
:config="config"
@details="details"
@edit="edit"
@delete="handleDelete"
></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
eventName: 'details'
},
{
label: '编辑',
type: 'primary',
eventName: 'edit'
},
{
label: '删除',
type: 'error',
eventName: 'delete'
}
]
function details() {
console.log('详情')
}
function edit() {
console.log('编辑')
}
function handleDelete() {
console.log('删除')
}
</script>eventName命名:
该名称为@符后面的名称,格式不做限制,支持camelCase、kebab-case、PascalCase
例如:自定义事件为@editData="handleEdit",此时eventName可以为以下三种:
eventName: 'edit-data'eventName: 'editData'eventName: 'EditData'
事件参数param
点击事件的默认参数是$event。
如果给Buttons组件传递了param属性:
- 该
param就为点击事件的第一参数,$event为第二参数;(注意:两种点击事件都有效) vif和disabled为Function时,该param为参数。
不传param | 传递param | |
|---|---|---|
| 点击事件 | onClick: (e: Event) => {} | onClick: (param: any, e: Event) => {} |
| vif | vif: () => {} | vif: (param: any) => {} |
| disabled | disabled: () => {} | disabled: (param: any) => {} |
完整例子:
<template>
<Buttons
:config="config"
:param="{ name: '企安' }"
@edit-data="edit"
></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
vif: (param: any) => param.name === '企安',
onClick: (param: any) => {
console.log(param) // {name: '企安'}
}
},
{
label: '编辑',
type: 'primary',
disabled: (param: any) => param.name === '企安',
eventName: 'edit-data'
}
]
function edit(param: any) {
console.log(param) // {name: '企安'}
}
</script>该
param在表格操作列里使用,效果尤为显著。让按钮配置可以不用写在render函数里,vif 和点击事件里也仍然能获取到需要的参数。
按钮显隐vif
config.vif:(boolean | (param?:object)=>boolean),按钮是否显示,不传表示显示。
若组件上传递了
param,vif为函数时,param可作为函数的参数。
<template>
<Buttons :config="config" :param="{ name: '企安' }"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
vif: false,
onClick: () => console.log('详情')
},
{
label: '编辑',
type: 'primary',
vif: (param: any) => param.name === '企安',
onClick: () => console.log('编辑')
},
]
</script>按钮禁用disabled
config.disabled:(boolean | (param?:object)=>boolean),按钮是否禁用,不传表示启用。
若组件上传递了
param,disabled为函数时,param可作为函数的参数。
<template>
<Buttons :config="config" :param="{ name: '企安' }"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
disabled: true,
onClick: () => console.log('详情')
},
{
label: '编辑',
type: 'primary',
disabled: (param: any) => param.name === '企安',
onClick: () => console.log('编辑')
},
]
</script>按钮权限auth
config.auth:(string[]),设置按钮权限。不传,表示显示按钮。
<template>
<Buttons
:config="config"
@details="details"
@editData="edit"
@delete="handleDelete"
></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
auth: ['BTN00459'],
eventName: 'details'
},
{
label: '编辑',
type: 'primary',
auth: ['BTN00460'],
eventName: 'EditData'
},
{
label: '删除',
type: 'error',
eventName: 'delete'
}
]
function details() {
console.log('详情')
}
function edit() {
console.log('编辑')
}
function handleDelete() {
console.log('删除')
}
</script>支持n-button的props
单独配置每个按钮
config配置支持naive-ui的n-button所有的props,例如:
<template>
<Buttons :config="config"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
size: 'small'
},
{
label: '编辑',
type: 'primary',
circle: true,
disabled: true
},
{
label: '删除',
type: 'error',
dashed: true
}
]
</script>统一配置所有按钮
组件上也支持naive-ui的n-button所有的props。
如果所有按钮的配置是一样的,就可以统一在组件上配置,例如:
<template>
<Buttons
:config="config"
type="primary"
size="small"
dashed
></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情'
},
{
label: '编辑'
},
{
label: '删除',
type: 'error'
}
]
</script>TIP
- Buttons组件会把除
config、btnType、param、spaceProps、@xxx以外的 props,都合并到 config 每一个按钮配置上; - 若有同名属性,以
config里的为主。
上述例子,等同于以下配置:
<template>
<Buttons :config="config"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
size: 'small',
dashed: true
},
{
label: '编辑',
type: 'primary',
size: 'small',
dashed: true
},
{
label: '删除',
type: 'error',
size: 'small',
dashed: true
}
]
</script>按钮类型btnType
针对表格写了一组按钮属性,用于统一表格操作列的按钮,传入btnType="tableBtn"可设置为表格类型
btnType默认是
other,即为空
<template>
<Buttons :config="config" btnType="tableBtn"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
onClick: () => console.log('详情')
},
{
label: '编辑',
type: 'primary',
onClick: () => console.log('编辑')
},
{
label: '删除',
type: 'error',
onClick: () => console.log('删除')
}
]
</script>可给单个按钮设置类型(优先级更高)
<template>
<Buttons :config="config"></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{
label: '详情',
type: 'primary',
btnType: 'tableBtn',
onClick: () => console.log('详情')
},
{
label: '编辑',
type: 'primary',
btnType: 'tableBtn',
onClick: () => console.log('编辑')
},
{
label: '删除',
type: 'error',
onClick: () => console.log('删除')
}
]
</script>后续根据项目UI可在组件内添加其他的风格
按钮间距
组件内部使用n-space包裹所有按钮,可通过属性spaceProps设置n-space的属性。
<template>
<Buttons
type="primary"
:config="config"
:spaceProps="{ vertical: true, size: 30, class: 'bg-red-200' }"
></Buttons>
</template>
<script setup lang="tsx">
import type { BtnItem } from 'comp/Buttons'
const config: BtnItem[] = [
{ label: '详情' },
{ label: '编辑' },
{ label: '删除', type: 'error' }
]
</script>INFO
组件内部:
<template>
<n-space v-bind="spaceProps">
<n-button v-for="item in btnList" ...> ... </n-button>
</n-space>
</template>在naive-ui-table中使用
<template>
<n-card>
<NaiveUiTable :columns="columns" :requestApi="getTableList">
<!-- 表格header按钮 -->
<template #tableHeader>
<Buttons :config="headerBtn" @add="add"></Buttons>
</template>
<!-- 表格操作列 -->
<template #operation="row">
<Buttons
:config="operationBtn"
btnType="tableBtn"
:param="row"
@details="details"
@edit="edit"
@delete="handleDelete"
></Buttons>
</template>
</NaiveUiTable>
</n-card>
</template>
<script setup lang="tsx">
import { CashOutline } from '@vicons/ionicons5'
import { NaiveUiTable, type TableColumns } from 'naive-ui-table'
import 'naive-ui-table/dist/style.css'
import type { BtnItem } from 'comp/Buttons'
import { list } from 'api/user'
type Item = Recordable
const headerBtn: BtnItem[] = [
{
label: '新增',
type: 'primary',
icon: CashOutline,
auth: ['BTN00458'],
eventName: 'add'
}
]
const operationBtn: BtnItem[] = [
{
label: '详情',
type: 'primary',
icon: CashOutline,
vif: (row) => row.age > 20,
auth: ['BTN00459'],
eventName: 'details'
},
{
label: '编辑',
type: 'primary',
disabled: (row) => row.age < 10,
auth: ['BTN00460'],
eventName: 'edit'
},
{
label: '删除',
type: 'error',
auth: ['BTN00461'],
eventName: 'delete'
}
]
const columns: TableColumns<Item> = [
{ title: '姓名', key: 'name' },
{ title: '年龄', key: 'age' },
{ title: '地址', key: 'address' },
{ title: '操作', key: 'operation', fixed: 'right', width: 330 }
]
function add() {
console.log('新增')
}
function details(data: Item) {
console.log('详情', data)
}
function edit(data: Item) {
console.log('编辑', data)
}
function handleDelete(data: Item) {
console.log('删除', data)
}
async function getTableList(params: object) {
console.log('params: ', params)
return await list(params)
}
</script>Props
| 属性名称 | 类型 | 是否必须 | 描述 |
| config | BtnItem[] | 是 | 按钮配置 |
| btnType | 'tableBtn' | 'other' | 否 | 按钮类型 (不传默认other,表示为空) |
| param | any | 否 | vif函数和点击事件参数 |
| spaceProps | SpaceProps | 否 | n-space组件的属性 |
| @xxx | Function | 否 | 按钮点击事件,需与 eventName 配合使用 |
| ……支持传入 naive-ui 的 button 的所有属性 | |||
| config配置项 | 类型 | 是否必须 | 描述 |
| label | string | 否 | 按钮内容 |
| icon | Component | 否 | 图标组件 |
| vif | boolean | (param?:any)=>boolean | 否 | 按钮是否回显(不传表示回显) |
| disabled | boolean | (param?:any)=>boolean | 否 | 按钮是否禁用(不传表示启用) |
| auth | string[] | 否 | 按钮权限(不传表示回显) |
| btnType | 'tableBtn' | 'other' | 否 | 按钮类型 (不传默认other,表示为空) |
| eventName | string | 否 | 按钮点击事件名称,与@xxx保持一致 |
| ……支持传入 naive-ui 的 button 的所有属性 | |||