@ebiz/designer-components 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/designer-components.css +1 -0
- package/dist/index.mjs +118521 -77394
- package/package.json +2 -2
- package/src/components/Button.vue +1 -1
- package/src/components/DataContainer.vue +2 -1
- package/src/components/EbizAutoForm.vue +597 -0
- package/src/components/EbizDescriptions.vue +341 -0
- package/src/components/EbizDescriptionsItem.vue +48 -0
- package/src/components/EbizPopconfirm.vue +48 -0
- package/src/components/EbizSelect.vue +95 -95
- package/src/components/EbizTable.vue +5 -1
- package/src/components/EbizTreeMergeTable.vue +1393 -0
- package/src/components/EbizTreeSelector.vue +64 -68
- package/src/components/Form.vue +2 -1
- package/src/components/TdesignDescriptions.vue +75 -0
- package/src/components/TdesignDescriptionsItem.vue +51 -0
- package/src/components/TdesignForm.vue +6 -1
- package/src/components/examples/PopconfirmExample.vue +150 -0
- package/src/index.js +20 -1
- package/src/router/index.js +24 -19
- package/src/views/EbizAutoFormDemo.vue +130 -0
- package/src/views/Home.vue +11 -4
- package/src/views/PopconfirmDemo.vue +81 -0
- package/src/views/TdesignDescriptions.vue +102 -0
- package/src/views/TreeMergeTableDemo.vue +240 -0
- package/dist/lowcode-components.css +0 -1
@@ -0,0 +1,130 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="demo-container">
|
3
|
+
<h1>EbizAutoForm 自动表单组件示例</h1>
|
4
|
+
|
5
|
+
<div class="demo-section">
|
6
|
+
<h2>基本使用</h2>
|
7
|
+
<ebiz-auto-form
|
8
|
+
:api-config="apiConfig"
|
9
|
+
:initial-data="initialData"
|
10
|
+
@submit="handleSubmit"
|
11
|
+
@reset="handleReset"
|
12
|
+
/>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div class="demo-section">
|
16
|
+
<h2>表单提交结果</h2>
|
17
|
+
<pre v-if="submittedData">{{ JSON.stringify(submittedData, null, 2) }}</pre>
|
18
|
+
<p v-else>尚未提交表单</p>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div class="demo-section">
|
22
|
+
<h2>自定义配置</h2>
|
23
|
+
<ebiz-auto-form
|
24
|
+
:api-config="customApiConfig"
|
25
|
+
:initial-data="customInitialData"
|
26
|
+
label-width="150px"
|
27
|
+
label-align="left"
|
28
|
+
:show-reset-button="false"
|
29
|
+
submit-button-text="保存信息"
|
30
|
+
@submit="handleCustomSubmit"
|
31
|
+
/>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</template>
|
35
|
+
|
36
|
+
<script>
|
37
|
+
export default {
|
38
|
+
name: "EbizAutoFormDemo"
|
39
|
+
}
|
40
|
+
</script>
|
41
|
+
|
42
|
+
<script setup>
|
43
|
+
import { ref } from 'vue';
|
44
|
+
import { EbizAutoForm } from '../index.js';
|
45
|
+
|
46
|
+
// 基本配置示例
|
47
|
+
const apiConfig = ref({
|
48
|
+
apiId: 'getUserForm',
|
49
|
+
apiType: 'DETAILS_DATA',
|
50
|
+
key: 'user'
|
51
|
+
});
|
52
|
+
|
53
|
+
// 初始数据
|
54
|
+
const initialData = ref({
|
55
|
+
name: '张三',
|
56
|
+
email: 'zhangsan@example.com',
|
57
|
+
gender: 'male'
|
58
|
+
});
|
59
|
+
|
60
|
+
// 自定义配置示例
|
61
|
+
const customApiConfig = ref({
|
62
|
+
apiId: 'getProductForm',
|
63
|
+
apiType: 'DETAILS_DATA',
|
64
|
+
key: 'product'
|
65
|
+
});
|
66
|
+
|
67
|
+
// 自定义初始数据
|
68
|
+
const customInitialData = ref({
|
69
|
+
productName: '智能手机',
|
70
|
+
price: 2999,
|
71
|
+
status: true
|
72
|
+
});
|
73
|
+
|
74
|
+
// 提交结果
|
75
|
+
const submittedData = ref(null);
|
76
|
+
|
77
|
+
// 处理提交
|
78
|
+
const handleSubmit = (data) => {
|
79
|
+
console.log('表单提交数据:', data);
|
80
|
+
submittedData.value = data;
|
81
|
+
alert('表单提交成功!');
|
82
|
+
};
|
83
|
+
|
84
|
+
// 处理重置
|
85
|
+
const handleReset = () => {
|
86
|
+
console.log('表单已重置');
|
87
|
+
submittedData.value = null;
|
88
|
+
};
|
89
|
+
|
90
|
+
// 处理自定义表单提交
|
91
|
+
const handleCustomSubmit = (data) => {
|
92
|
+
console.log('自定义表单提交数据:', data);
|
93
|
+
alert('自定义表单提交成功!');
|
94
|
+
};
|
95
|
+
</script>
|
96
|
+
|
97
|
+
<style lang="less" scoped>
|
98
|
+
.demo-container {
|
99
|
+
max-width: 1000px;
|
100
|
+
margin: 0 auto;
|
101
|
+
padding: 20px;
|
102
|
+
|
103
|
+
h1 {
|
104
|
+
margin-bottom: 24px;
|
105
|
+
font-size: 24px;
|
106
|
+
color: #0052d9;
|
107
|
+
}
|
108
|
+
|
109
|
+
.demo-section {
|
110
|
+
margin-bottom: 40px;
|
111
|
+
padding: 20px;
|
112
|
+
border: 1px solid #e7e7e7;
|
113
|
+
border-radius: 6px;
|
114
|
+
|
115
|
+
h2 {
|
116
|
+
margin-bottom: 16px;
|
117
|
+
font-size: 18px;
|
118
|
+
color: #333;
|
119
|
+
}
|
120
|
+
|
121
|
+
pre {
|
122
|
+
padding: 12px;
|
123
|
+
background-color: #f5f7fa;
|
124
|
+
border-radius: 4px;
|
125
|
+
font-family: monospace;
|
126
|
+
overflow: auto;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
</style>
|
package/src/views/Home.vue
CHANGED
@@ -17,6 +17,11 @@
|
|
17
17
|
<div class="component-title">树形选择器</div>
|
18
18
|
<div class="component-desc">基于树组件的选择器,支持搜索和多选</div>
|
19
19
|
</router-link>
|
20
|
+
|
21
|
+
<router-link to="/tree-merge-table-demo" class="component-item">
|
22
|
+
<div class="component-title">树形合并表格</div>
|
23
|
+
<div class="component-desc">支持树形展示和单元格合并的表格组件</div>
|
24
|
+
</router-link>
|
20
25
|
</div>
|
21
26
|
</div>
|
22
27
|
</template>
|
@@ -66,12 +71,14 @@ export default {
|
|
66
71
|
{ path: '/tdesign-dialog', title: 'TDesign对话框组件示例' },
|
67
72
|
{ path: '/page-header', title: 'Ebiz页面头部组件示例' },
|
68
73
|
{ path: '/table-demo', title: 'Ebiz表格组件示例' },
|
69
|
-
{ path: '/
|
74
|
+
{ path: '/detail-block', title: 'Ebiz详情块组件示例' },
|
70
75
|
{ path: '/table-column', title: 'Ebiz表格列组件示例' },
|
71
76
|
{ path: '/table-sort', title: 'Ebiz表格排序组件示例' },
|
72
|
-
{ path: '/
|
73
|
-
{ path: '/
|
74
|
-
{ path: '/
|
77
|
+
{ path: '/time-picker', title: 'Ebiz时间选择器组件示例' },
|
78
|
+
{ path: '/tdesign-descriptions', title: 'Ebiz描述列表组件示例' },
|
79
|
+
{ path: '/popconfirm', title: 'Ebiz气泡确认框组件示例' },
|
80
|
+
{ path: '/tree-merge-table-demo', title: '树形合并表格组件示例' },
|
81
|
+
{ path: '/auto-form-demo', title: 'Ebiz自动表单组件示例' }
|
75
82
|
]
|
76
83
|
|
77
84
|
return {
|
@@ -0,0 +1,81 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="popconfirm-demo">
|
3
|
+
<h1>气泡确认框示例</h1>
|
4
|
+
|
5
|
+
<h2>1. 基础用法</h2>
|
6
|
+
<div class="example-item">
|
7
|
+
<ebiz-popconfirm content="确定要删除这条数据吗?">
|
8
|
+
<ebiz-tdesign-button>删除</ebiz-tdesign-button>
|
9
|
+
</ebiz-popconfirm>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<h2>2. 事件处理</h2>
|
13
|
+
<div class="example-item">
|
14
|
+
<p>操作结果: <span>{{ operationResult }}</span></p>
|
15
|
+
<ebiz-popconfirm
|
16
|
+
content="确定要继续吗?"
|
17
|
+
@confirm="handleConfirm"
|
18
|
+
@cancel="handleCancel"
|
19
|
+
>
|
20
|
+
<ebiz-tdesign-button>点击触发事件</ebiz-tdesign-button>
|
21
|
+
</ebiz-popconfirm>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</template>
|
25
|
+
|
26
|
+
<script setup>
|
27
|
+
import { ref } from 'vue';
|
28
|
+
import { EbizPopconfirm, EbizTdesignButton, EbizMessage } from '../index';
|
29
|
+
|
30
|
+
const operationResult = ref('');
|
31
|
+
|
32
|
+
// 确认事件处理
|
33
|
+
const handleConfirm = () => {
|
34
|
+
operationResult.value = '您点击了确认按钮';
|
35
|
+
EbizMessage.success('操作已确认');
|
36
|
+
};
|
37
|
+
|
38
|
+
// 取消事件处理
|
39
|
+
const handleCancel = () => {
|
40
|
+
operationResult.value = '您点击了取消按钮';
|
41
|
+
EbizMessage.info('操作已取消');
|
42
|
+
};
|
43
|
+
</script>
|
44
|
+
|
45
|
+
<style lang="less" scoped>
|
46
|
+
.popconfirm-demo {
|
47
|
+
padding: 20px;
|
48
|
+
|
49
|
+
h1 {
|
50
|
+
margin-bottom: 30px;
|
51
|
+
font-weight: bold;
|
52
|
+
color: #0052d9;
|
53
|
+
}
|
54
|
+
|
55
|
+
h2 {
|
56
|
+
margin-top: 30px;
|
57
|
+
margin-bottom: 16px;
|
58
|
+
font-weight: bold;
|
59
|
+
font-size: 18px;
|
60
|
+
border-left: 4px solid #0052d9;
|
61
|
+
padding-left: 12px;
|
62
|
+
}
|
63
|
+
|
64
|
+
.example-item {
|
65
|
+
margin-bottom: 24px;
|
66
|
+
padding: 20px;
|
67
|
+
border: 1px solid #eee;
|
68
|
+
border-radius: 6px;
|
69
|
+
background-color: #fafafa;
|
70
|
+
}
|
71
|
+
|
72
|
+
p {
|
73
|
+
margin-bottom: 10px;
|
74
|
+
|
75
|
+
span {
|
76
|
+
color: #0052d9;
|
77
|
+
font-weight: bold;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
</style>
|
@@ -0,0 +1,102 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="container">
|
3
|
+
<h2>描述列表组件演示</h2>
|
4
|
+
|
5
|
+
<div class="demo-section">
|
6
|
+
<h3>基础用法</h3>
|
7
|
+
<EbizDescriptions title="配送信息" :column="2">
|
8
|
+
<EbizDescriptionsItem label="姓名">TDesign</EbizDescriptionsItem>
|
9
|
+
<EbizDescriptionsItem label="电话号码">139****0609</EbizDescriptionsItem>
|
10
|
+
<EbizDescriptionsItem label="地区">腾讯总部</EbizDescriptionsItem>
|
11
|
+
<EbizDescriptionsItem label="地址">深圳市南山区深南大道10000号</EbizDescriptionsItem>
|
12
|
+
</EbizDescriptions>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div class="demo-section">
|
16
|
+
<h3>带边框</h3>
|
17
|
+
<EbizDescriptions title="配送信息" :column="2" border>
|
18
|
+
<EbizDescriptionsItem label="姓名">TDesign</EbizDescriptionsItem>
|
19
|
+
<EbizDescriptionsItem label="电话号码">139****0609</EbizDescriptionsItem>
|
20
|
+
<EbizDescriptionsItem label="地区">腾讯总部</EbizDescriptionsItem>
|
21
|
+
<EbizDescriptionsItem label="地址">深圳市南山区深南大道10000号</EbizDescriptionsItem>
|
22
|
+
</EbizDescriptions>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<div class="demo-section">
|
26
|
+
<h3>带冒号</h3>
|
27
|
+
<EbizDescriptions title="配送信息" :column="2" colon>
|
28
|
+
<EbizDescriptionsItem label="姓名">TDesign</EbizDescriptionsItem>
|
29
|
+
<EbizDescriptionsItem label="电话号码">139****0609</EbizDescriptionsItem>
|
30
|
+
<EbizDescriptionsItem label="地区">腾讯总部</EbizDescriptionsItem>
|
31
|
+
<EbizDescriptionsItem label="地址">深圳市南山区深南大道10000号</EbizDescriptionsItem>
|
32
|
+
</EbizDescriptions>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="demo-section">
|
36
|
+
<h3>垂直布局</h3>
|
37
|
+
<EbizDescriptions title="配送信息" :column="2" layout="vertical" border>
|
38
|
+
<EbizDescriptionsItem label="姓名">TDesign</EbizDescriptionsItem>
|
39
|
+
<EbizDescriptionsItem label="电话号码">139****0609</EbizDescriptionsItem>
|
40
|
+
<EbizDescriptionsItem label="地区">腾讯总部</EbizDescriptionsItem>
|
41
|
+
<EbizDescriptionsItem label="地址">深圳市南山区深南大道10000号</EbizDescriptionsItem>
|
42
|
+
</EbizDescriptions>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<div class="demo-section">
|
46
|
+
<h3>自定义列数</h3>
|
47
|
+
<EbizDescriptions title="配送信息" :column="3" border>
|
48
|
+
<EbizDescriptionsItem label="姓名">TDesign</EbizDescriptionsItem>
|
49
|
+
<EbizDescriptionsItem label="电话号码">139****0609</EbizDescriptionsItem>
|
50
|
+
<EbizDescriptionsItem label="地区">腾讯总部</EbizDescriptionsItem>
|
51
|
+
<EbizDescriptionsItem label="地址" :span="2">深圳市南山区深南大道10000号</EbizDescriptionsItem>
|
52
|
+
</EbizDescriptions>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
<div class="demo-section">
|
56
|
+
<h3>自定义样式</h3>
|
57
|
+
<EbizDescriptions title="配送信息" :column="2" border table-border-color="#E7E7E7">
|
58
|
+
<EbizDescriptionsItem label="姓名" label-class-name="custom-label">TDesign</EbizDescriptionsItem>
|
59
|
+
<EbizDescriptionsItem label="电话号码">139****0609</EbizDescriptionsItem>
|
60
|
+
<EbizDescriptionsItem label="地区">腾讯总部</EbizDescriptionsItem>
|
61
|
+
<EbizDescriptionsItem label="地址" content-class-name="custom-content">
|
62
|
+
<span style="color: #0052d9">深圳市南山区深南大道10000号</span>
|
63
|
+
</EbizDescriptionsItem>
|
64
|
+
</EbizDescriptions>
|
65
|
+
</div>
|
66
|
+
</div>
|
67
|
+
</template>
|
68
|
+
|
69
|
+
<script setup>
|
70
|
+
import { EbizDescriptions, EbizDescriptionsItem } from '../index.js';
|
71
|
+
</script>
|
72
|
+
|
73
|
+
<style scoped>
|
74
|
+
.container {
|
75
|
+
padding: 24px;
|
76
|
+
max-width: 1000px;
|
77
|
+
margin: 0 auto;
|
78
|
+
}
|
79
|
+
|
80
|
+
.demo-section {
|
81
|
+
margin-bottom: 32px;
|
82
|
+
}
|
83
|
+
|
84
|
+
h2 {
|
85
|
+
font-size: 24px;
|
86
|
+
margin-bottom: 24px;
|
87
|
+
}
|
88
|
+
|
89
|
+
h3 {
|
90
|
+
font-size: 18px;
|
91
|
+
margin-bottom: 16px;
|
92
|
+
}
|
93
|
+
|
94
|
+
.custom-label {
|
95
|
+
font-weight: bold;
|
96
|
+
color: #0052d9;
|
97
|
+
}
|
98
|
+
|
99
|
+
.custom-content {
|
100
|
+
font-style: italic;
|
101
|
+
}
|
102
|
+
</style>
|
@@ -0,0 +1,240 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="container">
|
3
|
+
<h1>树形合并单元格表格组件</h1>
|
4
|
+
<p>本组件基于TDesign表格组件,支持树形结构展示和单元格合并功能,通过单一的v-model绑定选中数据。</p>
|
5
|
+
|
6
|
+
<h2>基础树形表格</h2>
|
7
|
+
<div class="demo-block">
|
8
|
+
<EbizTreeMergeTable
|
9
|
+
:data="treeData"
|
10
|
+
:columns="basicColumns"
|
11
|
+
:bordered="true"
|
12
|
+
:tree="{ childrenKey: 'children', treeNodeColumnIndex: 0 }"
|
13
|
+
row-key="id"
|
14
|
+
/>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<h2>可选择的树形表格</h2>
|
18
|
+
<div class="demo-block">
|
19
|
+
<EbizTreeMergeTable
|
20
|
+
v-model="selectedRows"
|
21
|
+
:data="treeData"
|
22
|
+
:columns="selectableColumns"
|
23
|
+
:bordered="true"
|
24
|
+
:tree="{ childrenKey: 'children', treeNodeColumnIndex: 1 }"
|
25
|
+
row-key="id"
|
26
|
+
@select-change="onSelectChange"
|
27
|
+
/>
|
28
|
+
<div class="mt-2">
|
29
|
+
<p>已选择的行:{{ selectedRows.map(item => item.name).join(', ') || '无' }}</p>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<h2>单元格合并的树形表格</h2>
|
34
|
+
<div class="demo-block">
|
35
|
+
<EbizTreeMergeTable
|
36
|
+
:data="mergeTreeData"
|
37
|
+
:columns="mergeColumns"
|
38
|
+
:bordered="true"
|
39
|
+
:tree="{ childrenKey: 'children', treeNodeColumnIndex: 0 }"
|
40
|
+
:merge-cells="mergeCells"
|
41
|
+
row-key="id"
|
42
|
+
/>
|
43
|
+
<div class="description">
|
44
|
+
<p>该示例展示了如何通过mergeCells属性实现单元格合并</p>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
|
48
|
+
<h2>动态合并单元格的树形表格</h2>
|
49
|
+
<div class="demo-block">
|
50
|
+
<EbizTreeMergeTable
|
51
|
+
:data="mergeTreeData"
|
52
|
+
:columns="mergeColumns"
|
53
|
+
:bordered="true"
|
54
|
+
:tree="{ childrenKey: 'children', treeNodeColumnIndex: 0 }"
|
55
|
+
:merge-config="dynamicMergeConfig"
|
56
|
+
row-key="id"
|
57
|
+
/>
|
58
|
+
<div class="description">
|
59
|
+
<p>该示例展示了如何通过mergeConfig函数动态计算单元格合并逻辑</p>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
</template>
|
64
|
+
|
65
|
+
<script setup>
|
66
|
+
import { ref, reactive } from 'vue';
|
67
|
+
import { EbizTreeMergeTable } from '../index.js';
|
68
|
+
|
69
|
+
// 基础树形数据
|
70
|
+
const treeData = [
|
71
|
+
{
|
72
|
+
id: 1,
|
73
|
+
name: '北京总部',
|
74
|
+
age: '-',
|
75
|
+
address: '北京市海淀区',
|
76
|
+
children: [
|
77
|
+
{ id: 11, name: '研发部', age: 20, address: '北京市海淀区' },
|
78
|
+
{ id: 12, name: '销售部', age: 15, address: '北京市朝阳区' },
|
79
|
+
]
|
80
|
+
},
|
81
|
+
{
|
82
|
+
id: 2,
|
83
|
+
name: '上海分部',
|
84
|
+
age: '-',
|
85
|
+
address: '上海市浦东新区',
|
86
|
+
children: [
|
87
|
+
{ id: 21, name: '研发部', age: 12, address: '上海市浦东新区' },
|
88
|
+
{ id: 22, name: '销售部', age: 8, address: '上海市静安区' },
|
89
|
+
]
|
90
|
+
}
|
91
|
+
];
|
92
|
+
|
93
|
+
// 合并单元格的树形数据
|
94
|
+
const mergeTreeData = [
|
95
|
+
{
|
96
|
+
id: 1,
|
97
|
+
name: '研发部',
|
98
|
+
manager: '张三',
|
99
|
+
project: 'A项目',
|
100
|
+
status: '进行中',
|
101
|
+
children: [
|
102
|
+
{ id: 11, name: '研发部', manager: '张三', project: 'A项目子任务1', status: '进行中' },
|
103
|
+
{ id: 12, name: '研发部', manager: '张三', project: 'A项目子任务2', status: '已完成' },
|
104
|
+
{ id: 13, name: '研发部', manager: '张三', project: 'A项目子任务3', status: '进行中' },
|
105
|
+
]
|
106
|
+
},
|
107
|
+
{
|
108
|
+
id: 2,
|
109
|
+
name: '销售部',
|
110
|
+
manager: '李四',
|
111
|
+
project: 'B项目',
|
112
|
+
status: '已完成',
|
113
|
+
children: [
|
114
|
+
{ id: 21, name: '销售部', manager: '李四', project: 'B项目子任务1', status: '已完成' },
|
115
|
+
{ id: 22, name: '销售部', manager: '李四', project: 'B项目子任务2', status: '已完成' },
|
116
|
+
]
|
117
|
+
},
|
118
|
+
{
|
119
|
+
id: 3,
|
120
|
+
name: '市场部',
|
121
|
+
manager: '王五',
|
122
|
+
project: 'C项目',
|
123
|
+
status: '规划中',
|
124
|
+
children: [
|
125
|
+
{ id: 31, name: '市场部', manager: '王五', project: 'C项目子任务1', status: '规划中' },
|
126
|
+
]
|
127
|
+
}
|
128
|
+
];
|
129
|
+
|
130
|
+
// 基础列配置
|
131
|
+
const basicColumns = [
|
132
|
+
{ colKey: 'name', title: '名称', width: 150 },
|
133
|
+
{ colKey: 'age', title: '年龄', width: 100 },
|
134
|
+
{ colKey: 'address', title: '地址' },
|
135
|
+
];
|
136
|
+
|
137
|
+
// 可选择列配置
|
138
|
+
const selectableColumns = [
|
139
|
+
{ colKey: 'row-select', type: 'multiple', width: 50 },
|
140
|
+
{ colKey: 'name', title: '名称', width: 150 },
|
141
|
+
{ colKey: 'age', title: '年龄', width: 100 },
|
142
|
+
{ colKey: 'address', title: '地址' },
|
143
|
+
];
|
144
|
+
|
145
|
+
// 合并单元格列配置
|
146
|
+
const mergeColumns = [
|
147
|
+
{ colKey: 'name', title: '部门', width: 150 },
|
148
|
+
{ colKey: 'manager', title: '负责人', width: 120 },
|
149
|
+
{ colKey: 'project', title: '项目', width: 200 },
|
150
|
+
{ colKey: 'status', title: '状态', width: 100 },
|
151
|
+
];
|
152
|
+
|
153
|
+
// 已选择的行
|
154
|
+
const selectedRows = ref([]);
|
155
|
+
|
156
|
+
// 选择变化处理
|
157
|
+
const onSelectChange = (selectedRowData) => {
|
158
|
+
console.log('选择变化', selectedRowData);
|
159
|
+
};
|
160
|
+
|
161
|
+
// 静态合并单元格配置
|
162
|
+
const mergeCells = [
|
163
|
+
{ row: 0, col: 0, rowspan: 4, colspan: 1 }, // 第一个部门名称跨4行
|
164
|
+
{ row: 0, col: 1, rowspan: 4, colspan: 1 }, // 第一个负责人跨4行
|
165
|
+
{ row: 4, col: 0, rowspan: 3, colspan: 1 }, // 第二个部门名称跨3行
|
166
|
+
{ row: 4, col: 1, rowspan: 3, colspan: 1 }, // 第二个负责人跨3行
|
167
|
+
{ row: 7, col: 0, rowspan: 2, colspan: 1 }, // 第三个部门名称跨2行
|
168
|
+
{ row: 7, col: 1, rowspan: 2, colspan: 1 }, // 第三个负责人跨2行
|
169
|
+
];
|
170
|
+
|
171
|
+
// 动态合并单元格配置函数
|
172
|
+
const dynamicMergeConfig = (data) => {
|
173
|
+
const mergeCells = [];
|
174
|
+
let rowIndex = 0;
|
175
|
+
|
176
|
+
// 为每个部门生成合并单元格配置
|
177
|
+
data.forEach(dept => {
|
178
|
+
const rowCount = getRowCount(dept);
|
179
|
+
|
180
|
+
// 如果有子节点,合并部门名称和负责人列
|
181
|
+
if (rowCount > 1) {
|
182
|
+
mergeCells.push({ row: rowIndex, col: 0, rowspan: rowCount, colspan: 1 }); // 部门名称
|
183
|
+
mergeCells.push({ row: rowIndex, col: 1, rowspan: rowCount, colspan: 1 }); // 负责人
|
184
|
+
}
|
185
|
+
|
186
|
+
rowIndex += rowCount;
|
187
|
+
});
|
188
|
+
|
189
|
+
return mergeCells;
|
190
|
+
};
|
191
|
+
|
192
|
+
// 计算一个节点及其子节点的总行数
|
193
|
+
const getRowCount = (node) => {
|
194
|
+
if (!node.children || node.children.length === 0) {
|
195
|
+
return 1;
|
196
|
+
}
|
197
|
+
|
198
|
+
return 1 + node.children.reduce((sum, child) => sum + getRowCount(child), 0);
|
199
|
+
};
|
200
|
+
</script>
|
201
|
+
|
202
|
+
<style scoped>
|
203
|
+
.container {
|
204
|
+
padding: 20px;
|
205
|
+
max-width: 1200px;
|
206
|
+
margin: 0 auto;
|
207
|
+
}
|
208
|
+
|
209
|
+
.demo-block {
|
210
|
+
margin-bottom: 24px;
|
211
|
+
border: 1px solid #e9e9e9;
|
212
|
+
border-radius: 2px;
|
213
|
+
padding: 24px;
|
214
|
+
background-color: #fafafa;
|
215
|
+
}
|
216
|
+
|
217
|
+
h1 {
|
218
|
+
font-size: 28px;
|
219
|
+
margin-bottom: 16px;
|
220
|
+
}
|
221
|
+
|
222
|
+
h2 {
|
223
|
+
font-size: 20px;
|
224
|
+
margin: 24px 0 16px;
|
225
|
+
}
|
226
|
+
|
227
|
+
h3 {
|
228
|
+
font-size: 18px;
|
229
|
+
margin: 24px 0 16px;
|
230
|
+
}
|
231
|
+
|
232
|
+
.description {
|
233
|
+
margin-top: 16px;
|
234
|
+
color: #666;
|
235
|
+
}
|
236
|
+
|
237
|
+
.mt-2 {
|
238
|
+
margin-top: 16px;
|
239
|
+
}
|
240
|
+
</style>
|