@nutui/nutui
Version:
京东风格的轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)
241 lines (240 loc) • 8.29 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
import { ref, reactive, computed, watch, toRefs, nextTick, resolveComponent, openBlock, createElementBlock, createElementVNode, normalizeStyle, createBlock, createCommentVNode, toDisplayString, renderSlot } from "vue";
import { c as createComponent } from "../component-DQf3CENX.js";
import { j as getScrollTopRoot } from "../util-D1pvnUYu.js";
import { u as useTouch } from "../index-I8tfW3Kf.js";
import { p as pxCheck } from "../pxCheck-DN6FYV6q.js";
import { u as useScrollParent } from "../index-BvmDLUYP.js";
import { Loading } from "@nutui/icons-vue";
import { u as useLocale } from "../index-BOB4ytqZ.js";
import { _ as _export_sfc } from "../_plugin-vue_export-helper-1tPrXgE0.js";
const { create } = createComponent("pull-refresh");
const cN = "NutPullRefresh";
const _sfc_main = create({
props: {
modelValue: {
type: Boolean,
default: false
},
pullingTxt: {
type: String,
default: ""
},
loosingTxt: {
type: String,
default: ""
},
loadingTxt: {
type: String,
default: ""
},
completeTxt: {
type: String,
default: ""
},
headHeight: {
type: [String, Number],
default: 50
},
pullDistance: {
type: [String, Number],
default: 50
},
duration: {
type: [String, Number],
default: 0.3
},
completeDuration: {
type: Number,
default: 0
}
},
emits: ["change", "refresh", "update:modelValue"],
components: { Loading },
setup(props, { emit, slots }) {
const translate = useLocale(cN);
const touch = useTouch();
const scroller = ref();
const scrollParent = useScrollParent(scroller);
const state = reactive({
isPullRefresh: false,
distance: 0,
status: "normal"
});
const getPullStatus = computed(() => {
switch (state.status) {
case "pulling":
return !slots.pulling ? props.pullingTxt || translate("pulling") : "";
case "loosing":
return !slots.loosing ? props.loosingTxt || translate("loosing") : "";
case "loading":
return !slots.loading ? props.loadingTxt || translate("loading") : "";
case "complete":
return !slots.complete ? props.completeTxt || translate("complete") : "";
}
return "";
});
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, isComplete) => {
const pullDistance = +(props.pullDistance || props.headHeight);
state.distance = distance;
if (isLoading) {
state.status = "loading";
} else if (isComplete) {
state.status = "complete";
} 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 {
if (props.completeDuration === 0) setPullStatus(0);
setPullStatus(+props.headHeight, false, true);
setTimeout(() => {
setPullStatus(0);
}, props.completeDuration);
}
}
);
return __spreadProps(__spreadValues({
scroller
}, toRefs(state)), {
touchStart,
touchMove,
touchEnd,
getStyle,
translate,
slots,
getHeightStyle,
getPullStatus
});
}
});
const _hoisted_1 = { class: "nut-pull-refresh-container-topbox-text" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_Loading = resolveComponent("Loading");
return openBlock(), createElementBlock("div", {
ref: "scroller",
class: "nut-pull-refresh",
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: "nut-pull-refresh-container",
style: normalizeStyle(_ctx.getStyle)
}, [
createElementVNode("div", {
class: "nut-pull-refresh-container-topbox",
style: normalizeStyle(_ctx.getHeightStyle)
}, [
_ctx.status == "loading" && !_ctx.slots.loading ? (openBlock(), createBlock(_component_Loading, {
key: 0,
class: "nut-icon-loading nut-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),
_ctx.status == "complete" ? renderSlot(_ctx.$slots, "complete", { key: 4 }) : createCommentVNode("", true)
], 4),
renderSlot(_ctx.$slots, "default")
], 4)
], 544);
}
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
index as default
};