npmapps 1.0.2 → 1.0.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 +3 -1
- package/app/EllTable/README.md +70 -0
- package/app/EllTable/index.js +218 -0
- package/package.json +12 -12
- package/app/v-fullScreen.browser.txt +0 -114
package/README.md
CHANGED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# EllTable 组件
|
|
2
|
+
|
|
3
|
+
基于 Element UI Table 组件扩展的表格组件,支持鼠标横向滚动和提示功能。
|
|
4
|
+
|
|
5
|
+
## 功能特点
|
|
6
|
+
|
|
7
|
+
- 支持鼠标横向滚动(按住 Alt 键)
|
|
8
|
+
- 自动检测表格是否需要横向滚动
|
|
9
|
+
- 可配置的提示信息和位置
|
|
10
|
+
- 继承 Element UI Table 的所有功能和属性
|
|
11
|
+
|
|
12
|
+
## 属性配置
|
|
13
|
+
|
|
14
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
15
|
+
|--------|------|---------|------|
|
|
16
|
+
| disableMouseHorizontalWheel | Boolean | false | 是否禁用鼠标横向滚动功能 |
|
|
17
|
+
| hiddenMouseWheel | Boolean | false | 是否隐藏鼠标滚动提示 |
|
|
18
|
+
| showTooltip | Boolean | false | 是否显示提示信息 |
|
|
19
|
+
| tooltipContent | String/Array | [] | 提示信息内容,可以是字符串或字符串数组 |
|
|
20
|
+
| tooltipPosition | Object | { top: "10px", left: "10px" } | 提示信息位置,支持 top、left、bottom、right |
|
|
21
|
+
|
|
22
|
+
## 使用示例
|
|
23
|
+
|
|
24
|
+
```vue
|
|
25
|
+
<template>
|
|
26
|
+
<ell-table
|
|
27
|
+
:data="tableData"
|
|
28
|
+
border
|
|
29
|
+
style="width: 100%"
|
|
30
|
+
height="300"
|
|
31
|
+
:tooltip-content="['按住Alt键可以横向滚动表格', '自定义提示信息']"
|
|
32
|
+
:show-tooltip="true"
|
|
33
|
+
:tooltip-position="{ top: '20px', right: '20px' }"
|
|
34
|
+
>
|
|
35
|
+
<el-table-column prop="date" label="日期" width="180" fixed="left"></el-table-column>
|
|
36
|
+
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
|
|
37
|
+
<el-table-column prop="address" label="地址" width="300"></el-table-column>
|
|
38
|
+
<!-- 更多列... -->
|
|
39
|
+
</ell-table>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script>
|
|
43
|
+
export default {
|
|
44
|
+
data() {
|
|
45
|
+
return {
|
|
46
|
+
tableData: [{
|
|
47
|
+
date: '2023-01-01',
|
|
48
|
+
name: '张三',
|
|
49
|
+
address: '北京市朝阳区'
|
|
50
|
+
}]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 注意事项
|
|
58
|
+
|
|
59
|
+
1. 组件会自动检测表格是否同时存在横向和纵向滚动条,如果存在则显示提示信息
|
|
60
|
+
2. 可以通过 `disableMouseHorizontalWheel` 属性禁用鼠标横向滚动功能
|
|
61
|
+
3. 提示信息位置可以通过 `tooltipPosition` 属性灵活配置
|
|
62
|
+
4. 组件完全兼容 Element UI Table 的所有功能,可以正常使用 Table 组件的所有属性和方法
|
|
63
|
+
|
|
64
|
+
## 建议功能扩展
|
|
65
|
+
|
|
66
|
+
1. 支持自定义滚动速度
|
|
67
|
+
2. 添加滚动方向锁定功能
|
|
68
|
+
3. 提供滚动事件回调
|
|
69
|
+
4. 支持 tooltip 主题定制
|
|
70
|
+
5. 添加更多交互效果(如双击切换滚动方向、滚动到边缘时的视觉反馈等)
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { Table } from "element-ui";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @description 扩展Element UI Table组件,支持鼠标横向滚动和提示功能
|
|
5
|
+
* @extends {Table}
|
|
6
|
+
*/
|
|
7
|
+
export const tableMouseHorizontalWheel = {
|
|
8
|
+
extends: Table,
|
|
9
|
+
data() {
|
|
10
|
+
return {
|
|
11
|
+
tooltipContentList: [],
|
|
12
|
+
tooltipVisible: this.showTooltip,
|
|
13
|
+
scrollDirection: 'vertical', // 默认为垂直滚动
|
|
14
|
+
isScrollingToEdge: false, // 是否滚动到边缘
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
props: {
|
|
18
|
+
/** @prop {Boolean} [disableMouseHorizontalWheel=false] - 是否禁用鼠标横向滚动功能 */
|
|
19
|
+
disableMouseHorizontalWheel: {
|
|
20
|
+
type: Boolean,
|
|
21
|
+
default: false,
|
|
22
|
+
},
|
|
23
|
+
/** @prop {Boolean} [hiddenMouseWheel=false] - 是否隐藏鼠标滚动提示 */
|
|
24
|
+
hiddenMouseWheel: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
default: false,
|
|
27
|
+
},
|
|
28
|
+
/** @prop {Boolean} [showTooltip=false] - 是否显示提示信息 */
|
|
29
|
+
showTooltip: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: false,
|
|
32
|
+
},
|
|
33
|
+
/** @prop {String|Array} [tooltipContent=[]] - 提示信息内容 */
|
|
34
|
+
tooltipContent: {
|
|
35
|
+
type: [String, Array],
|
|
36
|
+
default: () => [],
|
|
37
|
+
},
|
|
38
|
+
/** @prop {Object} [tooltipPosition={ top: "10px", left: "10px" }] - 提示信息位置 */
|
|
39
|
+
tooltipPosition: {
|
|
40
|
+
type: Object,
|
|
41
|
+
default: () => ({
|
|
42
|
+
top: "10px",
|
|
43
|
+
left: "10px",
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
created() {
|
|
48
|
+
// 初始化提示信息列表
|
|
49
|
+
if (Array.isArray(this.tooltipContent)) {
|
|
50
|
+
this.tooltipContentList.push(...this.tooltipContent);
|
|
51
|
+
} else {
|
|
52
|
+
this.tooltipContentList.push(this.tooltipContent);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
mounted() {
|
|
57
|
+
const newHasScrollbarByMff = _.debounce(this.hasScrollbarByMff, 10);
|
|
58
|
+
// 监听this.$el元素变化
|
|
59
|
+
const observer = new MutationObserver((mutations) => {
|
|
60
|
+
mutations.forEach((mutation) => {
|
|
61
|
+
if (mutation.type === "childList") {
|
|
62
|
+
newHasScrollbarByMff();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
observer.observe(this.$el, {
|
|
67
|
+
childList: true,
|
|
68
|
+
subtree: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (!this.disableMouseHorizontalWheel) {
|
|
72
|
+
this.$el.addEventListener("wheel", this.handleWheel);
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
beforeDestroy() {
|
|
77
|
+
if (!this.disableMouseHorizontalWheel) {
|
|
78
|
+
this.$el.removeEventListener("wheel", this.handleWheel);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
methods: {
|
|
82
|
+
/**
|
|
83
|
+
* @description 处理鼠标滚轮事件,实现横向滚动
|
|
84
|
+
* @param {WheelEvent} event - 鼠标滚轮事件对象
|
|
85
|
+
*/
|
|
86
|
+
handleWheel(event) {
|
|
87
|
+
const tableBody = this.$el.querySelector(".el-table__body-wrapper");
|
|
88
|
+
|
|
89
|
+
if (this.scrollDirection === 'horizontal' || event.altKey) {
|
|
90
|
+
event.preventDefault();
|
|
91
|
+
tableBody.scrollLeft += event.deltaY;
|
|
92
|
+
|
|
93
|
+
// 检查是否滚动到边缘
|
|
94
|
+
if (tableBody.scrollLeft <= 0 || tableBody.scrollLeft >= (tableBody.scrollWidth - tableBody.clientWidth)) {
|
|
95
|
+
this.showEdgeFeedback(tableBody);
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
// 检查垂直滚动是否到达边缘
|
|
99
|
+
if (tableBody.scrollTop <= 0 || tableBody.scrollTop >= (tableBody.scrollHeight - tableBody.clientHeight)) {
|
|
100
|
+
this.showEdgeFeedback(tableBody);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
/**
|
|
105
|
+
* @description 检测表格是否同时存在横向和纵向滚动条,并显示提示信息
|
|
106
|
+
*/
|
|
107
|
+
/**
|
|
108
|
+
* @description 切换滚动方向
|
|
109
|
+
*/
|
|
110
|
+
toggleScrollDirection() {
|
|
111
|
+
this.scrollDirection = this.scrollDirection === 'vertical' ? 'horizontal' : 'vertical';
|
|
112
|
+
this.tooltipContentList = this.tooltipContentList.filter(item => !item.includes('当前滚动方向'));
|
|
113
|
+
this.tooltipContentList.push(`当前滚动方向: ${this.scrollDirection === 'vertical' ? '垂直' : '水平'}`);
|
|
114
|
+
// 消息提醒
|
|
115
|
+
this.$message({
|
|
116
|
+
message: `当前表格滚动方向已切换为: ${this.scrollDirection ==='vertical'? '垂直' : '水平'}`,
|
|
117
|
+
type: 'info',
|
|
118
|
+
duration: 1000,
|
|
119
|
+
})
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @description 显示边缘视觉反馈
|
|
124
|
+
* @param {HTMLElement} element - 需要添加视觉反馈的元素
|
|
125
|
+
*/
|
|
126
|
+
showEdgeFeedback(element) {
|
|
127
|
+
if (!this.isScrollingToEdge) {
|
|
128
|
+
this.isScrollingToEdge = true;
|
|
129
|
+
element.style.transition = 'background-color 0.3s';
|
|
130
|
+
element.style.backgroundColor = 'rgba(0, 0, 0, 0.1)';
|
|
131
|
+
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
element.style.backgroundColor = '';
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
element.style.transition = '';
|
|
136
|
+
this.isScrollingToEdge = false;
|
|
137
|
+
}, 300);
|
|
138
|
+
}, 300);
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
hasScrollbarByMff() {
|
|
143
|
+
console.log(123);
|
|
144
|
+
|
|
145
|
+
const tableBody = this.$el.querySelector(".el-table__body-wrapper");
|
|
146
|
+
// 是否有竖向滚动条
|
|
147
|
+
const verticalScrollbarWidth =
|
|
148
|
+
tableBody.scrollHeight - tableBody.clientHeight;
|
|
149
|
+
console.log(tableBody.scrollHeight, tableBody.clientHeight,'1231321321',verticalScrollbarWidth);
|
|
150
|
+
|
|
151
|
+
// 是否有横向滚动条
|
|
152
|
+
const horizontalScrollbarHeight =
|
|
153
|
+
tableBody.scrollWidth - tableBody.clientWidth;
|
|
154
|
+
console.log(tableBody.scrollWidth, tableBody.clientWidth,'1231321321',horizontalScrollbarHeight);
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
// 如果有横向滚动条和竖向滚动条 hiddenMouseWheel 为false时 tooltipVisible 为true
|
|
159
|
+
if (
|
|
160
|
+
verticalScrollbarWidth > 0 &&
|
|
161
|
+
horizontalScrollbarHeight > 0 &&
|
|
162
|
+
!this.hiddenMouseWheel
|
|
163
|
+
) {
|
|
164
|
+
this.tooltipContentList.push("按住Alt键可以横向滚动表格");
|
|
165
|
+
this.tooltipVisible = true;
|
|
166
|
+
this.$el.addEventListener("dblclick", this.toggleScrollDirection);
|
|
167
|
+
this.tooltipContentList.push('双击表格任意位置可切换滚动方向')
|
|
168
|
+
}else{
|
|
169
|
+
this.tooltipContentList = this.tooltipContentList.filter(item =>!item.includes('按住Alt键可以横向滚动表格'));
|
|
170
|
+
this.tooltipContentList = this.tooltipContentList.filter(item =>!item.includes('双击表格任意位置可切换滚动方向'));
|
|
171
|
+
this.tooltipVisible = false;
|
|
172
|
+
console.log(1231321);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
render(h) {
|
|
178
|
+
const table = this.$options.extends.render.call(this, h);
|
|
179
|
+
return (
|
|
180
|
+
<div
|
|
181
|
+
style={{
|
|
182
|
+
position: "relative",
|
|
183
|
+
}}
|
|
184
|
+
>
|
|
185
|
+
<el-tooltip
|
|
186
|
+
placement="top"
|
|
187
|
+
style={{
|
|
188
|
+
position: "absolute",
|
|
189
|
+
...(this.tooltipPosition.top && { top: this.tooltipPosition.top }),
|
|
190
|
+
...(this.tooltipPosition.left && { left: this.tooltipPosition.left }),
|
|
191
|
+
...(this.tooltipPosition.bottom && { bottom: this.tooltipPosition.bottom }),
|
|
192
|
+
...(this.tooltipPosition.right && { right: this.tooltipPosition.right }),
|
|
193
|
+
zIndex: 11,
|
|
194
|
+
display: this.tooltipVisible ? "block" : "none",
|
|
195
|
+
}}
|
|
196
|
+
>
|
|
197
|
+
<div slot="content">
|
|
198
|
+
{this.tooltipContentList.map((item, index) => {
|
|
199
|
+
return (
|
|
200
|
+
<div key={index} style={{ marginBottom: "4px" }}>
|
|
201
|
+
<span>{index + 1}.</span> {item}
|
|
202
|
+
</div>
|
|
203
|
+
);
|
|
204
|
+
})}
|
|
205
|
+
</div>
|
|
206
|
+
<i
|
|
207
|
+
class="el-icon-info"
|
|
208
|
+
style={{
|
|
209
|
+
cursor: "pointer",
|
|
210
|
+
display: this.tooltipVisible ? "block" : "none",
|
|
211
|
+
}}
|
|
212
|
+
></i>
|
|
213
|
+
</el-tooltip>
|
|
214
|
+
{table}
|
|
215
|
+
</div>
|
|
216
|
+
);
|
|
217
|
+
},
|
|
218
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "npmapps",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [],
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"description": ""
|
|
12
|
+
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
bind(el, binding) {
|
|
3
|
-
el.style.position = 'relative';
|
|
4
|
-
let originalBgColor = window.getComputedStyle(el).backgroundColor || '#fff';
|
|
5
|
-
let isMaximized = false;
|
|
6
|
-
let originalStyles = {};
|
|
7
|
-
|
|
8
|
-
// 创建按钮
|
|
9
|
-
const btn = document.createElement('i');
|
|
10
|
-
btn.style.cssText = `
|
|
11
|
-
position: absolute;
|
|
12
|
-
top: 10px;
|
|
13
|
-
right: 10px;
|
|
14
|
-
cursor: pointer;
|
|
15
|
-
font-size: 20px;
|
|
16
|
-
color: #409EFF;
|
|
17
|
-
z-index: 1000;
|
|
18
|
-
`;
|
|
19
|
-
|
|
20
|
-
if (binding.modifiers.browser) {
|
|
21
|
-
// 浏览器内全屏模式
|
|
22
|
-
btn.className = 'el-icon-full-screen';
|
|
23
|
-
|
|
24
|
-
// 退出全屏的函数
|
|
25
|
-
const exitFullScreen = () => {
|
|
26
|
-
if (isMaximized) {
|
|
27
|
-
// 恢复原始样式
|
|
28
|
-
Object.assign(el.style, originalStyles);
|
|
29
|
-
btn.className = 'el-icon-full-screen';
|
|
30
|
-
isMaximized = false;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// 监听ESC键
|
|
35
|
-
document.addEventListener('keydown', (e) => {
|
|
36
|
-
if (e.key === 'Escape' && isMaximized) {
|
|
37
|
-
exitFullScreen();
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
btn.addEventListener('click', () => {
|
|
42
|
-
if (!isMaximized) {
|
|
43
|
-
ElementUI.Message.info('全屏模式下部分弹窗可能无法正常显示。');
|
|
44
|
-
|
|
45
|
-
// 保存原始样式
|
|
46
|
-
originalStyles = {
|
|
47
|
-
position: el.style.position,
|
|
48
|
-
top: el.style.top,
|
|
49
|
-
left: el.style.left,
|
|
50
|
-
width: el.style.width,
|
|
51
|
-
height: el.style.height,
|
|
52
|
-
zIndex: el.style.zIndex
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// 设置最大化样式
|
|
56
|
-
el.style.position = 'fixed';
|
|
57
|
-
el.style.top = '0';
|
|
58
|
-
el.style.left = '0';
|
|
59
|
-
el.style.width = '100%';
|
|
60
|
-
el.style.height = '100vh';
|
|
61
|
-
// 设置合适的z-index值,确保在el-dialog遮罩层(2000)之下
|
|
62
|
-
el.style.zIndex = '2000';
|
|
63
|
-
el.style.backgroundColor = originalBgColor;
|
|
64
|
-
|
|
65
|
-
btn.className = 'el-icon-close';
|
|
66
|
-
isMaximized = true;
|
|
67
|
-
} else {
|
|
68
|
-
exitFullScreen();
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
} else {
|
|
72
|
-
// 原生全屏模式
|
|
73
|
-
btn.className = 'el-icon-full-screen';
|
|
74
|
-
btn.addEventListener('click', () => {
|
|
75
|
-
if (!document.fullscreenElement) {
|
|
76
|
-
ElementUI.Message.info('全屏模式下部分弹窗可能无法正常显示。');
|
|
77
|
-
|
|
78
|
-
// 先设置页面全屏样式
|
|
79
|
-
el.style.position = 'fixed';
|
|
80
|
-
el.style.top = '0';
|
|
81
|
-
el.style.left = '0';
|
|
82
|
-
el.style.width = '100%';
|
|
83
|
-
el.style.height = '100vh';
|
|
84
|
-
el.style.zIndex = '2000';
|
|
85
|
-
el.style.backgroundColor = originalBgColor;
|
|
86
|
-
|
|
87
|
-
// 然后调用浏览器原生全屏
|
|
88
|
-
document.body.requestFullscreen();
|
|
89
|
-
btn.className = 'el-icon-close';
|
|
90
|
-
} else {
|
|
91
|
-
// 退出全屏时恢复样式
|
|
92
|
-
el.style.position = 'relative';
|
|
93
|
-
el.style.top = 'auto';
|
|
94
|
-
el.style.left = 'auto';
|
|
95
|
-
el.style.width = 'auto';
|
|
96
|
-
el.style.height = 'auto';
|
|
97
|
-
el.style.zIndex = 'auto';
|
|
98
|
-
document.exitFullscreen();
|
|
99
|
-
btn.className = 'el-icon-full-screen';
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// 监听全屏变化
|
|
104
|
-
document.addEventListener('fullscreenchange', () => {
|
|
105
|
-
if (!document.fullscreenElement) {
|
|
106
|
-
btn.className = 'el-icon-full-screen';
|
|
107
|
-
el.style.backgroundColor = originalBgColor;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
el.appendChild(btn);
|
|
113
|
-
}
|
|
114
|
-
}
|