UNPKG

@cqmcui/cqmcui

Version:

轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)

213 lines (212 loc) 6.9 kB
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 };