web-component-gallery 2.3.9 → 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.
@@ -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
- labelWidth: PropTypes.number.def(160),
19
- descDetails: PropTypes.object,
20
- descSettings: PropTypes.array,
21
- descAttrs: PropTypes.object,
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
- return item.customRender
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
- return item.multiProps
45
- .map(propsItem => transferData(details[propsItem], 'Array'))
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
- parentRemainingHeight: 'auto'
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.$bus.$offWindow(this, 'resize', this.setDescContentWidth)
90
+ this.cleanupResize()
93
91
  },
94
92
 
95
93
  methods: {
96
- // 初始化组件
94
+ // 初始化组件逻辑
97
95
  initComponent() {
98
- this.setDescContentWidth()
99
- this.$bus.$onWindow(this, 'resize', this.setDescContentWidth)
96
+ if (this.isResponsive) {
97
+ this.setDescContentWidth()
98
+ this.bindResize()
99
+ } else {
100
+ this.responsiveColumn = this.getColumnValue()
101
+ }
100
102
  },
101
103
 
102
- // 获取响应式列数
103
- getCurrentColumn(width) {
104
- const config = COLUMN_CONFIG.find(item => width >= item.minWidth)
105
- return config ? config.getColumn(this.column) : 1
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
- calculateItemWidth(totalWidth, itemSpan) {
110
- const effectiveSpan = itemSpan && this.responsiveColumn > itemSpan ? itemSpan : 1
111
- return totalWidth * (effectiveSpan / this.responsiveColumn)
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
- const retry = () => {
117
- const container = this.$refs.Descriptions
118
- if (!container) return
119
-
120
- const viewElement = container.querySelector('.ant-descriptions-view')
121
- if (!viewElement) return
122
-
123
- const width = viewElement.offsetWidth
124
- if (width === 0) {
125
- setTimeout(retry, 100)
126
- return
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
- retry()
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 rowElements = container.querySelectorAll('.ant-descriptions-row')
163
+ const rows = container.querySelectorAll('.ant-descriptions-row')
140
164
  let itemCount = 0
141
165
 
142
- rowElements.forEach(rowElement => {
143
- const labelElements = rowElement.querySelectorAll('.ant-descriptions-item-label')
144
- const contentElements = rowElement.querySelectorAll('.ant-descriptions-item-content')
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
- labelElements.forEach((labelEl, index) => {
170
+ labels.forEach((label, index) => {
147
171
  const itemConfig = this.descSettings[itemCount]
148
- const itemSpan = itemConfig?.span || 1
149
- const eachWidth = totalWidth / this.responsiveColumn * itemSpan
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(labelEl, {
153
- width: `${this.labelWidth}px`,
154
- minWidth: `${this.labelWidth}px`,
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
- Object.assign(element.style, styles)
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
- setParentRemainingHeight() {
180
- const parent = this.$el.parentElement
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-component-gallery",
3
- "version": "2.3.9",
3
+ "version": "2.3.10",
4
4
  "description": "基础vue、antdvue、less实现的私有组件库",
5
5
  "main": "dist/index.umd.js",
6
6
  "files": [