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.
- package/README.md +140 -192
- package/docs/README.md +162 -88
- package/docs/components/base/theme.md +248 -0
- package/docs/components/base/xt-list.md +1 -1
- package/docs/components/base/xt-scroll-arrow.md +87 -1
- package/docs/components/base/xt-scroll.md +237 -0
- package/docs/components/utils/config.md +18 -4
- package/docs/components/utils/theme.md +280 -183
- package/lib/index.common.1.js +4 -26
- package/lib/index.common.2.js +1 -1
- package/lib/index.common.js +1871 -671
- package/lib/index.css +1 -1
- package/lib/index.umd.1.js +4 -26
- package/lib/index.umd.2.js +1 -1
- package/lib/index.umd.js +1871 -671
- package/lib/index.umd.min.1.js +1 -1
- package/lib/index.umd.min.js +1 -1
- package/lib/theme/element-overrides.css +607 -0
- package/lib/theme/element-vars.css +280 -0
- package/lib/xt-badge/xt-badge.common.js +1 -1
- package/lib/xt-badge/xt-badge.umd.js +1 -1
- package/lib/xt-button/xt-button.common.js +1 -1
- package/lib/xt-button/xt-button.umd.js +1 -1
- package/lib/xt-card/xt-card.common.js +1 -1
- package/lib/xt-card/xt-card.umd.js +1 -1
- package/lib/xt-card-item/xt-card-item.common.js +1 -1
- package/lib/xt-card-item/xt-card-item.umd.js +1 -1
- package/lib/xt-chart/xt-chart.common.js +5 -5
- package/lib/xt-chart/xt-chart.umd.js +5 -5
- package/lib/xt-config-provider/xt-config-provider.css +1 -1
- package/lib/xt-date-picker/xt-date-picker.common.1.js +4 -26
- package/lib/xt-date-picker/xt-date-picker.common.2.js +1 -1
- package/lib/xt-date-picker/xt-date-picker.common.js +1 -47
- package/lib/xt-date-picker/xt-date-picker.css +1 -1
- package/lib/xt-date-picker/xt-date-picker.umd.1.js +4 -26
- package/lib/xt-date-picker/xt-date-picker.umd.2.js +1 -1
- package/lib/xt-date-picker/xt-date-picker.umd.js +1 -47
- package/lib/xt-date-picker/xt-date-picker.umd.min.1.js +1 -1
- package/lib/xt-date-picker/xt-date-picker.umd.min.js +1 -1
- package/lib/xt-flex-box/xt-flex-box.common.js +1 -1
- package/lib/xt-flex-box/xt-flex-box.umd.js +1 -1
- package/lib/xt-flow/xt-flow.common.js +1 -1
- package/lib/xt-flow/xt-flow.umd.js +1 -1
- package/lib/xt-form-schema/xt-form-schema.common.js +1 -1
- package/lib/xt-form-schema/xt-form-schema.umd.js +1 -1
- package/lib/xt-grid-box/xt-grid-box.common.js +1 -1
- package/lib/xt-grid-box/xt-grid-box.umd.js +1 -1
- package/lib/xt-grid-item/xt-grid-item.common.js +1 -1
- package/lib/xt-grid-item/xt-grid-item.umd.js +1 -1
- package/lib/xt-icon/xt-icon.common.js +1 -1
- package/lib/xt-icon/xt-icon.umd.js +1 -1
- package/lib/xt-input/xt-input.common.js +1 -1
- package/lib/xt-input/xt-input.umd.js +1 -1
- package/lib/xt-list/xt-list.common.js +457 -118
- package/lib/xt-list/xt-list.css +1 -1
- package/lib/xt-list/xt-list.umd.js +457 -118
- package/lib/xt-list/xt-list.umd.min.js +1 -1
- package/lib/xt-map/xt-map.common.js +1 -1
- package/lib/xt-map/xt-map.umd.js +1 -1
- package/lib/xt-map-provider/xt-map-provider.common.js +1 -1
- package/lib/xt-map-provider/xt-map-provider.umd.js +1 -1
- package/lib/xt-page/xt-page.common.js +1 -1
- package/lib/xt-page/xt-page.umd.js +1 -1
- package/lib/xt-progress/xt-progress.common.js +1 -1
- package/lib/xt-progress/xt-progress.umd.js +1 -1
- package/lib/xt-scroll/demo.html +10 -0
- package/lib/xt-scroll/index.js +1 -0
- package/lib/xt-scroll/xt-scroll.common.js +551 -0
- package/lib/xt-scroll/xt-scroll.css +1 -0
- package/lib/xt-scroll/xt-scroll.umd.js +561 -0
- package/lib/xt-scroll/xt-scroll.umd.min.js +1 -0
- package/lib/xt-scroll-arrow/xt-scroll-arrow.common.js +591 -170
- package/lib/xt-scroll-arrow/xt-scroll-arrow.css +1 -1
- package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.js +591 -170
- package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.min.js +1 -1
- package/lib/xt-select-tree/xt-select-tree.common.js +1 -1
- package/lib/xt-select-tree/xt-select-tree.umd.js +1 -1
- package/lib/xt-step-price/xt-step-price.common.js +2 -2
- package/lib/xt-step-price/xt-step-price.umd.js +2 -2
- package/lib/xt-step-price-item/xt-step-price-item.common.js +1 -1
- package/lib/xt-step-price-item/xt-step-price-item.umd.js +1 -1
- package/lib/xt-tab-pane/xt-tab-pane.common.js +1 -1
- package/lib/xt-tab-pane/xt-tab-pane.umd.js +1 -1
- package/lib/xt-table/xt-table.common.js +2 -2
- package/lib/xt-table/xt-table.umd.js +2 -2
- package/lib/xt-tabs/xt-tabs.common.js +1 -1
- package/lib/xt-tabs/xt-tabs.umd.js +1 -1
- package/lib/xt-text/xt-text.common.js +1 -1
- package/lib/xt-text/xt-text.umd.js +1 -1
- package/lib/xt-time/xt-time.common.js +1 -1
- package/lib/xt-time/xt-time.umd.js +1 -1
- package/lib/xt-transfer-tree/xt-transfer-tree.common.js +1 -1
- package/lib/xt-transfer-tree/xt-transfer-tree.umd.js +1 -1
- package/lib/xt-upload/xt-upload.common.js +2 -2
- package/lib/xt-upload/xt-upload.umd.js +2 -2
- package/package.json +5 -3
- package/src/components/index.scss +3 -0
- package/src/components/theme/element-overrides.css +607 -0
- package/src/components/theme/element-vars.css +280 -0
- package/src/components/theme/iframe-injector.js +502 -0
- package/src/components/theme/index.js +64 -0
- package/src/components/xt-config-provider/style/index.scss +0 -11
- package/src/components/xt-date-picker/component/RangeDate.vue +1 -29
- package/src/components/xt-date-picker/style/index.scss +80 -53
- package/src/components/xt-list/index.vue +23 -12
- package/src/components/xt-scroll/index.js +9 -0
- package/src/components/xt-scroll/index.vue +363 -0
- package/src/components/xt-scroll/style/index.scss +107 -0
- package/src/components/xt-scroll-arrow/index.vue +200 -83
- package/src/components/xt-scroll-arrow/style/index.scss +16 -5
- package/src/index.js +9 -2
- package/src/utils/color.js +105 -0
- package/src/utils/index.js +456 -468
- package/src/utils/theme-vars.js +134 -0
- package/lib/css/1.87a493be.css +0 -1
- 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` 自动管理,避免手动注入遗漏
|
|
@@ -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. `
|
|
285
|
-
4.
|
|
296
|
+
2. 设置主色调时,会自动生成对应的浅色系列(light-3 到 light-9)和暗色系列(dark-2)
|
|
297
|
+
3. `setPrimaryColor` 会**同时设置** `--el-*`(Element UI)和 `--xt-*`(xt 组件)两套变量
|
|
298
|
+
4. `onConfigChange` 返回的取消订阅函数应在组件销毁时调用,避免内存泄漏
|
|
299
|
+
5. 所有配置修改都会触发 `onConfigChange` 监听器
|