rrj-astra-ui 1.1.7 → 1.1.9
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/AuiList.vue +24 -8
- package/components/AuiListItem.vue +46 -32
- package/package.json +1 -1
package/components/AuiList.vue
CHANGED
|
@@ -3,16 +3,32 @@
|
|
|
3
3
|
<slot></slot>
|
|
4
4
|
</view>
|
|
5
5
|
</template>
|
|
6
|
+
|
|
6
7
|
<script setup>
|
|
8
|
+
import { defineProps, ref, provide } from 'vue';
|
|
9
|
+
const __name = 'AuiList'; // 保留你的 __name,无改动
|
|
10
|
+
|
|
11
|
+
defineOptions({
|
|
12
|
+
name: __name
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const props = defineProps({});
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
|
|
17
|
+
// 核心:记录当前展开的子组件实例(AuiListItem)
|
|
18
|
+
const currentOpenItem = ref(null);
|
|
10
19
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
// 核心:父组件提供的重置方法,供所有子组件调用
|
|
21
|
+
const resetAllListItems = (currentItem) => {
|
|
22
|
+
// 如果有其他展开的子项,调用它的重置方法
|
|
23
|
+
if (currentOpenItem.value && currentOpenItem.value !== currentItem) {
|
|
24
|
+
currentOpenItem.value.resetSlide();
|
|
25
|
+
}
|
|
26
|
+
// 记录当前展开的子项(如果是 null,说明要清空所有展开状态)
|
|
27
|
+
currentOpenItem.value = currentItem;
|
|
28
|
+
};
|
|
14
29
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
30
|
+
// 关键:通过 provide 向所有子组件注入重置方法,实现父子通信
|
|
31
|
+
provide('auiListContext', {
|
|
32
|
+
resetAllListItems,
|
|
33
|
+
});
|
|
18
34
|
</script>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<view class="aui-list-item" ref="listItemRef">
|
|
3
|
-
<view class="aui-list-item-content-wrapper"
|
|
3
|
+
<view class="aui-list-item-content-wrapper"
|
|
4
|
+
:style="{ transform: `translateX(${offsetX}px)` }"
|
|
5
|
+
@touchstart="onTouchStart"
|
|
6
|
+
@touchmove="onTouchMove"
|
|
7
|
+
@touchend="onTouchEnd">
|
|
4
8
|
<view class="aui-list-item_befor">
|
|
5
9
|
<slot name="befor"></slot>
|
|
6
10
|
</view>
|
|
@@ -26,8 +30,8 @@
|
|
|
26
30
|
</template>
|
|
27
31
|
|
|
28
32
|
<script setup>
|
|
29
|
-
import { defineProps, ref, onMounted, onUnmounted } from 'vue';
|
|
30
|
-
const __name = 'AuiListItem'; //
|
|
33
|
+
import { defineProps, ref, onMounted, onUnmounted, inject, expose } from 'vue';
|
|
34
|
+
const __name = 'AuiListItem'; // 保留你的 __name,无改动
|
|
31
35
|
|
|
32
36
|
defineOptions({
|
|
33
37
|
name: __name
|
|
@@ -52,35 +56,35 @@ const props = defineProps({
|
|
|
52
56
|
}
|
|
53
57
|
});
|
|
54
58
|
|
|
59
|
+
// 注入父组件提供的上下文(重置方法)
|
|
60
|
+
const auiListContext = inject('auiListContext', null);
|
|
61
|
+
|
|
55
62
|
const startX = ref(0);
|
|
56
63
|
const offsetX = ref(0);
|
|
57
64
|
const isSliding = ref(false);
|
|
58
65
|
const SLIDE_THRESHOLD = -50;
|
|
59
|
-
// 新增:获取组件 DOM 引用(保留你的原有定义)
|
|
60
66
|
const listItemRef = ref(null);
|
|
61
67
|
|
|
62
|
-
//
|
|
68
|
+
// 原有滑动逻辑(已修复右滑,无改动)
|
|
63
69
|
const onTouchStart = (e) => {
|
|
64
70
|
if (!props.allowSlide) return;
|
|
65
|
-
// 新增:触摸当前项时,收回其他已展开的项(解决多选项同时展开)
|
|
66
|
-
uni.$emit('auiListItem:resetAllSlide');
|
|
67
71
|
startX.value = e.touches[0].clientX;
|
|
68
|
-
offsetX.value = 0;
|
|
69
|
-
isSliding.value = false;
|
|
72
|
+
offsetX.value = 0;
|
|
73
|
+
isSliding.value = false;
|
|
70
74
|
};
|
|
71
75
|
|
|
72
76
|
const onTouchMove = (e) => {
|
|
73
77
|
if (!props.allowSlide) return;
|
|
74
78
|
const currentX = e.touches[0].clientX;
|
|
75
79
|
const diffX = currentX - startX.value;
|
|
76
|
-
//
|
|
80
|
+
// 左滑逻辑(你的原有逻辑)
|
|
77
81
|
if (diffX < 0) {
|
|
78
82
|
offsetX.value = diffX;
|
|
79
83
|
if (diffX < SLIDE_THRESHOLD) {
|
|
80
84
|
isSliding.value = true;
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
//
|
|
87
|
+
// 右滑恢复逻辑(你的原有逻辑,修复无法右滑)
|
|
84
88
|
if (diffX > 0) {
|
|
85
89
|
offsetX.value = 0;
|
|
86
90
|
isSliding.value = false;
|
|
@@ -89,31 +93,36 @@ const onTouchMove = (e) => {
|
|
|
89
93
|
|
|
90
94
|
const onTouchEnd = () => {
|
|
91
95
|
if (!props.allowSlide) return;
|
|
92
|
-
// 完全还原你的原有逻辑,不做任何额外限制
|
|
93
96
|
if (offsetX.value < SLIDE_THRESHOLD) {
|
|
94
97
|
offsetX.value = -150;
|
|
98
|
+
isSliding.value = true;
|
|
99
|
+
// 关键:当前项展开时,通知父组件重置其他子项,并记录自身实例
|
|
100
|
+
if (auiListContext) {
|
|
101
|
+
auiListContext.resetAllListItems(instanceRef.value);
|
|
102
|
+
}
|
|
95
103
|
} else {
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
resetSlide();
|
|
105
|
+
// 关键:当前项收回时,通知父组件清空展开记录
|
|
106
|
+
if (auiListContext) {
|
|
107
|
+
auiListContext.resetAllListItems(null);
|
|
108
|
+
}
|
|
98
109
|
}
|
|
99
110
|
};
|
|
100
111
|
|
|
101
|
-
//
|
|
112
|
+
// 核心:收回当前项的滑动状态(暴露给父组件调用)
|
|
102
113
|
const resetSlide = () => {
|
|
103
|
-
if (!props.allowSlide
|
|
114
|
+
if (!props.allowSlide) return;
|
|
104
115
|
offsetX.value = 0;
|
|
105
116
|
isSliding.value = false;
|
|
106
117
|
};
|
|
107
118
|
|
|
108
|
-
//
|
|
119
|
+
// 关键:监听组件外部点击(收回当前项,同时通知父组件清空记录)
|
|
109
120
|
const handlePageClick = (e) => {
|
|
110
121
|
if (!listItemRef.value || !isSliding.value) return;
|
|
111
122
|
|
|
112
|
-
// 获取组件 DOM 信息
|
|
113
123
|
const itemDom = listItemRef.value;
|
|
114
124
|
const itemRect = itemDom.getBoundingClientRect();
|
|
115
125
|
|
|
116
|
-
// 判断点击坐标是否在组件外部
|
|
117
126
|
const clickX = e.clientX || e.touches?.[0]?.clientX;
|
|
118
127
|
const clickY = e.clientY || e.touches?.[0]?.clientY;
|
|
119
128
|
if (
|
|
@@ -122,33 +131,38 @@ const handlePageClick = (e) => {
|
|
|
122
131
|
clickY < itemRect.top ||
|
|
123
132
|
clickY > itemRect.bottom
|
|
124
133
|
) {
|
|
125
|
-
// 点击外部,触发收回
|
|
126
134
|
resetSlide();
|
|
135
|
+
if (auiListContext) {
|
|
136
|
+
auiListContext.resetAllListItems(null);
|
|
137
|
+
}
|
|
127
138
|
}
|
|
128
139
|
};
|
|
129
140
|
|
|
130
|
-
//
|
|
131
|
-
const
|
|
132
|
-
resetSlide
|
|
133
|
-
};
|
|
141
|
+
// 关键:暴露当前组件实例和 resetSlide 方法,供父组件调用
|
|
142
|
+
const instanceRef = ref({
|
|
143
|
+
resetSlide
|
|
144
|
+
});
|
|
145
|
+
expose({
|
|
146
|
+
resetSlide
|
|
147
|
+
});
|
|
134
148
|
|
|
135
|
-
// 挂载时添加监听(优化:去重但保留你的原有监听,新增全局事件)
|
|
136
149
|
onMounted(() => {
|
|
137
|
-
//
|
|
138
|
-
uni.onClickOutside(listItemRef,
|
|
139
|
-
|
|
150
|
+
// 保留你的外部点击监听(兼容所有场景)
|
|
151
|
+
uni.onClickOutside(listItemRef, () => {
|
|
152
|
+
resetSlide();
|
|
153
|
+
if (auiListContext) {
|
|
154
|
+
auiListContext.resetAllListItems(null);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
140
157
|
window.addEventListener('click', handlePageClick);
|
|
141
158
|
window.addEventListener('touchstart', handlePageClick);
|
|
142
|
-
// 新增:监听全局重置事件,不影响你的原有逻辑
|
|
143
|
-
uni.$on('auiListItem:resetAllSlide', handleResetAllSlide);
|
|
144
159
|
});
|
|
145
160
|
|
|
146
161
|
onUnmounted(() => {
|
|
147
|
-
//
|
|
162
|
+
// 移除监听,防止内存泄漏
|
|
148
163
|
uni.offClickOutside(listItemRef, resetSlide);
|
|
149
164
|
window.removeEventListener('click', handlePageClick);
|
|
150
165
|
window.removeEventListener('touchstart', handlePageClick);
|
|
151
|
-
uni.$off('auiListItem:resetAllSlide', handleResetAllSlide);
|
|
152
166
|
});
|
|
153
167
|
</script>
|
|
154
168
|
|