|
@@ -13,15 +13,18 @@
|
|
|
direction == 'horizontal' ? 'pullrefresh-top-h' : 'pullrefresh-top-v'
|
|
direction == 'horizontal' ? 'pullrefresh-top-h' : 'pullrefresh-top-v'
|
|
|
"
|
|
"
|
|
|
>
|
|
>
|
|
|
- <template v-if="status == 'loading' && reachTop && distance > 0">
|
|
|
|
|
- 加载中...
|
|
|
|
|
- </template>
|
|
|
|
|
- <template v-if="status == 'pulling' && reachTop && distance > 0">
|
|
|
|
|
- 下拉刷新...
|
|
|
|
|
- </template>
|
|
|
|
|
- <template v-if="status == 'loosing' && reachTop && distance > 0">
|
|
|
|
|
- 释放刷新...
|
|
|
|
|
- </template>
|
|
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-if="status == 'loading' && (reachTop || reachLeft) && distance > 0"
|
|
|
|
|
+ >{{ loadingText }}</template
|
|
|
|
|
+ >
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-if="status == 'pulling' && (reachTop || reachLeft) && distance > 0"
|
|
|
|
|
+ >{{ pullingText }}</template
|
|
|
|
|
+ >
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-if="status == 'loosing' && (reachTop || reachLeft) && distance > 0"
|
|
|
|
|
+ >{{ loosingText }}</template
|
|
|
|
|
+ >
|
|
|
</view>
|
|
</view>
|
|
|
<view class="pullrefresh-content" ref="pull">
|
|
<view class="pullrefresh-content" ref="pull">
|
|
|
<slot></slot>
|
|
<slot></slot>
|
|
@@ -36,15 +39,24 @@
|
|
|
"
|
|
"
|
|
|
:style="getBottomStyle"
|
|
:style="getBottomStyle"
|
|
|
>
|
|
>
|
|
|
- <template v-if="status == 'loading' && reachBottom && distance < 0">
|
|
|
|
|
- 加载中...
|
|
|
|
|
- </template>
|
|
|
|
|
- <template v-if="status == 'pulling' && reachBottom && distance < 0">
|
|
|
|
|
- 下拉刷新...
|
|
|
|
|
- </template>
|
|
|
|
|
- <template v-if="status == 'loosing' && reachBottom && distance < 0">
|
|
|
|
|
- 释放刷新...
|
|
|
|
|
- </template>
|
|
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-if="
|
|
|
|
|
+ status == 'loading' && (reachBottom || reachRight) && distance < 0
|
|
|
|
|
+ "
|
|
|
|
|
+ >{{ loadingText }}</template
|
|
|
|
|
+ >
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-if="
|
|
|
|
|
+ status == 'pulling' && (reachBottom || reachRight) && distance < 0
|
|
|
|
|
+ "
|
|
|
|
|
+ >{{ pullingText }}</template
|
|
|
|
|
+ >
|
|
|
|
|
+ <template
|
|
|
|
|
+ v-if="
|
|
|
|
|
+ status == 'loosing' && (reachBottom || reachRight) && distance < 0
|
|
|
|
|
+ "
|
|
|
|
|
+ >{{ loosingText }}</template
|
|
|
|
|
+ >
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
@@ -74,6 +86,19 @@ export default create({
|
|
|
direction: {
|
|
direction: {
|
|
|
type: String,
|
|
type: String,
|
|
|
default: 'vertical'
|
|
default: 'vertical'
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ pullingText: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '下拉刷新'
|
|
|
|
|
+ },
|
|
|
|
|
+ loosingText: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '松手释放刷新'
|
|
|
|
|
+ },
|
|
|
|
|
+ loadingText: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '加载中...'
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
components: {},
|
|
components: {},
|
|
@@ -87,6 +112,9 @@ export default create({
|
|
|
const reachTop = ref(false);
|
|
const reachTop = ref(false);
|
|
|
const reachBottom = ref(false);
|
|
const reachBottom = ref(false);
|
|
|
|
|
|
|
|
|
|
+ const reachLeft = ref(false);
|
|
|
|
|
+ const reachRight = ref(false);
|
|
|
|
|
+
|
|
|
const state = reactive({
|
|
const state = reactive({
|
|
|
status: 'normal',
|
|
status: 'normal',
|
|
|
distance: 0,
|
|
distance: 0,
|
|
@@ -100,10 +128,12 @@ export default create({
|
|
|
|
|
|
|
|
const getStyle = computed(() => {
|
|
const getStyle = computed(() => {
|
|
|
let style: CSSProperties = {};
|
|
let style: CSSProperties = {};
|
|
|
-
|
|
|
|
|
|
|
+ const { deltaY, deltaX } = touch;
|
|
|
if (
|
|
if (
|
|
|
- (reachTop.value && touch.deltaY.value > 0 && touch.isVertical()) ||
|
|
|
|
|
- (reachBottom.value && touch.deltaY.value < 0 && touch.isVertical())
|
|
|
|
|
|
|
+ direction.value == 'vertical' &&
|
|
|
|
|
+ ((reachTop.value && deltaY.value > 0) ||
|
|
|
|
|
+ (reachBottom.value && deltaY.value < 0)) &&
|
|
|
|
|
+ touch.isVertical()
|
|
|
) {
|
|
) {
|
|
|
style = {
|
|
style = {
|
|
|
transitionDuration: `${state.duration}ms`,
|
|
transitionDuration: `${state.duration}ms`,
|
|
@@ -112,17 +142,48 @@ export default create({
|
|
|
: `translate3d(0,0,0)`
|
|
: `translate3d(0,0,0)`
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'horizontal' &&
|
|
|
|
|
+ ((reachLeft.value && deltaX.value > 0) ||
|
|
|
|
|
+ (reachRight.value && deltaX.value < 0)) &&
|
|
|
|
|
+ touch.isHorizontal()
|
|
|
|
|
+ ) {
|
|
|
|
|
+ style = {
|
|
|
|
|
+ transitionDuration: `${state.duration}ms`,
|
|
|
|
|
+ transform: state.distance
|
|
|
|
|
+ ? `translate3d(${state.distance}px, 0,0)`
|
|
|
|
|
+ : `translate3d(0,0,0)`
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return style;
|
|
return style;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const getBottomStyle = computed(() => {
|
|
const getBottomStyle = computed(() => {
|
|
|
let style: CSSProperties = {};
|
|
let style: CSSProperties = {};
|
|
|
- if (reachBottom.value && touch.deltaY.value < 0 && touch.isVertical()) {
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'vertical' &&
|
|
|
|
|
+ reachBottom.value &&
|
|
|
|
|
+ touch.deltaY.value < 0 &&
|
|
|
|
|
+ touch.isVertical()
|
|
|
|
|
+ ) {
|
|
|
const dis = Math.abs(state.distance) < 50 ? -state.distance : 50;
|
|
const dis = Math.abs(state.distance) < 50 ? -state.distance : 50;
|
|
|
style = {
|
|
style = {
|
|
|
height: dis + 'px'
|
|
height: dis + 'px'
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'horizontal' &&
|
|
|
|
|
+ reachRight.value &&
|
|
|
|
|
+ touch.deltaX.value < 0 &&
|
|
|
|
|
+ touch.isVertical()
|
|
|
|
|
+ ) {
|
|
|
|
|
+ const dis = Math.abs(state.distance) < 50 ? -state.distance : 50;
|
|
|
|
|
+ style = {
|
|
|
|
|
+ width: dis + 'px'
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
return style;
|
|
return style;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -187,62 +248,97 @@ export default create({
|
|
|
const top = 'scrollTop' in scrollEl ? scrollEl.scrollTop : 0;
|
|
const top = 'scrollTop' in scrollEl ? scrollEl.scrollTop : 0;
|
|
|
reachTop.value = Math.max(top, 0) == 0 ? true : false;
|
|
reachTop.value = Math.max(top, 0) == 0 ? true : false;
|
|
|
|
|
|
|
|
- if (reachTop.value) {
|
|
|
|
|
- state.duration = 0;
|
|
|
|
|
- touch.start(event);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const { scrollHeight, clientHeight, scrollTop } = scrollEl;
|
|
|
|
|
-
|
|
|
|
|
/** 判断滚动条是否在底部*/
|
|
/** 判断滚动条是否在底部*/
|
|
|
|
|
+ const { scrollHeight, clientHeight, scrollTop } = scrollEl;
|
|
|
reachBottom.value =
|
|
reachBottom.value =
|
|
|
clientHeight + scrollTop == scrollHeight ? true : false;
|
|
clientHeight + scrollTop == scrollHeight ? true : false;
|
|
|
|
|
|
|
|
- if (reachBottom.value) {
|
|
|
|
|
|
|
+ if (reachTop.value || reachBottom.value) {
|
|
|
state.duration = 0;
|
|
state.duration = 0;
|
|
|
touch.start(event);
|
|
touch.start(event);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
const { scrollWidth, clientWidth, scrollLeft } = scrollEl;
|
|
const { scrollWidth, clientWidth, scrollLeft } = scrollEl;
|
|
|
/** 判断滚动条是否在左边 */
|
|
/** 判断滚动条是否在左边 */
|
|
|
- console.log(scrollWidth, clientWidth, scrollLeft);
|
|
|
|
|
|
|
+ const left = 'scrollLeft' in scrollEl ? scrollEl.scrollLeft : 0;
|
|
|
|
|
+ reachLeft.value = Math.max(left, 0) == 0 ? true : false;
|
|
|
|
|
+
|
|
|
|
|
+ /** 判断滚动条是否在右边 */
|
|
|
|
|
+ reachRight.value =
|
|
|
|
|
+ clientWidth + scrollLeft == scrollWidth ? true : false;
|
|
|
|
|
+
|
|
|
|
|
+ if (reachLeft.value || reachRight.value) {
|
|
|
|
|
+ state.duration = 0;
|
|
|
|
|
+ touch.start(event);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const touchMove = event => {
|
|
const touchMove = event => {
|
|
|
if (isTouchable()) {
|
|
if (isTouchable()) {
|
|
|
- const { deltaY } = touch;
|
|
|
|
|
|
|
+ const { deltaY, deltaX } = touch;
|
|
|
touch.move(event);
|
|
touch.move(event);
|
|
|
- if (reachTop.value && deltaY.value >= 0 && touch.isVertical()) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'vertical' &&
|
|
|
|
|
+ ((reachBottom.value && deltaY.value < 0) ||
|
|
|
|
|
+ (reachTop.value && deltaY.value >= 0)) &&
|
|
|
|
|
+ touch.isVertical()
|
|
|
|
|
+ ) {
|
|
|
preventDefault(event);
|
|
preventDefault(event);
|
|
|
setStatus(ease(deltaY.value));
|
|
setStatus(ease(deltaY.value));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (reachBottom.value && deltaY.value < 0 && touch.isVertical()) {
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'horizontal' &&
|
|
|
|
|
+ ((reachLeft.value && deltaX.value >= 0) ||
|
|
|
|
|
+ (reachRight.value && deltaX.value < 0)) &&
|
|
|
|
|
+ touch.isHorizontal()
|
|
|
|
|
+ ) {
|
|
|
preventDefault(event);
|
|
preventDefault(event);
|
|
|
- setStatus(ease(deltaY.value));
|
|
|
|
|
|
|
+ setStatus(ease(deltaX.value));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
const touchEnd = () => {
|
|
const touchEnd = () => {
|
|
|
if (isTouchable()) {
|
|
if (isTouchable()) {
|
|
|
- if (reachTop.value && touch.deltaY.value > 0) {
|
|
|
|
|
- if (state.status === 'loosing') {
|
|
|
|
|
- setStatus(50, true);
|
|
|
|
|
- emit('refresh', refreshDone);
|
|
|
|
|
- } else {
|
|
|
|
|
- setStatus(0);
|
|
|
|
|
|
|
+ const { deltaY, deltaX } = touch;
|
|
|
|
|
+ if (state.status === 'loosing') {
|
|
|
|
|
+ let dis = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'vertical' &&
|
|
|
|
|
+ reachTop.value &&
|
|
|
|
|
+ deltaY.value > 0
|
|
|
|
|
+ ) {
|
|
|
|
|
+ dis = 50;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (reachBottom.value && touch.deltaY.value < 0) {
|
|
|
|
|
- if (state.status === 'loosing') {
|
|
|
|
|
- setStatus(-50, true);
|
|
|
|
|
- emit('refresh', refreshDone);
|
|
|
|
|
- } else {
|
|
|
|
|
- setStatus(0);
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'vertical' &&
|
|
|
|
|
+ reachBottom.value &&
|
|
|
|
|
+ deltaY.value < 0
|
|
|
|
|
+ ) {
|
|
|
|
|
+ dis = -50;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'horizontal' &&
|
|
|
|
|
+ reachLeft.value &&
|
|
|
|
|
+ deltaX.value > 0
|
|
|
|
|
+ ) {
|
|
|
|
|
+ dis = 50;
|
|
|
}
|
|
}
|
|
|
|
|
+ if (
|
|
|
|
|
+ direction.value == 'horizontal' &&
|
|
|
|
|
+ reachRight.value &&
|
|
|
|
|
+ deltaX.value < 0
|
|
|
|
|
+ ) {
|
|
|
|
|
+ dis = -50;
|
|
|
|
|
+ }
|
|
|
|
|
+ setStatus(dis, true);
|
|
|
|
|
+ emit('refresh', refreshDone);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setStatus(0);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -254,6 +350,8 @@ export default create({
|
|
|
getStyle,
|
|
getStyle,
|
|
|
reachBottom,
|
|
reachBottom,
|
|
|
reachTop,
|
|
reachTop,
|
|
|
|
|
+ reachRight,
|
|
|
|
|
+ reachLeft,
|
|
|
getBottomStyle,
|
|
getBottomStyle,
|
|
|
...toRefs(state)
|
|
...toRefs(state)
|
|
|
};
|
|
};
|