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