vue2server7 7.0.108 → 7.0.110

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.
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: 表格列配置演示页面设计
3
+ description: 新增表格列配置演示页面的设计文档
4
+ type: project
5
+ ---
6
+
7
+ # 表格列配置演示页面设计
8
+
9
+ ## 概述
10
+
11
+ 为前端项目新增一个"表格列配置演示"路由页面,提供基础的表格页面框架,预留列配置功能的扩展点。
12
+
13
+ ## 功能需求
14
+
15
+ 1. **基础表格页面**:包含标题、工具栏、表格组件、分页
16
+ 2. **模拟数据**:提供基础的表格数据和列配置数据结构
17
+ 3. **预留扩展点**:列设置按钮、预留列配置功能位置
18
+ 4. **路由配置**:在侧边栏菜单中显示"表格列配置演示"
19
+
20
+ ## 架构设计
21
+
22
+ ### 文件结构
23
+
24
+ ```
25
+ frontEnd/src/
26
+ ├── pages/
27
+ │ └── ColumnConfigDemoPage.vue # 新增:列配置演示页面
28
+ └── router/
29
+ └── routes.js # 修改:添加新路由
30
+ ```
31
+
32
+ ### 技术栈
33
+
34
+ - Vue 3 + Composition API + TypeScript
35
+ - Element Plus UI 组件库
36
+ - vue-router 4.x
37
+
38
+ ## 实现步骤
39
+
40
+ 1. 创建 `ColumnConfigDemoPage.vue` 页面文件
41
+ - 基础页面结构(标题、工具栏、el-table、分页)
42
+ - 模拟列配置数据(含 key、label、width、align 等属性)
43
+ - 模拟表格数据
44
+ - 预留"列设置"按钮及相关 UI 位置
45
+
46
+ 2. 修改 `routes.js` 添加新路由
47
+ - 路径:/column-config-demo
48
+ - 名称:ColumnConfigDemo
49
+ - 菜单标题:表格列配置演示
50
+ - showInMenu: true
51
+
52
+ ## 数据结构
53
+
54
+ ### 列配置接口
55
+
56
+ ```typescript
57
+ interface ColumnConfig {
58
+ key: string // 列唯一标识
59
+ prop: string // 数据字段名
60
+ label: string // 列标题
61
+ width?: number // 列宽
62
+ minWidth?: number // 最小列宽
63
+ align?: 'left' | 'center' | 'right'
64
+ fixed?: boolean | 'left' | 'right'
65
+ sortable?: boolean | 'custom'
66
+ visible?: boolean // 是否显示
67
+ }
68
+ ```
69
+
70
+ ## 注意事项
71
+
72
+ - 遵循现有页面的代码风格和目录结构
73
+ - 列配置的具体实现逻辑由用户自行开发
74
+ - 页面结构保持简洁,便于后续扩展
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: 表格列配置组件设计
3
+ description: 集成 TableColumnSettings 列配置组件到项目
4
+ type: project
5
+ ---
6
+
7
+ # 表格列配置组件设计
8
+
9
+ ## 概述
10
+
11
+ 将用户提供的 TableColumnSettings 列配置组件集成到项目中,并更新 ColumnConfigDemoPage 演示页面使用该组件。
12
+
13
+ ## 功能需求
14
+
15
+ 1. **TableColumnSettings 组件**
16
+ - 弹窗形式的列配置面板
17
+ - 支持全选/反选、多选框组
18
+ - 支持禁用某些列(不可取消选中)
19
+ - 确认后触发事件返回选中的列 keys
20
+ - 自定义按钮文本
21
+
22
+ 2. **演示页面集成**
23
+ - 在 ColumnConfigDemoPage 中使用列配置组件
24
+ - 实现列显示/隐藏的动态更新
25
+ - 支持强制显示的列(disabled)
26
+
27
+ ## 架构设计
28
+
29
+ ### 文件结构
30
+
31
+ ```
32
+ frontEnd/src/
33
+ ├── components/
34
+ │ └── TableColumnSettings.vue # 新增:列配置组件
35
+ └── pages/
36
+ └── ColumnConfigDemoPage.vue # 修改:集成组件
37
+ ```
38
+
39
+ ## 组件接口
40
+
41
+ ### Props
42
+
43
+ | 名称 | 类型 | 说明 | 默认值 |
44
+ |------|------|------|--------|
45
+ | columns | Array | 列配置数组,每项需包含 prop、label、disabled | [] |
46
+ | selectedKeys | Array | 当前选中的列 key 数组 | [] |
47
+ | buttonText | String | 按钮显示文本 | '列配置' |
48
+
49
+ ### Events
50
+
51
+ | 名称 | 参数 | 说明 |
52
+ |------|------|------|
53
+ | confirm | selectedKeys | 用户点击确认时触发,返回选中的列 keys 数组 |
54
+
55
+ ### Column 数据结构
56
+
57
+ ```javascript
58
+ {
59
+ prop: 'name', // 列唯一标识
60
+ label: '姓名', // 列显示名称
61
+ disabled: false // 是否禁用(禁用的列始终显示,不可取消选中)
62
+ }
63
+ ```
64
+
65
+ ## 实现步骤
66
+
67
+ 1. 创建 `TableColumnSettings.vue` 组件
68
+ 2. 更新 `ColumnConfigDemoPage.vue` 集成组件
69
+ 3. 验证功能正常工作
@@ -0,0 +1,296 @@
1
+ <template>
2
+ <div class="base-table-wrapper">
3
+ <!-- 工具栏区域 -->
4
+ <div class="table-toolbar" v-if="showToolbar">
5
+ <slot name="toolbar">
6
+ <!-- 列配置按钮 -->
7
+ <TableColumnSettings
8
+ :columns="columnSettings"
9
+ :selected-keys="selectedKeys"
10
+ :storage-key="storageKey"
11
+ @confirm="onColumnConfirm"
12
+ />
13
+ </slot>
14
+ </div>
15
+
16
+ <!-- 表格主体 -->
17
+ <el-table
18
+ ref="tableRef"
19
+ :key="tableKey"
20
+ v-bind="$attrs"
21
+ :data="data"
22
+ border
23
+ stripe
24
+ size="small"
25
+ style="width: 100%"
26
+ v-on="$listeners"
27
+ >
28
+ <!-- 序号列(可选) -->
29
+ <el-table-column
30
+ v-if="showIndex"
31
+ type="index"
32
+ label="序号"
33
+ width="60"
34
+ align="center"
35
+ />
36
+
37
+ <!-- 动态列渲染 -->
38
+ <el-table-column
39
+ v-for="col in visibleColumns"
40
+ :key="col.prop"
41
+ :prop="col.prop"
42
+ :label="col.label"
43
+ :width="col.width"
44
+ :min-width="col.minWidth"
45
+ :align="col.align || 'left'"
46
+ :header-align="col.headerAlign || col.align || 'left'"
47
+ :sortable="col.sortable || false"
48
+ :fixed="col.fixed || false"
49
+ >
50
+ <!-- 自定义列插槽(格式为 column-xxx,xxx 是列的 prop) -->
51
+ <template #default="scope">
52
+ <slot :name="'column-' + col.prop" v-bind="scope">
53
+ {{ scope.row[col.prop] }}
54
+ </slot>
55
+ </template>
56
+ </el-table-column>
57
+
58
+ <!-- 操作列(插槽) -->
59
+ <slot name="action-column" />
60
+ </el-table>
61
+
62
+ <!-- 分页区域(可选) -->
63
+ <div class="table-pagination" v-if="showPagination && total > 0">
64
+ <el-pagination
65
+ layout="total, prev, pager, next"
66
+ :current-page="currentPage"
67
+ :page-size="pageSize"
68
+ :total="total"
69
+ @current-change="onPageChange"
70
+ />
71
+ </div>
72
+ </div>
73
+ </template>
74
+
75
+ <script setup lang="ts">
76
+ import { ref, computed, onMounted, useAttrs } from 'vue'
77
+ import TableColumnSettings from './TableColumnSettings.vue'
78
+
79
+ // 列配置接口
80
+ interface ColumnConfig {
81
+ prop: string // 列唯一标识(必填)
82
+ label: string // 列显示名称(必填)
83
+ width?: number // 列宽
84
+ minWidth?: number // 最小列宽
85
+ align?: 'left' | 'center' | 'right' // 对齐方式
86
+ headerAlign?: 'left' | 'center' | 'right' // 表头对齐
87
+ sortable?: boolean | 'custom' // 是否可排序
88
+ fixed?: boolean | 'left' | 'right' // 是否固定
89
+ disabled?: boolean // 是否禁用(禁用的列始终显示,不可取消)
90
+ }
91
+
92
+ // 组件 Props 定义
93
+ const props = defineProps({
94
+ /**
95
+ * 表格数据
96
+ */
97
+ data: {
98
+ type: Array,
99
+ default: () => []
100
+ },
101
+ /**
102
+ * 列配置数组
103
+ */
104
+ columns: {
105
+ type: Array as () => ColumnConfig[],
106
+ default: () => []
107
+ },
108
+ /**
109
+ * 是否显示序号列
110
+ */
111
+ showIndex: {
112
+ type: Boolean,
113
+ default: true
114
+ },
115
+ /**
116
+ * 是否显示工具栏
117
+ */
118
+ showToolbar: {
119
+ type: Boolean,
120
+ default: true
121
+ },
122
+ /**
123
+ * 是否显示分页
124
+ */
125
+ showPagination: {
126
+ type: Boolean,
127
+ default: true
128
+ },
129
+ /**
130
+ * 当前页码
131
+ */
132
+ currentPage: {
133
+ type: Number,
134
+ default: 1
135
+ },
136
+ /**
137
+ * 每页条数
138
+ */
139
+ pageSize: {
140
+ type: Number,
141
+ default: 10
142
+ },
143
+ /**
144
+ * 总条数
145
+ */
146
+ total: {
147
+ type: Number,
148
+ default: 0
149
+ },
150
+ /**
151
+ * localStorage 存储键名
152
+ * 用于持久化用户的列配置
153
+ * 不设置则不持久化
154
+ */
155
+ storageKey: {
156
+ type: String,
157
+ default: ''
158
+ }
159
+ })
160
+
161
+ // 组件 Events 定义
162
+ const emit = defineEmits<{
163
+ (e: 'update:currentPage', page: number): void
164
+ (e: 'pageChange', page: number): void
165
+ }>()
166
+
167
+ // ==================== 响应式状态 ====================
168
+
169
+ /**
170
+ * el-table 实例引用
171
+ * 可以通过 ref 调用 Element Plus 表格的原生方法
172
+ */
173
+ const tableRef = ref()
174
+
175
+ /**
176
+ * 表格 key,用于强制刷新表格
177
+ * 列配置变更后更新此值,触发表格重新渲染
178
+ */
179
+ const tableKey = ref(0)
180
+
181
+ /**
182
+ * 当前选中的列 key 数组
183
+ * 存储用户选择显示的列 prop
184
+ */
185
+ const selectedKeys = ref<string[]>([])
186
+
187
+ // ==================== 计算属性 ====================
188
+
189
+ /**
190
+ * 列配置组件需要的数据格式
191
+ * 只提取列配置组件需要的三个字段
192
+ */
193
+ const columnSettings = computed(() => {
194
+ return props.columns.map(col => ({
195
+ prop: col.prop,
196
+ label: col.label,
197
+ disabled: col.disabled || false
198
+ }))
199
+ })
200
+
201
+ /**
202
+ * 当前可见的列
203
+ * 根据 selectedKeys 过滤出用户选择显示的列
204
+ */
205
+ const visibleColumns = computed(() => {
206
+ return props.columns.filter(col => selectedKeys.value.includes(col.prop))
207
+ })
208
+
209
+ // ==================== 方法 ====================
210
+
211
+ /**
212
+ * 列配置确认回调
213
+ * @param keys - 用户选中的列 prop 数组
214
+ *
215
+ * 逻辑:
216
+ * 1. 更新选中的列
217
+ * 2. 更新 tableKey 强制表格重新渲染
218
+ */
219
+ const onColumnConfirm = (keys: string[]) => {
220
+ selectedKeys.value = keys
221
+ tableKey.value += 1 // 强制刷新表格
222
+ }
223
+
224
+ /**
225
+ * 分页切换回调
226
+ * @param page - 目标页码
227
+ *
228
+ * 触发两个事件:
229
+ * 1. update:currentPage - 支持 v-model:currentPage
230
+ * 2. pageChange - 普通分页变更事件
231
+ */
232
+ const onPageChange = (page: number) => {
233
+ emit('update:currentPage', page)
234
+ emit('pageChange', page)
235
+ }
236
+
237
+ // ==================== 生命周期 ====================
238
+
239
+ /**
240
+ * 组件挂载时初始化
241
+ *
242
+ * 逻辑:
243
+ * 1. 如果设置了 storageKey,从 localStorage 读取保存的配置
244
+ * 2. 读取失败或没有存储,则默认显示所有列
245
+ */
246
+ onMounted(() => {
247
+ if (props.storageKey) {
248
+ const stored = localStorage.getItem(props.storageKey)
249
+ if (stored) {
250
+ try {
251
+ selectedKeys.value = JSON.parse(stored)
252
+ } catch {
253
+ // 解析失败,默认显示所有列
254
+ selectedKeys.value = props.columns.map(col => col.prop)
255
+ }
256
+ } else {
257
+ // 没有存储,默认显示所有列
258
+ selectedKeys.value = props.columns.map(col => col.prop)
259
+ }
260
+ } else {
261
+ // 没有设置 storageKey,默认显示所有列
262
+ selectedKeys.value = props.columns.map(col => col.prop)
263
+ }
264
+ })
265
+
266
+ // 暴露 el-table 实例给父组件,方便调用原生方法
267
+ defineExpose({
268
+ tableRef
269
+ })
270
+ </script>
271
+
272
+ <style scoped>
273
+ /**
274
+ * 表格外层容器
275
+ */
276
+ .base-table-wrapper {
277
+ width: 100%;
278
+ }
279
+
280
+ /**
281
+ * 工具栏样式
282
+ * 位于表格上方,包含操作按钮等
283
+ */
284
+ .table-toolbar {
285
+ margin-bottom: 12px;
286
+ }
287
+
288
+ /**
289
+ * 分页容器样式
290
+ * 位于表格下方,右对齐
291
+ */
292
+ .table-pagination {
293
+ margin-top: 12px;
294
+ text-align: right;
295
+ }
296
+ </style>