npm i @blueking/ediatable
<template>
<Ediatable :thead-list="theadList">
<!-- thead-list 等价写法 -->
<!-- <template #default>
<RenderTableHeadColumn
required
:min-width="120"
:width="450"
>
<span>目标集群</span>
</RenderTableHeadColumn>
<RenderTableHeadColumn
fixed="right"
:required="false"
:width="100"
>
操作
</RenderTableHeadColumn>
</template> -->
<template #data>
<RenderRow
v-for="(item, index) in tableData"
:key="item.rowKey"
ref="rowRefs"
:data="item"
@add="payload => handleAppend(index, payload)"
@remove="handleRemove(index)"
/>
</template>
</Ediatable>
<Button
theme="primary"
@click="handleSubmit"
>
提交
</Button>
</template>
<script setup lang="tsx">
import { ref } from 'vue';
import { Ediatable } from '@blueking/ediatable';
import('@blueking/ediatable/vue3/vue3.css');
const rowRefs = ref();
const tableData = ref([createRowData()]);
const theadList: IHead[] = [
{
minWidth: 120,
title: '目标集群',
width: 450,
renderAppend: () => <span style='color: red;margin-left:5px;font-size:10px'>必填</span>,
},
{
fixed: 'right',
required: false,
title: '操作',
width: 100,
},
];
// 追加一个集群
const handleAppend = (index: number, appendList: Array<IDataRow>) => {
tableData.value.splice(index + 1, 0, ...appendList);
};
// 删除一个集群
const handleRemove = (index: number) => {
tableData.value.splice(index, 1);
};
const handleSubmit = async () => {
const params = await Promise.all(rowRefs.value.map((item: { getValue: () => any }) => item.getValue()));
console.log('params>>>', params);
};
</script>
推荐自定义表格的行组件,将每一列的组件纳入其中统一管理,便于后期的增删及交互处理。
<template>
<tr>
<td>
<RenderTargetCluster
ref="clusterRef"
:data="data.cluster"
@input-finish="handleInputFinish"
/>
</td>
<td>
<TextPlainColumn
:data="data.nodeType"
:is-loading="data.isLoading"
placeholder="输入集群后自动生成"
/>
</td>
<td>
<RenderTargetNumber
ref="numRef"
:data="data.targetNum"
:disabled="!data.cluster"
:is-loading="data.isLoading"
/>
</td>
<td>
<RenderKeyRelated
required
ref="includeKeyRef"
/>
</td>
<td>
<RenderTargetDateTime
ref="timeRef"
:data="data.targetDateTime"
:is-loading="data.isLoading"
/>
</td>
<td>
<RenderSwitchMode
ref="switchModeRef"
:data="data.switchMode"
:is-loading="data.isLoading"
/>
</td>
<OperationColumn
:removeable="removeable"
show-copy
@add="handleAppend"
@remove="handleRemove"
/>
</tr>
</template>
<script lang="ts">
import _ from 'lodash';
import { OperationColumn, TextPlainColumn } from '@blueking/ediatable';
// 下面这几个都是自定义列组件
import RenderTargetCluster from './cluster-name.vue';
import RenderSwitchMode from './switch-mode.vue';
import RenderTargetNumber from './target-number.vue';
import RenderKeyRelated from './regex-keys.vue';
import RenderTargetDateTime from './target-datetime.vue';
export interface IDataRow {
rowKey?: string;
isLoading?: boolean;
cluster: string;
nodeType?: string;
switchMode?: string;
targetNum?: number;
targetDateTime?: string;
}
const random = () => `${_.random(0, 999999)}_${Date.now()}_${_.random(0, 999999)}`;
// 创建表格行数据
export const createRowData = (data?: IDataRow): IDataRow => ({
rowKey: random(),
isLoading: false,
cluster: data?.cluster ?? '',
nodeType: data?.nodeType ?? '',
switchMode: data?.switchMode ?? '',
});
</script>
<script setup lang="ts">
import { ref } from 'vue';
interface Props {
data: IDataRow;
removeable: boolean;
}
interface Emits {
(e: 'add', params: Array<IDataRow>): void;
(e: 'remove'): void;
(e: 'clusterInputFinish', value: string): void;
}
interface Exposes {
getValue: () => Promise<{
cluster: string;
target_num: number;
include_keys: string[];
target_time: string;
mode: string;
}>;
}
const props = defineProps<Props>();
const emits = defineEmits<Emits>();
const clusterRef = ref<InstanceType<typeof RenderTargetCluster>>();
const numRef = ref<InstanceType<typeof RenderTargetNumber>>();
const includeKeyRef = ref<InstanceType<typeof RenderKeyRelated>>();
const timeRef = ref<InstanceType<typeof RenderTargetDateTime>>();
const switchModeRef = ref<InstanceType<typeof RenderSwitchMode>>();
const handleInputFinish = (value: string) => {
emits('clusterInputFinish', value);
};
const handleAppend = () => {
emits('add', [createRowData()]);
};
const handleRemove = () => {
if (props.removeable) {
return;
}
emits('remove');
};
defineExpose<Exposes>({
async getValue() {
return await Promise.all([
clusterRef.value!.getValue(),
numRef.value!.getValue(),
includeKeyRef.value!.getValue(),
timeRef.value!.getValue(),
switchModeRef.value!.getValue(),
]).then(data => {
const [cluster, target_num, include_keys, target_time, mode] = data;
return {
cluster,
target_num,
include_keys,
target_time,
mode,
};
});
},
});
</script>
RenderTargetCluster.vue参考代码
其他自定义列组件也可参考进行封装
<template>
<InputColumn
ref="editRef"
v-model="localValue"
placeholder=”请输入或选择集群"
:rules="rules"
@submit="value => handleInputFinish(value)"
/>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
import { InputColumn } from '@blueking/ediatable';
interface Props {
data?: string;
}
interface Emits {
(e: 'input-finish', value: string): void;
}
interface Exposes {
getValue: () => Promise<string>;
}
const props = withDefaults(defineProps<Props>(), {
data: '',
inputed: () => [],
});
const emits = defineEmits<Emits>();
const localValue = ref(props.data);
const editRef = ref();
const rules = [
{
validator: (value: string) => Boolean(value),
message: '目标集群不能为空',
},
];
watch(
() => props.data,
data => {
localValue.value = data;
},
{
immediate: true,
},
);
const handleInputFinish = (value: string) => {
emits('input-finish', value);
};
defineExpose<Exposes>({
getValue() {
return editRef.value.getValue().then(() => localValue.value);
},
});
</script>
属性名 |
描述 |
属性类型 |
默认值 |
theadList |
表头列表配置 |
Array<IHead> |
[] |
属性名 |
描述 |
属性类型 |
默认值 |
fixed |
表头列是否固定 |
right 或 left 或 undefined |
undefined |
maxWidth |
表头列最大宽度 |
number 或 undefined |
undefined |
minWidth |
表头列最小宽度 |
number 或 undefined |
undefined |
memo |
列名hover时的提示 |
string 或 undefined |
undefined |
required |
是否必填标志 |
boolean |
true |
title |
表头列名 |
string 或 undefined |
undefined |
width |
表头列宽度 |
number 或 undefined |
undefined |
renderAppend |
表头列名之后追加的元素 |
() => JSX.Element 或 undefined |
undefined |
属性名 |
描述 |
属性类型 |
默认值 |
validator |
校验函数 |
(value: any) => boolean 或 Promise<boolean> |
无 |
message |
校验出错提示 |
string 或 (() => string) |
无 |
<script lang="ts">
import { InputColumn } from '@blueking/ediatable';
</script>
属性名 |
描述 |
属性类型 |
默认值 |
rules |
校验规则配置 |
IRule[] |
undefined |
其他配置同 bkui-vue3
的 Input
组件
事件名 |
参数 |
参数类型 |
描述 |
submit |
value |
string 或 number |
输入完成事件 |
error |
value |
boolean |
校验报错事件 |
clear |
|
|
清空事件 | |
事件名 |
描述 |
getValue |
校验并获取最新值 |
focus |
组件聚焦 |
<script lang="ts">
import { DateTimePickerColumn } from '@blueking/ediatable';
</script>
属性名 |
描述 |
属性类型 |
默认值 |
rules |
校验规则配置 |
IRule[] |
undefined |
其他配置同 bkui-vue3
的 TimerPicker
组件
事件名 |
参数 |
参数类型 |
描述 |
change |
value |
[string, string] 或 string |
选择完成事件 |
error |
value |
boolean |
校验报错事件 |
<script lang="ts">
import { SelectColumn } from '@blueking/ediatable';
</script>
属性名 |
描述 |
属性类型 |
默认值 |
rules |
校验规则配置 |
IRule[] |
undefined |
其他配置同 bkui-vue3
的 Select
组件
事件名 |
参数 |
参数类型 |
描述 |
change |
value |
string 或 number |
选择完成事件 |
error |
value |
boolean |
校验报错事件 |
<script lang="ts">
import { TagInputColumn } from '@blueking/ediatable';
</script>
属性名 |
描述 |
属性类型 |
默认值 |
rules |
校验规则配置 |
IRule[] |
undefined |
其他配置同 bkui-vue3
的 TagInput
组件
事件名 |
参数 |
参数类型 |
描述 |
change |
value |
string[] |
输入完成事件 |
error |
value |
boolean |
校验报错事件 |
名称 |
描述 |
tip |
聚焦后的 popover 提示 |
<script lang="ts">
import { TagInputColumn } from '@blueking/ediatable';
</script>
属性名 |
描述 |
属性类型 |
默认值 |
data |
文本内容 |
string 或 number 或 undefined |
undefined |
isLoading |
是否加载中 |
boolean 或 undefined |
undefined |
placeholder |
空白提示 |
string 或 undefined |
undefined |
rules |
校验规则配置 |
IRule[] 或 undefined |
undefined |
<script lang="ts">
import { OperationColumn } from '@blueking/ediatable';
</script>
属性名 |
描述 |
属性类型 |
默认值 |
removeable |
删除图标是否可用 |
boolean |
true |
showCopy |
是否展示行克隆图标 |
boolean |
false |
showAdd |
是否展示添加图标 |
boolean |
true |
showRemove |
是否展示删除图标 |
boolean |
true |
事件名 |
参数 |
参数类型 |
描述 |
add |
|
|
添加事件 |
copy |
|
|
克隆事件 |
remove |
|
|
删除事件 |
<script lang="ts">
import { FixedColumn } from '@blueking/ediatable';
</script>
属性名 |
描述 |
属性类型 |
默认值 |
fixed |
是否固定列 |
left 或 right |
right |
<script lang="ts">
import { HeadColumn } from '@blueking/ediatable';
</script>
同 IHead
配置
名称 |
描述 |
default |
表头 |
append |
表头追加元素 |