UNPKG

nutui-taro-upgrade

Version:

@nutui/nutui-taro 对京东风格组件库的taro4 版本支持

457 lines (456 loc) 14.1 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { ref, reactive, computed, provide, onDeactivated, onBeforeUnmount, watch, openBlock, createElementBlock, createElementVNode, normalizeClass, normalizeStyle, renderSlot, createTextVNode, Fragment, renderList, createCommentVNode } from "vue"; import { c as createComponent } from "../component-669c158a.js"; import { c as clamp } from "../util-f26975e1.js"; import { u as useTouch } from "../index-7a7385e4.js"; import { u as useTaroRect } from "../index-d9b20e11.js"; import { r as requestAniFrame } from "../raf-df951186.js"; import Taro, { eventCenter, getCurrentInstance } from "@tarojs/taro"; import { S as SWIPER_KEY } from "../types-e7486245.js"; import { _ as _export_sfc } from "../_plugin-vue_export-helper-cc2b3d55.js"; const { create, componentName } = createComponent("swiper"); const _sfc_main = create({ props: { width: { type: [Number, String] }, height: { type: [Number, String] }, direction: { type: String, default: "horizontal" // horizontal and vertical }, paginationVisible: { type: Boolean, default: false }, paginationColor: { type: String, default: "#fff" }, loop: { type: Boolean, default: true }, duration: { type: [Number, String], default: 500 }, autoPlay: { type: [Number, String], default: 0 }, initPage: { type: [Number, String], default: 0 }, touchable: { type: Boolean, default: true }, isPreventDefault: { type: Boolean, default: true }, isStopPropagation: { type: Boolean, default: true }, paginationUnselectedColor: { type: String, default: "#ddd" } }, emits: ["change"], setup(props, { emit, slots, expose }) { const container = ref(); const refRandomId = Math.random().toString(36).slice(-8); const state = reactive({ active: 0, num: 0, rect: null, width: 0, height: 0, moving: false, offset: 0, touchTime: 0, autoplayTimer: null, children: [], childrenVNode: [], style: {} }); const touch = useTouch(); const isVertical = computed(() => props.direction === "vertical"); const classesInner = computed(() => { const prefixCls = componentName; return { [`${prefixCls}-inner`]: true, [`${prefixCls}-vertical`]: isVertical.value }; }); const classesPagination = computed(() => { const prefixCls = componentName; return { [`${prefixCls}-pagination`]: true, [`${prefixCls}-pagination-vertical`]: isVertical.value }; }); const delTa = computed(() => { return isVertical.value ? touch.deltaY.value : touch.deltaX.value; }); const isCorrectDirection = computed(() => { return touch.direction.value === props.direction; }); const childCount = computed(() => state.children.length); const size = computed(() => state[isVertical.value ? "height" : "width"]); const trackSize = computed(() => childCount.value * size.value); const minOffset = computed(() => { if (state.rect) { const base = isVertical.value ? state.rect.height : state.rect.width; return base - size.value * childCount.value; } return 0; }); const activePagination = computed(() => (state.active + childCount.value) % childCount.value); const getStyle = () => { let offset = 0; offset = state.offset; state.style = { transitionDuration: `${state.moving ? 0 : props.duration}ms`, transform: `translate${isVertical.value ? "Y" : "X"}(${offset}px)`, [isVertical.value ? "height" : "width"]: `${size.value * childCount.value}px`, [isVertical.value ? "width" : "height"]: `${isVertical.value ? state.width : state.height}px` }; }; const relation = (child) => { var _a; let children = []; const childrenVNodeLen = state.childrenVNode.length; let slot = (_a = slots == null ? void 0 : slots.default) == null ? void 0 : _a.call(slots); slot = slot.filter((item) => item.children && Array.isArray(item.children)); slot.forEach((item) => { children = children.concat(item.children); }); if (!childrenVNodeLen) { state.childrenVNode = children.slice(); child.proxy && state.children.push(child.proxy); } else { if (childrenVNodeLen > children.length) { state.children = state.children.filter((item) => child.proxy !== item); } else if (childrenVNodeLen < children.length) { for (let i = 0; i < childrenVNodeLen; i++) { if (children[i].key !== state.childrenVNode[i].key) { child.proxy && state.children.splice(i, 0, child.proxy); child.vnode && state.childrenVNode.splice(i, 0, child.vnode); break; } } if (childrenVNodeLen !== children.length) { child.proxy && state.children.push(child.proxy); child.vnode && state.childrenVNode.push(child.vnode); } } else { state.childrenVNode = children.slice(); child.proxy && state.children.push(child.proxy); } } }; const getOffset = (active, offset = 0) => { let currentPosition = active * size.value; if (!props.loop) { currentPosition = Math.min(currentPosition, -minOffset.value); } let targetOffset = offset - currentPosition; if (!props.loop) { targetOffset = clamp(targetOffset, minOffset.value, 0); } return targetOffset; }; const getActive = (pace) => { const { active } = state; if (pace) { if (props.loop) { return clamp(active + pace, -1, childCount.value); } return clamp(active + pace, 0, childCount.value - 1); } return active; }; const move = ({ pace = 0, offset = 0, isEmit = false }) => { if (childCount.value <= 1) return; const { active } = state; const targetActive = getActive(pace); const targetOffset = getOffset(targetActive, offset); if (props.loop) { if (state.children[0] && targetOffset !== minOffset.value) { const rightBound = targetOffset < minOffset.value; state.children[0].setOffset(rightBound ? trackSize.value : 0); } if (state.children[childCount.value - 1] && targetOffset !== 0) { const leftBound = targetOffset > 0; state.children[childCount.value - 1].setOffset(leftBound ? -trackSize.value : 0); } } state.active = targetActive; state.offset = targetOffset; if (isEmit && active !== state.active) { emit("change", activePagination.value); } getStyle(); }; const resettPosition = () => { state.moving = true; if (state.active <= -1) { move({ pace: childCount.value }); } if (state.active >= childCount.value) { move({ pace: -childCount.value }); } }; const stopAutoPlay = () => { if (state.autoplayTimer) { clearTimeout(state.autoplayTimer); } }; const jump = (pace) => { resettPosition(); touch.reset(); requestAniFrame(() => { requestAniFrame(() => { state.moving = false; move({ pace, isEmit: true }); }); }); }; const prev = () => { jump(-1); }; const next = () => { jump(1); }; const to = (index) => { resettPosition(); touch.reset(); requestAniFrame(() => { state.moving = false; let targetIndex; if (props.loop && childCount.value === index) { targetIndex = state.active === 0 ? 0 : index; } else { targetIndex = index % childCount.value; } move({ pace: targetIndex - state.active, isEmit: true }); }); }; const autoplay = () => { if (Number(props.autoPlay) <= 0 || childCount.value <= 1) return; stopAutoPlay(); state.autoplayTimer = setTimeout(() => { next(); autoplay(); }, Number(props.autoPlay)); }; const init = (..._0) => __async(this, [..._0], function* (active = +props.initPage) { if (!container.value) return; stopAutoPlay(); useTaroRect(container).then( (rect) => { state.rect = rect; active = Math.min(childCount.value - 1, active); state.width = props.width ? +props.width : rect == null ? void 0 : rect.width; state.height = props.height ? +props.height : rect == null ? void 0 : rect.height; state.active = active; state.offset = getOffset(state.active); state.moving = true; getStyle(); autoplay(); }, () => { } ); }); const onTouchStart = (e) => { if (props.isStopPropagation) e.stopPropagation(); if (!props.touchable) return; touch.start(e); state.touchTime = Date.now(); stopAutoPlay(); resettPosition(); }; const onTouchMove = (e) => { if (props.touchable && state.moving) { touch.move(e); if (isCorrectDirection.value) { move({ offset: delTa.value }); } } }; const onTouchEnd = () => { if (!props.touchable || !state.moving) return; const speed = delTa.value / (Date.now() - state.touchTime); const isShouldMove = Math.abs(speed) > 0.3 || Math.abs(delTa.value) > +(size.value / 2).toFixed(2); if (isShouldMove && isCorrectDirection.value) { let pace = 0; const offset = isVertical.value ? touch.offsetY.value : touch.offsetX.value; if (props.loop) { pace = offset > 0 ? delTa.value > 0 ? -1 : 1 : 0; } else { pace = -Math[delTa.value > 0 ? "ceil" : "floor"](delTa.value / size.value); } move({ pace, isEmit: true }); } else if (delTa.value) { move({ pace: 0 }); } state.moving = false; getStyle(); autoplay(); }; provide(SWIPER_KEY, { props, size, relation }); expose({ prev, next, to }); onDeactivated(() => { stopAutoPlay(); }); onBeforeUnmount(() => { stopAutoPlay(); }); watch( () => props.initPage, (val) => { Taro.nextTick(() => { init(+val); }); eventCenter.once(getCurrentInstance().router.onReady, () => { init(+val); }); } ); watch( () => props.height, () => { Taro.nextTick(() => { init(); }); eventCenter.once(getCurrentInstance().router.onReady, () => { init(); }); } ); watch( () => state.children.length, () => { Taro.nextTick(() => { init(); }); eventCenter.once(getCurrentInstance().router.onReady, () => { Taro.nextTick(() => { init(); }); }); } ); watch( () => props.autoPlay, (val) => { Number(val) > 0 ? autoplay() : stopAutoPlay(); } ); return { state, refRandomId, classesPagination, classesInner, container, activePagination, onTouchStart, onTouchMove, onTouchEnd }; } }); const _hoisted_1 = ["id", "catch-move"]; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("view", { id: "container-" + _ctx.refRandomId, ref: "container", class: "nut-swiper", "catch-move": _ctx.isPreventDefault, onTouchstart: _cache[0] || (_cache[0] = (...args) => _ctx.onTouchStart && _ctx.onTouchStart(...args)), onTouchmove: _cache[1] || (_cache[1] = (...args) => _ctx.onTouchMove && _ctx.onTouchMove(...args)), onTouchend: _cache[2] || (_cache[2] = (...args) => _ctx.onTouchEnd && _ctx.onTouchEnd(...args)), onTouchcancel: _cache[3] || (_cache[3] = (...args) => _ctx.onTouchEnd && _ctx.onTouchEnd(...args)) }, [ createElementVNode("view", { class: normalizeClass(_ctx.classesInner), style: normalizeStyle(_ctx.state.style) }, [ renderSlot(_ctx.$slots, "default") ], 6), _cache[4] || (_cache[4] = createTextVNode()), renderSlot(_ctx.$slots, "page"), _cache[5] || (_cache[5] = createTextVNode()), _ctx.paginationVisible && !_ctx.$slots.page ? (openBlock(), createElementBlock("view", { key: 0, class: normalizeClass(_ctx.classesPagination) }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.state.children.length, (item, index) => { return openBlock(), createElementBlock("i", { key: index, style: normalizeStyle({ backgroundColor: _ctx.activePagination === index ? _ctx.paginationColor : _ctx.paginationUnselectedColor }), class: normalizeClass({ active: _ctx.activePagination === index }) }, null, 6); }), 128)) ], 2)) : createCommentVNode("", true) ], 40, _hoisted_1); } const NutSwiper = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { NutSwiper as default };