web-component-gallery 2.3.8 → 2.3.10
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/js.umd.js +1 -1
- package/lib/descriptions-list/index.jsx +117 -102
- package/lib/model/style/index.less +1 -1
- package/package.json +1 -1
|
@@ -1,49 +1,54 @@
|
|
|
1
|
+
// 导入类型检查工具
|
|
1
2
|
import PropTypes from 'ant-design-vue/es/_util/vue-types'
|
|
3
|
+
// 导入 Ant Design Vue 的描述列表组件
|
|
2
4
|
import Descriptions from 'ant-design-vue/es/descriptions'
|
|
5
|
+
// 导入自定义的文件浏览组件
|
|
3
6
|
import Browse from '../browse/index.jsx'
|
|
7
|
+
// 导入数据转换工具函数
|
|
4
8
|
import { transferData } from '../../utils/Filter.js'
|
|
5
9
|
|
|
6
10
|
const { Item: DescriptionsItem } = Descriptions
|
|
7
11
|
|
|
8
|
-
//
|
|
12
|
+
// 描述列表的默认属性配置
|
|
9
13
|
const DESC_DEFAULT_ATTRS = {
|
|
10
14
|
size: 'middle',
|
|
11
15
|
bordered: true
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
//
|
|
18
|
+
// 组件的 Props 定义
|
|
15
19
|
const DescriptionsProps = {
|
|
16
|
-
title: PropTypes.string,
|
|
17
|
-
column: PropTypes.oneOfType([PropTypes.number, PropTypes.object]).def(4),
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
title: PropTypes.string, // 标题
|
|
21
|
+
column: PropTypes.oneOfType([PropTypes.number, PropTypes.object]).def(4), // 列数,支持响应式对象或固定数字
|
|
22
|
+
isResponsive: PropTypes.bool.def(true), // 是否开启响应式布局
|
|
23
|
+
labelWidth: PropTypes.number.def(160), // 标签固定宽度
|
|
24
|
+
descDetails: PropTypes.object, // 描述详情数据
|
|
25
|
+
descSettings: PropTypes.array, // 描述项配置数组
|
|
26
|
+
descAttrs: PropTypes.object, // 传递给 Descriptions 组件的其他属性
|
|
22
27
|
}
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
/**
|
|
30
|
+
* 渲染描述项的内容
|
|
31
|
+
* @param {Function} h - 渲染函数
|
|
32
|
+
* @param {Object} item - 当前项的配置
|
|
33
|
+
* @param {Object} details - 详情数据
|
|
34
|
+
*/
|
|
25
35
|
const renderContent = (h, item, details) => {
|
|
36
|
+
// 根据类型决定使用自定义组件还是普通 span
|
|
26
37
|
const CustomTag = item.type === 'file' ? Browse : 'span'
|
|
27
38
|
|
|
28
|
-
//
|
|
29
|
-
const getContentValue = () =>
|
|
30
|
-
|
|
31
|
-
? item.customRender(details[item.props], details)
|
|
32
|
-
: details[item.props]
|
|
33
|
-
}
|
|
39
|
+
// 获取内容值:优先使用自定义渲染函数,否则直接取数据
|
|
40
|
+
const getContentValue = () =>
|
|
41
|
+
item.customRender ? item.customRender(details[item.props], details) : details[item.props]
|
|
34
42
|
|
|
35
43
|
const contentValue = getContentValue()
|
|
36
44
|
|
|
37
|
-
//
|
|
45
|
+
// 处理数据:如果是文件类型且未自定义渲染,则进行数据转换
|
|
38
46
|
const processData = () => {
|
|
39
|
-
if (item.type !== 'file') return contentValue
|
|
40
|
-
|
|
41
|
-
if (item.customRender) return contentValue
|
|
47
|
+
if (item.type !== 'file' || item.customRender) return contentValue
|
|
42
48
|
|
|
43
49
|
if (item.hasOwnProperty('multiProps')) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.flat()
|
|
50
|
+
// 处理多属性情况,转换并扁平化数组
|
|
51
|
+
return item.multiProps.map(propsItem => transferData(details[propsItem], 'Array')).flat()
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
return contentValue
|
|
@@ -51,21 +56,14 @@ const renderContent = (h, item, details) => {
|
|
|
51
56
|
|
|
52
57
|
const data = processData()
|
|
53
58
|
|
|
54
|
-
const props = {
|
|
55
|
-
data,
|
|
56
|
-
isThumb: true,
|
|
57
|
-
astrictH: 78
|
|
58
|
-
}
|
|
59
|
-
|
|
60
59
|
return (
|
|
61
|
-
<CustomTag {...{ props }}>
|
|
60
|
+
<CustomTag {...{ props: { data, isThumb: true, astrictH: 78 } }}>
|
|
62
61
|
{contentValue ?? '暂无'}
|
|
63
62
|
</CustomTag>
|
|
64
63
|
)
|
|
65
64
|
}
|
|
66
|
-
// ... existing code ...
|
|
67
65
|
|
|
68
|
-
//
|
|
66
|
+
// 响应式列数配置:根据容器宽度动态计算列数
|
|
69
67
|
const COLUMN_CONFIG = [
|
|
70
68
|
{ minWidth: 1600, getColumn: (column) => column || 4 },
|
|
71
69
|
{ minWidth: 1200, getColumn: (column) => Math.min(4, column) },
|
|
@@ -79,8 +77,8 @@ const DescriptionsList = {
|
|
|
79
77
|
props: DescriptionsProps,
|
|
80
78
|
data() {
|
|
81
79
|
return {
|
|
82
|
-
responsiveColumn: 1,
|
|
83
|
-
|
|
80
|
+
responsiveColumn: 1, // 当前响应式列数
|
|
81
|
+
resizeTimer: null // 防抖定时器
|
|
84
82
|
}
|
|
85
83
|
},
|
|
86
84
|
|
|
@@ -89,78 +87,97 @@ const DescriptionsList = {
|
|
|
89
87
|
},
|
|
90
88
|
|
|
91
89
|
beforeDestroy() {
|
|
92
|
-
this
|
|
90
|
+
this.cleanupResize()
|
|
93
91
|
},
|
|
94
92
|
|
|
95
93
|
methods: {
|
|
96
|
-
//
|
|
94
|
+
// 初始化组件逻辑
|
|
97
95
|
initComponent() {
|
|
98
|
-
this.
|
|
99
|
-
|
|
96
|
+
if (this.isResponsive) {
|
|
97
|
+
this.setDescContentWidth()
|
|
98
|
+
this.bindResize()
|
|
99
|
+
} else {
|
|
100
|
+
this.responsiveColumn = this.getColumnValue()
|
|
101
|
+
}
|
|
100
102
|
},
|
|
101
103
|
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
// 清理窗口大小监听和定时器
|
|
105
|
+
cleanupResize() {
|
|
106
|
+
if (this.resizeTimer) {
|
|
107
|
+
clearTimeout(this.resizeTimer)
|
|
108
|
+
this.resizeTimer = null
|
|
109
|
+
}
|
|
110
|
+
window.removeEventListener('resize', this.handleResize)
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
// 绑定窗口大小变化事件
|
|
114
|
+
bindResize() {
|
|
115
|
+
window.addEventListener('resize', this.handleResize)
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// 处理窗口大小变化(带防抖)
|
|
119
|
+
handleResize() {
|
|
120
|
+
if (this.resizeTimer) clearTimeout(this.resizeTimer)
|
|
121
|
+
this.resizeTimer = setTimeout(() => {
|
|
122
|
+
this.setDescContentWidth()
|
|
123
|
+
}, 150)
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
// 获取非响应式模式下的列数值
|
|
127
|
+
getColumnValue() {
|
|
128
|
+
return typeof this.column === 'object' ? this.column.xs : this.column || 4
|
|
106
129
|
},
|
|
107
130
|
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
return
|
|
131
|
+
// 根据当前宽度获取应显示的列数
|
|
132
|
+
getCurrentColumn(width) {
|
|
133
|
+
const config = COLUMN_CONFIG.find(item => width >= item.minWidth)
|
|
134
|
+
return config?.getColumn(this.column) ?? 1
|
|
112
135
|
},
|
|
113
136
|
|
|
114
|
-
//
|
|
137
|
+
// 计算并设置描述内容的宽度和列数
|
|
115
138
|
setDescContentWidth() {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
this.responsiveColumn = this.getCurrentColumn(width)
|
|
130
|
-
this.updateItemStyles(container, width)
|
|
139
|
+
if (!this.isResponsive) return
|
|
140
|
+
|
|
141
|
+
const container = this.$refs.Descriptions
|
|
142
|
+
if (!container) return
|
|
143
|
+
|
|
144
|
+
const viewElement = container.querySelector('.ant-descriptions-view')
|
|
145
|
+
if (!viewElement) return
|
|
146
|
+
|
|
147
|
+
const width = viewElement.offsetWidth
|
|
148
|
+
// 如果宽度为 0(可能尚未渲染),延迟重试
|
|
149
|
+
if (width === 0) {
|
|
150
|
+
setTimeout(() => this.setDescContentWidth(), 100)
|
|
151
|
+
return
|
|
131
152
|
}
|
|
132
153
|
|
|
133
|
-
|
|
154
|
+
this.responsiveColumn = this.getCurrentColumn(width)
|
|
155
|
+
this.updateItemStyles(container, width)
|
|
134
156
|
},
|
|
135
157
|
|
|
136
|
-
//
|
|
158
|
+
// 更新每一项的标签和内容宽度样式
|
|
137
159
|
updateItemStyles(container, totalWidth) {
|
|
160
|
+
if (!this.isResponsive) return
|
|
161
|
+
|
|
138
162
|
this.$nextTick(() => {
|
|
139
|
-
const
|
|
163
|
+
const rows = container.querySelectorAll('.ant-descriptions-row')
|
|
140
164
|
let itemCount = 0
|
|
141
165
|
|
|
142
|
-
|
|
143
|
-
const
|
|
144
|
-
const
|
|
166
|
+
rows.forEach(row => {
|
|
167
|
+
const labels = row.querySelectorAll('.ant-descriptions-item-label')
|
|
168
|
+
const contents = row.querySelectorAll('.ant-descriptions-item-content')
|
|
145
169
|
|
|
146
|
-
|
|
170
|
+
labels.forEach((label, index) => {
|
|
147
171
|
const itemConfig = this.descSettings[itemCount]
|
|
148
|
-
const
|
|
149
|
-
|
|
172
|
+
const span = itemConfig?.span || 1
|
|
173
|
+
// 计算每项总宽度和内容区域宽度
|
|
174
|
+
const eachWidth = (totalWidth / this.responsiveColumn) * span
|
|
175
|
+
const contentWidth = eachWidth - this.labelWidth
|
|
150
176
|
|
|
151
|
-
//
|
|
152
|
-
this.setStyle(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
maxWidth: `${this.labelWidth}px`
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
// 设置内容样式
|
|
159
|
-
this.setStyle(contentElements[index], {
|
|
160
|
-
width: `${eachWidth - this.labelWidth}px`,
|
|
161
|
-
minWidth: `${eachWidth - this.labelWidth}px`,
|
|
162
|
-
maxWidth: `${eachWidth - this.labelWidth}px`
|
|
163
|
-
})
|
|
177
|
+
// 设置固定标签宽度
|
|
178
|
+
this.setStyle(label, { width: `${this.labelWidth}px`, minWidth: `${this.labelWidth}px`, maxWidth: `${this.labelWidth}px` })
|
|
179
|
+
// 设置自适应内容宽度
|
|
180
|
+
this.setStyle(contents[index], { width: `${contentWidth}px`, minWidth: `${contentWidth}px`, maxWidth: `${contentWidth}px` })
|
|
164
181
|
|
|
165
182
|
itemCount++
|
|
166
183
|
})
|
|
@@ -168,22 +185,22 @@ const DescriptionsList = {
|
|
|
168
185
|
})
|
|
169
186
|
},
|
|
170
187
|
|
|
171
|
-
//
|
|
188
|
+
// 辅助方法:设置元素样式
|
|
172
189
|
setStyle(element, styles) {
|
|
173
|
-
if (element)
|
|
174
|
-
|
|
175
|
-
|
|
190
|
+
if (element) Object.assign(element.style, styles)
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
watch: {
|
|
195
|
+
// 监听响应式开关变化
|
|
196
|
+
isResponsive(val) {
|
|
197
|
+
val ? this.bindResize() : this.cleanupResize()
|
|
198
|
+
this.responsiveColumn = val ? this.getCurrentColumn(window.innerWidth) : this.getColumnValue()
|
|
176
199
|
},
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (parent) {
|
|
182
|
-
const parentHeight = parent.offsetHeight
|
|
183
|
-
const rect = this.$el.getBoundingClientRect()
|
|
184
|
-
const parentRect = parent.getBoundingClientRect()
|
|
185
|
-
const remainingHeight = parentHeight - (rect.top - parentRect.top)
|
|
186
|
-
this.parentRemainingHeight = `${remainingHeight}px`
|
|
200
|
+
// 监听列数配置变化
|
|
201
|
+
column(val) {
|
|
202
|
+
if (!this.isResponsive) {
|
|
203
|
+
this.responsiveColumn = this.getColumnValue()
|
|
187
204
|
}
|
|
188
205
|
}
|
|
189
206
|
},
|
|
@@ -199,10 +216,7 @@ const DescriptionsList = {
|
|
|
199
216
|
{...{ attrs: { ...DESC_DEFAULT_ATTRS, ...descAttrs } }}
|
|
200
217
|
>
|
|
201
218
|
{descSettings.map((descItem, key) => (
|
|
202
|
-
<DescriptionsItem
|
|
203
|
-
key={key}
|
|
204
|
-
span={descItem.span ?? 1}
|
|
205
|
-
>
|
|
219
|
+
<DescriptionsItem key={key} span={descItem.span ?? 1}>
|
|
206
220
|
<span slot="label">
|
|
207
221
|
{$slots[`${descItem.props}Label`] ?? descItem.label}
|
|
208
222
|
</span>
|
|
@@ -218,8 +232,9 @@ const DescriptionsList = {
|
|
|
218
232
|
}
|
|
219
233
|
}
|
|
220
234
|
|
|
235
|
+
// 安装方法,用于注册全局组件
|
|
221
236
|
DescriptionsList.install = function(Vue) {
|
|
222
237
|
Vue.component('DescriptionsList', DescriptionsList)
|
|
223
238
|
}
|
|
224
239
|
|
|
225
|
-
export default DescriptionsList
|
|
240
|
+
export default DescriptionsList
|