@cqmcui/cqmcui
Version:
轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)
213 lines (212 loc) • 6.9 kB
JavaScript
import { ref, reactive, computed, watch, toRefs, nextTick, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, normalizeStyle, createBlock, createCommentVNode, toDisplayString, renderSlot } from "vue";
import { c as createComponent, l as getScrollTopRoot } from "./component-81a4c1d0.js";
import { u as useTouch } from "./index-7a7385e4.js";
import { p as pxCheck } from "./pxCheck-c6b9f6b7.js";
import { u as useScrollParent } from "./index-43c34ac6.js";
import { Loading } from "@cqmcui/icons-vue";
import { _ as _export_sfc } from "./_plugin-vue_export-helper-cc2b3d55.js";
import "../locale/lang";
const { componentName, create, translate } = createComponent("pull-refresh");
const _sfc_main = create({
props: {
modelValue: {
type: Boolean,
default: false
},
pullingTxt: {
type: String,
default: translate("pulling")
},
loosingTxt: {
type: String,
default: translate("loosing")
},
loadingTxt: {
type: String,
default: translate("loading")
},
// completeTxt: {
// type: String,
// default: ''
// },
headHeight: {
type: [String, Number],
default: 50
},
pullDistance: {
type: [String, Number],
default: 50
},
duration: {
type: [String, Number],
default: 0.3
}
},
emits: ["change", "refresh", "update:modelValue"],
components: { Loading },
setup(props, { emit, slots }) {
const touch = useTouch();
const scroller = ref();
const scrollParent = useScrollParent(scroller);
const state = reactive({
isPullRefresh: false,
distance: 0,
status: "normal"
});
const classes = computed(() => {
const prefixCls = componentName;
return {
[prefixCls]: true
};
});
const getPullStatus = computed(() => {
switch (state.status) {
case "pulling":
return !slots.pulling ? props.pullingTxt : "";
case "loosing":
return !slots.loosing ? props.loosingTxt : "";
case "loading":
return !slots.loading ? props.loadingTxt : "";
}
});
const getStyle = computed(() => {
return {
transitionDuration: `${props.duration}s`,
transform: state.distance ? `translate3d(0,${state.distance}px, 0)` : ""
};
});
const getHeightStyle = computed(() => {
const styles = {};
if (props.headHeight != 50)
styles.height = pxCheck(props.headHeight);
return styles;
});
const timing = (distance) => {
const pullDistance = +(props.pullDistance || props.headHeight);
let moveDistance = distance;
if (distance > pullDistance) {
if (distance < pullDistance * 2) {
moveDistance = (distance + pullDistance) / 2;
} else {
moveDistance = pullDistance + distance / 4;
}
}
return Math.round(moveDistance);
};
const setPullStatus = (distance, isLoading) => {
const pullDistance = +(props.pullDistance || props.headHeight);
state.distance = distance;
if (isLoading) {
state.status = "loading";
} else if (distance === 0) {
state.status = "normal";
} else if (distance < pullDistance) {
state.status = "pulling";
} else {
state.status = "loosing";
}
emit("change", { status: state.status, distance });
};
const isCanTouch = () => state.status !== "loading" && state.status !== "complete";
const isScrollTop = () => {
if (scrollParent.value == window) {
return getScrollTopRoot() == 0;
} else {
return scrollParent.value && scrollParent.value.scrollTop == 0;
}
};
const touchStart = (event) => {
if (isCanTouch()) {
if (isScrollTop()) {
touch.start(event);
state.isPullRefresh = true;
} else {
state.distance = 0;
state.isPullRefresh = false;
}
}
};
const touchMove = (event) => {
if (isCanTouch()) {
touch.move(event);
const { deltaY } = touch;
if (touch.isVertical() && deltaY.value > 0 && state.isPullRefresh) {
event.preventDefault();
setPullStatus(timing(deltaY.value));
}
}
};
const touchEnd = () => {
if (state.isPullRefresh && isCanTouch() && touch.deltaY.value) {
if (state.status === "loosing") {
setPullStatus(+props.headHeight, true);
emit("update:modelValue", true);
nextTick(() => emit("refresh"));
} else {
setPullStatus(0);
}
}
setTimeout(() => {
touch.reset();
}, 0);
};
watch(
() => props.modelValue,
(val) => {
if (val) {
setPullStatus(+props.headHeight, true);
} else {
setPullStatus(0);
}
}
);
return {
classes,
scroller,
...toRefs(state),
touchStart,
touchMove,
touchEnd,
getStyle,
translate,
slots,
getHeightStyle,
getPullStatus
};
}
});
const _hoisted_1 = { class: "cqmc-pull-refresh-container-topbox-text" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_Loading = resolveComponent("Loading");
return openBlock(), createElementBlock("div", {
class: normalizeClass(_ctx.classes),
ref: "scroller",
onTouchstart: _cache[0] || (_cache[0] = (...args) => _ctx.touchStart && _ctx.touchStart(...args)),
onTouchmove: _cache[1] || (_cache[1] = (...args) => _ctx.touchMove && _ctx.touchMove(...args)),
onTouchend: _cache[2] || (_cache[2] = (...args) => _ctx.touchEnd && _ctx.touchEnd(...args))
}, [
createElementVNode("div", {
class: "cqmc-pull-refresh-container",
style: normalizeStyle(_ctx.getStyle)
}, [
createElementVNode("div", {
class: "cqmc-pull-refresh-container-topbox",
style: normalizeStyle(_ctx.getHeightStyle)
}, [
_ctx.status == "loading" && !_ctx.slots.loading ? (openBlock(), createBlock(_component_Loading, {
key: 0,
class: "cqmc-icon-loading cqmc-pull-refresh-container-topbox-icon"
})) : createCommentVNode("", true),
createElementVNode("div", _hoisted_1, toDisplayString(_ctx.getPullStatus), 1),
_ctx.status == "pulling" ? renderSlot(_ctx.$slots, "pulling", { key: 1 }) : createCommentVNode("", true),
_ctx.status == "loosing" ? renderSlot(_ctx.$slots, "loosing", { key: 2 }) : createCommentVNode("", true),
_ctx.status == "loading" ? renderSlot(_ctx.$slots, "loading", { key: 3 }) : createCommentVNode("", true)
], 4),
renderSlot(_ctx.$slots, "default")
], 4)
], 34);
}
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
index as default
};