xt-element-ui 2.2.3 → 2.2.4

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.
Files changed (116) hide show
  1. package/README.md +140 -192
  2. package/docs/README.md +162 -88
  3. package/docs/components/base/theme.md +248 -0
  4. package/docs/components/base/xt-list.md +1 -1
  5. package/docs/components/base/xt-scroll-arrow.md +87 -1
  6. package/docs/components/base/xt-scroll.md +237 -0
  7. package/docs/components/utils/config.md +18 -4
  8. package/docs/components/utils/theme.md +280 -183
  9. package/lib/index.common.1.js +4 -26
  10. package/lib/index.common.2.js +1 -1
  11. package/lib/index.common.js +1871 -671
  12. package/lib/index.css +1 -1
  13. package/lib/index.umd.1.js +4 -26
  14. package/lib/index.umd.2.js +1 -1
  15. package/lib/index.umd.js +1871 -671
  16. package/lib/index.umd.min.1.js +1 -1
  17. package/lib/index.umd.min.js +1 -1
  18. package/lib/theme/element-overrides.css +607 -0
  19. package/lib/theme/element-vars.css +280 -0
  20. package/lib/xt-badge/xt-badge.common.js +1 -1
  21. package/lib/xt-badge/xt-badge.umd.js +1 -1
  22. package/lib/xt-button/xt-button.common.js +1 -1
  23. package/lib/xt-button/xt-button.umd.js +1 -1
  24. package/lib/xt-card/xt-card.common.js +1 -1
  25. package/lib/xt-card/xt-card.umd.js +1 -1
  26. package/lib/xt-card-item/xt-card-item.common.js +1 -1
  27. package/lib/xt-card-item/xt-card-item.umd.js +1 -1
  28. package/lib/xt-chart/xt-chart.common.js +5 -5
  29. package/lib/xt-chart/xt-chart.umd.js +5 -5
  30. package/lib/xt-config-provider/xt-config-provider.css +1 -1
  31. package/lib/xt-date-picker/xt-date-picker.common.1.js +4 -26
  32. package/lib/xt-date-picker/xt-date-picker.common.2.js +1 -1
  33. package/lib/xt-date-picker/xt-date-picker.common.js +1 -47
  34. package/lib/xt-date-picker/xt-date-picker.css +1 -1
  35. package/lib/xt-date-picker/xt-date-picker.umd.1.js +4 -26
  36. package/lib/xt-date-picker/xt-date-picker.umd.2.js +1 -1
  37. package/lib/xt-date-picker/xt-date-picker.umd.js +1 -47
  38. package/lib/xt-date-picker/xt-date-picker.umd.min.1.js +1 -1
  39. package/lib/xt-date-picker/xt-date-picker.umd.min.js +1 -1
  40. package/lib/xt-flex-box/xt-flex-box.common.js +1 -1
  41. package/lib/xt-flex-box/xt-flex-box.umd.js +1 -1
  42. package/lib/xt-flow/xt-flow.common.js +1 -1
  43. package/lib/xt-flow/xt-flow.umd.js +1 -1
  44. package/lib/xt-form-schema/xt-form-schema.common.js +1 -1
  45. package/lib/xt-form-schema/xt-form-schema.umd.js +1 -1
  46. package/lib/xt-grid-box/xt-grid-box.common.js +1 -1
  47. package/lib/xt-grid-box/xt-grid-box.umd.js +1 -1
  48. package/lib/xt-grid-item/xt-grid-item.common.js +1 -1
  49. package/lib/xt-grid-item/xt-grid-item.umd.js +1 -1
  50. package/lib/xt-icon/xt-icon.common.js +1 -1
  51. package/lib/xt-icon/xt-icon.umd.js +1 -1
  52. package/lib/xt-input/xt-input.common.js +1 -1
  53. package/lib/xt-input/xt-input.umd.js +1 -1
  54. package/lib/xt-list/xt-list.common.js +457 -118
  55. package/lib/xt-list/xt-list.css +1 -1
  56. package/lib/xt-list/xt-list.umd.js +457 -118
  57. package/lib/xt-list/xt-list.umd.min.js +1 -1
  58. package/lib/xt-map/xt-map.common.js +1 -1
  59. package/lib/xt-map/xt-map.umd.js +1 -1
  60. package/lib/xt-map-provider/xt-map-provider.common.js +1 -1
  61. package/lib/xt-map-provider/xt-map-provider.umd.js +1 -1
  62. package/lib/xt-page/xt-page.common.js +1 -1
  63. package/lib/xt-page/xt-page.umd.js +1 -1
  64. package/lib/xt-progress/xt-progress.common.js +1 -1
  65. package/lib/xt-progress/xt-progress.umd.js +1 -1
  66. package/lib/xt-scroll/demo.html +10 -0
  67. package/lib/xt-scroll/index.js +1 -0
  68. package/lib/xt-scroll/xt-scroll.common.js +551 -0
  69. package/lib/xt-scroll/xt-scroll.css +1 -0
  70. package/lib/xt-scroll/xt-scroll.umd.js +561 -0
  71. package/lib/xt-scroll/xt-scroll.umd.min.js +1 -0
  72. package/lib/xt-scroll-arrow/xt-scroll-arrow.common.js +591 -170
  73. package/lib/xt-scroll-arrow/xt-scroll-arrow.css +1 -1
  74. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.js +591 -170
  75. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.min.js +1 -1
  76. package/lib/xt-select-tree/xt-select-tree.common.js +1 -1
  77. package/lib/xt-select-tree/xt-select-tree.umd.js +1 -1
  78. package/lib/xt-step-price/xt-step-price.common.js +2 -2
  79. package/lib/xt-step-price/xt-step-price.umd.js +2 -2
  80. package/lib/xt-step-price-item/xt-step-price-item.common.js +1 -1
  81. package/lib/xt-step-price-item/xt-step-price-item.umd.js +1 -1
  82. package/lib/xt-tab-pane/xt-tab-pane.common.js +1 -1
  83. package/lib/xt-tab-pane/xt-tab-pane.umd.js +1 -1
  84. package/lib/xt-table/xt-table.common.js +2 -2
  85. package/lib/xt-table/xt-table.umd.js +2 -2
  86. package/lib/xt-tabs/xt-tabs.common.js +1 -1
  87. package/lib/xt-tabs/xt-tabs.umd.js +1 -1
  88. package/lib/xt-text/xt-text.common.js +1 -1
  89. package/lib/xt-text/xt-text.umd.js +1 -1
  90. package/lib/xt-time/xt-time.common.js +1 -1
  91. package/lib/xt-time/xt-time.umd.js +1 -1
  92. package/lib/xt-transfer-tree/xt-transfer-tree.common.js +1 -1
  93. package/lib/xt-transfer-tree/xt-transfer-tree.umd.js +1 -1
  94. package/lib/xt-upload/xt-upload.common.js +2 -2
  95. package/lib/xt-upload/xt-upload.umd.js +2 -2
  96. package/package.json +5 -3
  97. package/src/components/index.scss +3 -0
  98. package/src/components/theme/element-overrides.css +607 -0
  99. package/src/components/theme/element-vars.css +280 -0
  100. package/src/components/theme/iframe-injector.js +502 -0
  101. package/src/components/theme/index.js +64 -0
  102. package/src/components/xt-config-provider/style/index.scss +0 -11
  103. package/src/components/xt-date-picker/component/RangeDate.vue +1 -29
  104. package/src/components/xt-date-picker/style/index.scss +80 -53
  105. package/src/components/xt-list/index.vue +23 -12
  106. package/src/components/xt-scroll/index.js +9 -0
  107. package/src/components/xt-scroll/index.vue +363 -0
  108. package/src/components/xt-scroll/style/index.scss +107 -0
  109. package/src/components/xt-scroll-arrow/index.vue +200 -83
  110. package/src/components/xt-scroll-arrow/style/index.scss +16 -5
  111. package/src/index.js +9 -2
  112. package/src/utils/color.js +105 -0
  113. package/src/utils/index.js +456 -468
  114. package/src/utils/theme-vars.js +134 -0
  115. package/lib/css/1.87a493be.css +0 -1
  116. package/lib/xt-date-picker/css/1.87a493be.css +0 -1
