rrj-astra-ui 1.1.3 → 1.1.5
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/components/AuiListItem.vue +39 -24
- package/package.json +1 -1
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
|
|
28
28
|
<script setup>
|
|
29
29
|
import { defineProps, ref, onMounted, onUnmounted } from 'vue';
|
|
30
|
+
const __name = 'AuiListItem'; // 保留__name,不删除
|
|
31
|
+
|
|
32
|
+
defineOptions({
|
|
33
|
+
name: __name
|
|
34
|
+
})
|
|
30
35
|
|
|
31
36
|
const props = defineProps({
|
|
32
37
|
text: {
|
|
@@ -51,24 +56,28 @@ const startX = ref(0);
|
|
|
51
56
|
const offsetX = ref(0);
|
|
52
57
|
const isSliding = ref(false);
|
|
53
58
|
const SLIDE_THRESHOLD = -50;
|
|
54
|
-
// 新增:获取组件 DOM 引用
|
|
55
59
|
const listItemRef = ref(null);
|
|
56
60
|
|
|
57
|
-
//
|
|
61
|
+
// 原有滑动逻辑优化:增加防止过度右滑
|
|
58
62
|
const onTouchStart = (e) => {
|
|
59
63
|
if (!props.allowSlide) return;
|
|
64
|
+
// 先收回其他可能展开的项(通过全局事件通知)
|
|
65
|
+
uni.$emit('auiListItem:resetAllSlide');
|
|
60
66
|
startX.value = e.touches[0].clientX;
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
// 保留当前已有偏移(如果已经展开,再次触摸不重置偏移)
|
|
68
|
+
const currentOffset = offsetX.value;
|
|
69
|
+
offsetX.value = currentOffset;
|
|
70
|
+
isSliding.value = currentOffset === -150;
|
|
63
71
|
};
|
|
64
72
|
|
|
65
73
|
const onTouchMove = (e) => {
|
|
66
74
|
if (!props.allowSlide) return;
|
|
67
75
|
const currentX = e.touches[0].clientX;
|
|
68
76
|
const diffX = currentX - startX.value;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
// 只允许左滑(diffX < 0),且偏移不小于-150(最大左滑距离)
|
|
78
|
+
if (diffX < 0 && (offsetX.value + diffX) >= -150) {
|
|
79
|
+
offsetX.value = diffX + (isSliding.value ? -150 : 0);
|
|
80
|
+
if (offsetX.value < SLIDE_THRESHOLD) {
|
|
72
81
|
isSliding.value = true;
|
|
73
82
|
}
|
|
74
83
|
}
|
|
@@ -77,60 +86,67 @@ const onTouchMove = (e) => {
|
|
|
77
86
|
const onTouchEnd = () => {
|
|
78
87
|
if (!props.allowSlide) return;
|
|
79
88
|
if (offsetX.value < SLIDE_THRESHOLD) {
|
|
89
|
+
// 展开:固定偏移到-150
|
|
80
90
|
offsetX.value = -150;
|
|
91
|
+
isSliding.value = true;
|
|
81
92
|
} else {
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
// 收回:重置偏移和状态
|
|
94
|
+
resetSlide();
|
|
84
95
|
}
|
|
85
96
|
};
|
|
86
97
|
|
|
87
|
-
//
|
|
98
|
+
// 核心:收回当前项的滑动状态
|
|
88
99
|
const resetSlide = () => {
|
|
89
|
-
if (!props.allowSlide
|
|
100
|
+
if (!props.allowSlide) return;
|
|
90
101
|
offsetX.value = 0;
|
|
91
102
|
isSliding.value = false;
|
|
92
103
|
};
|
|
93
104
|
|
|
94
|
-
//
|
|
105
|
+
// 监听全局事件:收回所有列表项的滑动状态(解决多个项同时展开)
|
|
106
|
+
const handleResetAllSlide = () => {
|
|
107
|
+
resetSlide();
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// 优化:页面点击/触摸外部判断(移除重复监听,保留uni-app内置方法更稳定)
|
|
95
111
|
const handlePageClick = (e) => {
|
|
96
112
|
if (!listItemRef.value || !isSliding.value) return;
|
|
97
113
|
|
|
98
|
-
// 获取组件 DOM 信息
|
|
99
114
|
const itemDom = listItemRef.value;
|
|
100
115
|
const itemRect = itemDom.getBoundingClientRect();
|
|
101
116
|
|
|
102
|
-
// 判断点击坐标是否在组件外部
|
|
103
117
|
const clickX = e.clientX || e.touches?.[0]?.clientX;
|
|
104
118
|
const clickY = e.clientY || e.touches?.[0]?.clientY;
|
|
119
|
+
|
|
120
|
+
// 点击组件外部,收回滑动
|
|
105
121
|
if (
|
|
106
122
|
clickX < itemRect.left ||
|
|
107
123
|
clickX > itemRect.right ||
|
|
108
124
|
clickY < itemRect.top ||
|
|
109
125
|
clickY > itemRect.bottom
|
|
110
126
|
) {
|
|
111
|
-
// 点击外部,触发收回
|
|
112
127
|
resetSlide();
|
|
113
128
|
}
|
|
114
129
|
};
|
|
115
130
|
|
|
116
|
-
// 新增:挂载时添加页面点击监听,卸载时移除(防止内存泄漏)
|
|
117
131
|
onMounted(() => {
|
|
118
|
-
//
|
|
119
|
-
uni.onClickOutside(listItemRef, resetSlide);
|
|
120
|
-
//
|
|
132
|
+
// 1. 优先使用uni-app内置外部点击监听(更适配uni-app生态,无重复)
|
|
133
|
+
uni.onClickOutside(listItemRef, resetSlide);
|
|
134
|
+
// 2. 监听全局事件,用于收回所有项
|
|
135
|
+
uni.$on('auiListItem:resetAllSlide', handleResetAllSlide);
|
|
136
|
+
// 3. 备用:window点击监听(兼容PC端和部分特殊场景)
|
|
121
137
|
window.addEventListener('click', handlePageClick);
|
|
122
138
|
window.addEventListener('touchstart', handlePageClick);
|
|
123
139
|
});
|
|
124
140
|
|
|
125
141
|
onUnmounted(() => {
|
|
126
|
-
//
|
|
142
|
+
// 移除所有监听,防止内存泄漏
|
|
127
143
|
uni.offClickOutside(listItemRef, resetSlide);
|
|
144
|
+
uni.$off('auiListItem:resetAllSlide', handleResetAllSlide);
|
|
128
145
|
window.removeEventListener('click', handlePageClick);
|
|
129
146
|
window.removeEventListener('touchstart', handlePageClick);
|
|
130
147
|
});
|
|
131
148
|
</script>
|
|
132
149
|
|
|
133
|
-
<!-- 样式部分不变,保留你的原有样式 -->
|
|
134
150
|
<style scoped lang="scss">
|
|
135
151
|
@import '../style.scss';
|
|
136
152
|
.aui-list-item {
|
|
@@ -143,9 +159,8 @@ onUnmounted(() => {
|
|
|
143
159
|
}
|
|
144
160
|
.aui-list-item-content-wrapper {
|
|
145
161
|
display: flex;
|
|
146
|
-
// align-items: center;
|
|
147
162
|
width: 100%;
|
|
148
|
-
transition: transform 0.3s;
|
|
163
|
+
transition: transform 0.3s; /* 平滑过渡,提升体验 */
|
|
149
164
|
}
|
|
150
165
|
.aui-list-item_befor {
|
|
151
166
|
margin:0 10px;
|
|
@@ -175,7 +190,7 @@ onUnmounted(() => {
|
|
|
175
190
|
right: 0;
|
|
176
191
|
top: 0;
|
|
177
192
|
bottom: 0;
|
|
178
|
-
width: 150px; /*
|
|
193
|
+
width: 150px; /* 与左滑偏移-150对应 */
|
|
179
194
|
background-color: #f0f0f0;
|
|
180
195
|
display: flex;
|
|
181
196
|
align-items: center;
|