@@ -0,0 +1,248 @@
1
+ ## iframe 主题注入
2
+
3
+ ## 概述
4
+
5
+ 为微前端架构提供统一的主题管理方案。主系统切换主题后,子系统 iframe 中的 Element UI 组件会自动同步换色,子系统无需任何改造。
6
+
7
+ ### 设计思路
8
+
9
+ | 角色 | 职责 |
10
+ |------|------|
11
+ | 主系统 | 统一管理主题状态,注入 CSS 变量到 iframe |
12
+ | 子系统 | 标准 Element UI 项目,无需改造 |
13
+ | 注入时机 | iframe 加载完成后自动注入 |
14
+
15
+ ### 工作流程
16
+
17
+ ```
18
+ 1. 主系统调用 setTheme('dark')
19
+
20
+ 2. utils 同步更新 --el-* + --xt-* 变量到主文档
21
+
22
+ 3. utils 通过 onConfigChange 广播主题变更
23
+
24
+ 4. 所有 IframeThemeInjector 实例收到通知
25
+
26
+ 5. 实例通过 applyThemeVars 将新主题应用到管理的 iframe
27
+
28
+ 6. 所有 iframe 内的 Element UI 组件实时换色
29
+ ```
30
+
31
+ ## 快速开始
32
+
33
+ ### JS 模块(CSS 已内联为字符串)
34
+
35
+ ```javascript
36
+ import { createThemeInjector } from 'xt-element-ui'
37
+
38
+ // 创建注入器(CSS 已内联,无需手动提供)
39
+ const injector = createThemeInjector({ theme: 'white' })
40
+
41
+ // 注入所有 iframe
42
+ injector.injectAll('iframe')
43
+ ```
44
+
45
+ ### 直接引用 CSS 文件
46
+
47
+ 如果使用独立 CSS 文件注入:
48
+
49
+ ```html
50
+ <link rel="stylesheet" href="xt-element-ui/lib/theme/element-vars.css">
51
+ <link rel="stylesheet" href="xt-element-ui/lib/theme/element-overrides.css">
52
+ ```
53
+
54
+ ### 手动注入 iframe(使用独立 CSS 文件)
55
+
56
+ ```javascript
57
+ // 动态加载并注入
58
+ fetch('/lib/theme/element-vars.css')
59
+ .then(res => res.text())
60
+ .then(css => {
61
+ const style = document.createElement('style')
62
+ style.textContent = css
63
+ iframe.contentDocument.head.appendChild(style)
64
+ })
65
+ ```
66
+
67
+ ## API 说明
68
+
69
+ ### createThemeInjector(options)
70
+
71
+ 创建一个预配置的主题注入器实例。
72
+
73
+ | 参数 | 类型 | 必填 | 说明 |
74
+ |------|------|------|------|
75
+ | `options.theme` | String | 否 | 初始主题:`white`、`dark`(默认 `white`) |
76
+ | `options.primaryColor` | String | 否 | 初始主色调(默认 `#1890ff`) |
77
+ | `options.brand` | String | 否 | 品牌标识:`''`、`water`、`electricity`、`gas` |
78
+ | `options.persist` | Boolean | 否 | 是否持久化到 localStorage(默认 `false`) |
79
+ | `options.onThemeChange` | Function | 否 | 主题变化回调 |
80
+
81
+ **返回值**:`IframeThemeInjector` 实例
82
+
83
+ ### inject(iframe)
84
+
85
+ 向指定 iframe 注入主题 CSS。
86
+
87
+ | 参数 | 类型 | 必填 | 说明 |
88
+ |------|------|------|------|
89
+ | `iframe` | HTMLIFrameElement | 是 | iframe 元素 |
90
+
91
+ **返回值**:`boolean` 是否注入成功
92
+
93
+ ### injectAll(selector)
94
+
95
+ 批量注入所有匹配选择器的 iframe。
96
+
97
+ | 参数 | 类型 | 必填 | 说明 |
98
+ |------|------|------|------|
99
+ | `selector` | String | 否 | CSS 选择器(默认 `'iframe'`) |
100
+
101
+ **返回值**:`number` 成功注入的数量
102
+
103
+ ### setTheme(theme, options)
104
+
105
+ 切换主题,自动同步到主文档和所有 iframe。
106
+
107
+ | 参数 | 类型 | 必填 | 说明 |
108
+ |------|------|------|------|
109
+ | `theme` | String | 是 | `white`、`dark` |
110
+ | `options.primaryColor` | String | 否 | 同时设置主色调 |
111
+ | `options.brand` | String | 否 | 同时设置品牌色 |
112
+
113
+ ```javascript
114
+ const injector = createThemeInjector({ theme: 'white' })
115
+ injector.injectAll('iframe')
116
+
117
+ // 切换主题(自动同步主文档 + 所有 iframe)
118
+ injector.setTheme('dark')
119
+ ```
120
+
121
+ ### setPrimaryColor(color)
122
+
123
+ 设置主色调,自动同步到主文档和所有 iframe。
124
+
125
+ | 参数 | 类型 | 必填 | 说明 |
126
+ |------|------|------|------|
127
+ | `color` | String | 是 | 十六进制颜色值 |
128
+
129
+ ### setBrand(brand)
130
+
131
+ 设置品牌色,切换对应品牌的主色调。
132
+
133
+ | 参数 | 类型 | 必填 | 说明 |
134
+ |------|------|------|------|
135
+ | `brand` | String | 是 | `''`、`water`、`electricity`、`gas` |
136
+
137
+ **品牌色映射**:
138
+
139
+ | 品牌 | 亮色 | 暗色 |
140
+ |------|------|------|
141
+ | `water` | `#0077be` | `#0099cc` |
142
+ | `electricity` | `#2ecc71` | `#27ae60` |
143
+ | `gas` | `#f39c12` | `#e67e22` |
144
+
145
+ ### startObserving(target)
146
+
147
+ 开始自动监听 DOM 变化,自动注入新添加的 iframe。
148
+
149
+ | 参数 | 类型 | 必填 | 说明 |
150
+ |------|------|------|------|
151
+ | `target` | HTMLElement | 否 | 监听容器(默认 `document.body`) |
152
+
153
+ ### stopObserving()
154
+
155
+ 停止自动监听。
156
+
157
+ ### remove(iframe)
158
+
159
+ 移除指定 iframe 的注入。
160
+
161
+ ### removeAll()
162
+
163
+ 移除所有 iframe 的注入。
164
+
165
+ ### destroy()
166
+
167
+ 销毁实例,清理所有资源。
168
+
169
+ ## 使用示例
170
+
171
+ ### 基本用法
172
+
173
+ ```javascript
174
+ import { createThemeInjector } from 'xt-element-ui'
175
+
176
+ // 创建注入器
177
+ const injector = createThemeInjector({ theme: 'white' })
178
+
179
+ // 注入现有 iframe
180
+ injector.injectAll('iframe')
181
+
182
+ // 切换主题
183
+ injector.setTheme('dark')
184
+
185
+ // 设置品牌色
186
+ injector.setBrand('water')
187
+
188
+ // 销毁
189
+ injector.destroy()
190
+ ```
191
+
192
+ ### 与全局主题配置联动
193
+
194
+ ```javascript
195
+ import { setTheme, onConfigChange } from 'xt-element-ui'
196
+ import { createThemeInjector } from 'xt-element-ui'
197
+
198
+ // 1. 创建注入器
199
+ const injector = createThemeInjector({ theme: 'white' })
200
+
201
+ // 2. 注入 iframe
202
+ injector.injectAll('iframe')
203
+
204
+ // 3. 监听全局主题变化(保持同步)
205
+ const unsubscribe = onConfigChange((key, value) => {
206
+ if (key === 'theme') {
207
+ console.log('主题变更:', value)
208
+ }
209
+ })
210
+
211
+ // 4. 通过全局 API 切换主题(自动同步到 iframe)
212
+ setTheme('dark')
213
+ ```
214
+
215
+ ### 自动监听新增 iframe
216
+
217
+ ```javascript
218
+ const injector = createThemeInjector({ theme: 'white' })
219
+ injector.startObserving() // 自动监听 DOM
220
+
221
+ // 动态添加的 iframe 会自动被注入主题
222
+ const newIframe = document.createElement('iframe')
223
+ document.body.appendChild(newIframe) // 自动注入
224
+
225
+ // 清理
226
+ injector.stopObserving()
227
+ ```
228
+
229
+ ### 持久化配置
230
+
231
+ ```javascript
232
+ // 创建时启用持久化
233
+ const injector = createThemeInjector({
234
+ theme: 'white',
235
+ persist: true // 保存到 localStorage
236
+ })
237
+
238
+ // 下次加载时自动恢复
239
+ // localStorage 中的配置会自动应用
240
+ ```
241
+
242
+ ## 注意事项
243
+
244
+ 1. **跨域限制**:跨域 iframe 无法访问,将输出警告日志
245
+ 2. **加载时机**:iframe 必须加载完成后才能注入(注入器会自动等待 `load` 事件)
246
+ 3. **CSS 内联**:推荐使用 `createThemeInjector()`,CSS 已内联无需额外配置
247
+ 4. **主题同步**:通过 `onConfigChange` 实现主文档和 iframe 的主题自动同步
248
+ 5. **性能**:大量 iframe 场景建议使用 `startObserving` 自动管理,避免手动注入遗漏
@@ -164,7 +164,7 @@ export default {
164
164
 
165
165
  ### 虚拟滚动
166
166
 
167
- 大数据量场景下启用虚拟滚动,仅渲染可见区域的卡片。
167
+ 大数据量场景下启用虚拟滚动,仅渲染可见区域的卡片。组件内部使用 `XtScroll`(原生滚动容器)作为滚动容器,提供流畅的滚动体验。
168
168
 
169
169
  ::: demo 虚拟滚动
170
170
  ```vue
@@ -1,4 +1,4 @@
1
- 滚动箭头组件用于在内容溢出时显示滚动箭头,支持水平和垂直方向的滚动。
1
+ 滚动箭头组件用于在内容溢出时显示滚动箭头,支持水平和垂直方向的滚动。基于 `XtScroll` 封装,支持虚拟滚动模式处理海量数据。
2
2
 
3
3
  ## 基本用法
4
4
 
@@ -24,11 +24,27 @@
24
24
  | `autoHide` | Boolean | true | - | 是否自动隐藏箭头(滚动到边界时隐藏) |
25
25
  | `height` | String / Number | - | - | 容器高度 |
26
26
  | `width` | String / Number | - | - | 容器宽度 |
27
+ | `v-scroll` | Boolean | false | - | 是否启用虚拟滚动 |
28
+ | `v-scroll-data` | Array | [] | - | 虚拟滚动数据源 |
29
+ | `item-size` | Number | 50 | - | 每个 item 的固定尺寸(px) |
30
+ | `key-field` | String | 'id' | - | item 的唯一键字段名 |
31
+ | `buffer-size` | Number | 5 | - | 预渲染缓冲区大小 |
32
+ | `v-scroll-loading` | Boolean | false | - | 虚拟滚动加载状态 |
33
+ | `load-more` | Boolean | false | - | 是否启用加载更多 |
34
+ | `load-more-text` | String | '加载更多' | - | 加载更多按钮文字 |
35
+ | `load-more-loading` | Boolean | false | - | 加载更多按钮加载状态 |
36
+
37
+ ## 插槽说明
38
+ | 插槽名 | 作用域 | 说明 |
39
+ |--------|--------|------|
40
+ | `default` | — | 非虚拟滚动模式下的默认内容 |
41
+ | `vitem` | `{ item, index }` | 虚拟滚动模式下每个 item 的渲染内容 |
27
42
 
28
43
  ## 事件说明
29
44
  | 事件名称 | 说明 | 参数 |
30
45
  |----------|------|------|
31
46
  | `scroll` | 滚动时触发 | `scrollContainer` - 滚动容器元素 |
47
+ | `load-more` | 触发加载更多 | — |
32
48
 
33
49
  ## 示例
34
50
 
@@ -153,4 +169,74 @@ export default {
153
169
  </XtScrollArrow>
154
170
  </template>
155
171
  ```
172
+ :::
173
+
174
+ ### 虚拟滚动(水平)
175
+
176
+ ::: demo 虚拟滚动(水平)—— 渲染 5000 条数据
177
+ ```vue
178
+ <template>
179
+ <XtScrollArrow
180
+ direction="horizontal"
181
+ :v-scroll="true"
182
+ :v-scroll-data="tagData"
183
+ :item-size="120"
184
+ >
185
+ <template #vitem="{ item }">
186
+ <div style="width: 100px; height: 40px; display: flex; align-items: center; justify-content: center; background: #ecf5ff; border-radius: 4px; margin: 0 4px; color: #409eff; font-size: 13px;">
187
+ {{ item.label }}
188
+ </div>
189
+ </template>
190
+ </XtScrollArrow>
191
+ </template>
192
+ <script>
193
+ export default {
194
+ data() {
195
+ return {
196
+ tagData: Array.from({ length: 5000 }, (_, i) => ({
197
+ id: i,
198
+ label: `标签 ${i + 1}`
199
+ }))
200
+ }
201
+ }
202
+ }
203
+ </script>
204
+ ```
205
+ :::
206
+
207
+ ### 虚拟滚动(垂直)
208
+
209
+ ::: demo 虚拟滚动(垂直)—— 渲染 5000 条数据
210
+ ```vue
211
+ <template>
212
+ <XtScrollArrow
213
+ direction="vertical"
214
+ :height="200"
215
+ :v-scroll="true"
216
+ :v-scroll-data="listData"
217
+ :item-size="48"
218
+ >
219
+ <template #vitem="{ item, index }">
220
+ <div style="height: 48px; display: flex; align-items: center; padding: 0 12px; border-bottom: 1px solid #ebeef5; gap: 8px;">
221
+ <span style="color: #909399; font-size: 12px;">{{ index + 1 }}</span>
222
+ <span>{{ item.name }}</span>
223
+ <span style="color: #909399; font-size: 12px; margin-left: auto;">{{ item.desc }}</span>
224
+ </div>
225
+ </template>
226
+ </XtScrollArrow>
227
+ </template>
228
+ <script>
229
+ export default {
230
+ data() {
231
+ return {
232
+ listData: Array.from({ length: 5000 }, (_, i) => ({
233
+ id: i,
234
+ name: `用户 ${i + 1}`,
235
+ desc: `部门 ${(i % 10) + 1}`
236
+ }))
237
+ }
238
+ }
239
+ }
240
+ </script>
241
+ ```
156
242
  :::
@@ -0,0 +1,237 @@
1
+ 原生实现的虚拟滚动容器组件,支持横向和纵向虚拟滚动,适用于大数据量列表的高性能渲染。不依赖 `el-scrollbar`,采用原生 CSS 滚动容器,更轻量灵活。
2
+
3
+ ### 基本用法
4
+
5
+ ::: demo 基本用法
6
+ ```vue
7
+ <template>
8
+ <XtScroll :style="{ height: '400px' }" :v-scroll="true" :data="items" :item-size="50" key-field="id">
9
+ <template #item="{ item, index }">
10
+ <div style="padding: 12px; border-bottom: 1px solid #eee;">
11
+ <strong>{{ index + 1 }}.</strong> {{ item.label }}
12
+ </div>
13
+ </template>
14
+ </XtScroll>
15
+ </template>
16
+
17
+ <script>
18
+ export default {
19
+ data() {
20
+ return {
21
+ items: Array.from({ length: 10000 }, (_, i) => ({ id: i, label: `数据项 ${i + 1}` }))
22
+ }
23
+ }
24
+ }
25
+ </script>
26
+ ```
27
+ :::
28
+
29
+ ### 纵向虚拟滚动
30
+
31
+ ::: demo 设置 `scroll-direction="vertical"`(默认值)启用纵向虚拟滚动。
32
+ ```vue
33
+ <template>
34
+ <XtScroll
35
+ :style="{ height: '300px' }"
36
+ :v-scroll="true"
37
+ :data="verticalData"
38
+ :item-size="40"
39
+ key-field="id"
40
+ scroll-direction="vertical"
41
+ >
42
+ <template #item="{ item }">
43
+ <div style="padding: 0 12px; line-height: 40px; height: 40px; border-bottom: 1px solid #ebeef5;">
44
+ {{ item.name }} - {{ item.email }}
45
+ </div>
46
+ </template>
47
+ </XtScroll>
48
+ </template>
49
+ <script>
50
+ export default {
51
+ data() {
52
+ return {
53
+ verticalData: Array.from({ length: 5000 }, (_, i) => ({
54
+ id: i,
55
+ name: `用户 ${i + 1}`,
56
+ email: `user${i + 1}@example.com`
57
+ }))
58
+ }
59
+ }
60
+ }
61
+ </script>
62
+ ```
63
+ :::
64
+
65
+ ### 横向虚拟滚动
66
+
67
+ ::: demo 设置 `scroll-direction="horizontal"` 启用横向虚拟滚动,适用于超宽表格、时间轴等场景。
68
+ ```vue
69
+ <template>
70
+ <XtScroll
71
+ :style="{ width: '600px', height: '80px' }"
72
+ :v-scroll="true"
73
+ :data="horizontalData"
74
+ :item-size="120"
75
+ scroll-direction="horizontal"
76
+ >
77
+ <template #item="{ item, index }">
78
+ <div style="width: 120px; height: 80px; display: inline-flex; align-items: center; justify-content: center; background: #f0f2f5; margin-right: 4px; border-radius: 4px;">
79
+ <span>{{ item }}</span>
80
+ </div>
81
+ </template>
82
+ </XtScroll>
83
+ </template>
84
+ <script>
85
+ export default {
86
+ data() {
87
+ return {
88
+ horizontalData: Array.from({ length: 1000 }, (_, i) => `标签 ${i + 1}`)
89
+ }
90
+ }
91
+ }
92
+ </script>
93
+ ```
94
+ :::
95
+
96
+ ### 非虚拟滚动模式
97
+
98
+ ::: demo `vScroll` 为 false 时,使用默认插槽正常渲染,原生滚动条提供流畅的滚动体验。
99
+ ```vue
100
+ <template>
101
+ <XtScroll :style="{ height: '200px' }">
102
+ <div v-for="i in 20" :key="i" style="padding: 8px; border-bottom: 1px solid #eee;">
103
+ 内容行 {{ i }} - 原生滚动条
104
+ </div>
105
+ </XtScroll>
106
+ </template>
107
+ ```
108
+ :::
109
+
110
+ ### 配合 XtList 使用
111
+
112
+ ::: demo XtList 内置了 XtScroll,开启 `virtual-scroll` 即可启用虚拟滚动。
113
+ ```vue
114
+ <template>
115
+ <XtList
116
+ :data="listData"
117
+ :columns="2"
118
+ :virtual-scroll="true"
119
+ :item-height="160"
120
+ :height="400"
121
+ title="订单列表(虚拟滚动)"
122
+ />
123
+ </template>
124
+ <script>
125
+ export default {
126
+ data() {
127
+ return {
128
+ listData: Array.from({ length: 5000 }, (_, i) => ({
129
+ title: `订单 #${i + 1}`,
130
+ subtitle: `2024-${String(Math.ceil((i + 1) / 30)).padStart(2, '0')}-${String((i % 28) + 1).padStart(2, '0')}`,
131
+ content: `金额: ¥${(Math.random() * 1000).toFixed(2)}`,
132
+ footer: i % 3 === 0 ? '已完成' : i % 3 === 1 ? '待发货' : '已取消'
133
+ }))
134
+ }
135
+ }
136
+ }
137
+ </script>
138
+ ```
139
+ :::
140
+
141
+ ### 配合 XtScrollArrow 使用
142
+
143
+ ::: demo XtScrollArrow 内置了 XtScroll,开启虚拟滚动后支持海量数据带箭头导航。
144
+ ```vue
145
+ <template>
146
+ <XtScrollArrow
147
+ direction="horizontal"
148
+ :v-scroll="true"
149
+ :v-scroll-data="arrowData"
150
+ :item-size="120"
151
+ >
152
+ <template #vitem="{ item }">
153
+ <div style="width: 100px; height: 40px; display: flex; align-items: center; justify-content: center; background: #ecf5ff; border-radius: 4px; margin: 0 4px;">
154
+ {{ item.label }}
155
+ </div>
156
+ </template>
157
+ </XtScrollArrow>
158
+ </template>
159
+ <script>
160
+ export default {
161
+ data() {
162
+ return {
163
+ arrowData: Array.from({ length: 200 }, (_, i) => ({ id: i, label: `标签 ${i + 1}` }))
164
+ }
165
+ }
166
+ }
167
+ </script>
168
+ ```
169
+ :::
170
+
171
+ ### Attributes
172
+
173
+ | 参数 | 说明 | 类型 | 默认值 |
174
+ |------|------|------|--------|
175
+ | v-scroll | 是否启用虚拟滚动 | boolean | false |
176
+ | data | 虚拟滚动数据源 | array | [] |
177
+ | item-size | 每个 item 的固定尺寸(px),纵向为高度,横向为宽度 | number | 50 |
178
+ | key-field | item 的唯一键字段名 | string | 'id' |
179
+ | buffer-size | 预渲染缓冲区大小(item 数量) | number | 5 |
180
+ | scroll-direction | 虚拟滚动方向 | 'vertical' \| 'horizontal' | 'vertical' |
181
+ | item-class-name | item 的自定义 CSS 类名 | string | '' |
182
+ | height | 容器高度 | number \| string | '' |
183
+ | max-height | 容器最大高度 | number \| string | '' |
184
+ | width | 容器宽度 | number \| string | '' |
185
+ | max-width | 容器最大宽度 | number \| string | '' |
186
+ | loading | 加载状态 | boolean | false |
187
+ | empty-text | 空数据提示文字 | string | '暂无数据' |
188
+ | load-more | 是否启用加载更多 | boolean | false |
189
+ | load-more-text | 加载更多按钮文字 | string | '加载更多' |
190
+ | load-more-loading | 加载更多按钮加载状态 | boolean | false |
191
+
192
+ ### Slots
193
+
194
+ | 名称 | 说明 | 作用域 |
195
+ |------|------|--------|
196
+ | default | 非虚拟滚动模式下的默认内容 | — |
197
+ | item | 虚拟滚动模式下每个 item 的渲染内容 | `{ item, index }` |
198
+ | empty | 空数据时的自定义内容 | — |
199
+ | loading | 加载中的自定义内容 | — |
200
+
201
+ ### Events
202
+
203
+ | 事件名 | 说明 | 回调参数 |
204
+ |--------|------|----------|
205
+ | scroll | 滚动事件 | `{ scrollTop, scrollLeft }` |
206
+ | load-more | 触发加载更多 | — |
207
+
208
+ ### Methods
209
+
210
+ | 方法名 | 说明 | 参数 |
211
+ |--------|------|------|
212
+ | scrollTo(pos) | 滚动到指定位置 | `pos: number` |
213
+ | scrollToItem(index) | 滚动到指定索引的 item | `index: number` |
214
+ | scrollToStart() | 滚动到顶部/左侧 | — |
215
+ | scrollToEnd() | 滚动到底部/右侧 | — |
216
+ | getScrollPos() | 获取当前滚动位置 | — |
217
+ | getScrollContainer() | 获取原生滚动容器 DOM 元素 | — |
218
+
219
+ ### XtScrollArrow 新增属性
220
+
221
+ | 参数 | 说明 | 类型 | 默认值 |
222
+ |------|------|------|--------|
223
+ | v-scroll | 是否启用虚拟滚动 | boolean | false |
224
+ | v-scroll-data | 虚拟滚动数据源 | array | [] |
225
+ | item-size | 每个 item 的固定尺寸(px) | number | 50 |
226
+ | key-field | item 的唯一键字段名 | string | 'id' |
227
+ | buffer-size | 预渲染缓冲区大小 | number | 5 |
228
+ | v-scroll-loading | 虚拟滚动加载状态 | boolean | false |
229
+ | load-more | 是否启用加载更多 | boolean | false |
230
+ | load-more-text | 加载更多按钮文字 | string | '加载更多' |
231
+ | load-more-loading | 加载更多按钮加载状态 | boolean | false |
232
+
233
+ ### XtScrollArrow 新增 Slot
234
+
235
+ | 名称 | 说明 | 作用域 |
236
+ |------|------|--------|
237
+ | vitem | 虚拟滚动模式下每个 item 的渲染内容 | `{ item, index }` |
@@ -80,12 +80,25 @@ export default {
80
80
 
81
81
  ### setPrimaryColor(color)
82
82
 
83
- 设置全局主色调。
83
+ 设置全局主色调,同时更新 `--el-color-primary*`(Element UI)和 `--xt-color-primary*`(xt 组件)两套 CSS 变量。
84
84
 
85
85
  | 参数 | 类型 | 必填 | 说明 |
86
86
  |------|------|------|------|
87
87
  | `color` | String | 是 | 十六进制颜色值 |
88
88
 
89
+ **自动衍生变量**:设置主色后会自动生成以下 Element UI 变量:
90
+
91
+ | 变量 | 说明 |
92
+ |------|------|
93
+ | `--el-color-primary` | 主色 |
94
+ | `--el-color-primary-light-3` | 主色 +30% 亮度 |
95
+ | `--el-color-primary-light-5` | 主色 +50% 亮度 |
96
+ | `--el-color-primary-light-7` | 主色 +70% 亮度 |
97
+ | `--el-color-primary-light-8` | 主色 +80% 亮度 |
98
+ | `--el-color-primary-light-9` | 主色 +90% 亮度 |
99
+ | `--el-color-primary-dark-2` | 主色 -20% 亮度 |
100
+ | `--el-color-primary-rgb` | 主色 RGB 值 |
101
+
89
102
  ```vue
90
103
  <template>
91
104
  <div>
@@ -280,6 +293,7 @@ export default {
280
293
  ## 注意事项
281
294
 
282
295
  1. `setPrimaryColor` 只支持十六进制颜色格式(如 `#1890ff`、`#fff`)
283
- 2. 设置主色调时,会自动生成对应的浅色系列(light-3 到 light-9)
284
- 3. `onConfigChange` 返回的取消订阅函数应在组件销毁时调用,避免内存泄漏
285
- 4. 所有配置修改都会触发 `onConfigChange` 监听器
296
+ 2. 设置主色调时,会自动生成对应的浅色系列(light-3 到 light-9)和暗色系列(dark-2
297
+ 3. `setPrimaryColor` 会**同时设置** `--el-*`(Element UI)和 `--xt-*`(xt 组件)两套变量
298
+ 4. `onConfigChange` 返回的取消订阅函数应在组件销毁时调用,避免内存泄漏
299
+ 5. 所有配置修改都会触发 `onConfigChange` 监听器