UNPKG

vue3-multi-tab-swiper

Version:

### 介绍

2 lines (1 loc) 8.69 kB
(function(e,L){typeof exports=="object"&&typeof module<"u"?module.exports=L(require("vue")):typeof define=="function"&&define.amd?define(["vue"],L):(e=typeof globalThis<"u"?globalThis:e||self,e.Vue3MultiTabSwiper=L(e.Vue))})(this,function(e){"use strict";const L=(d,S)=>{const h=d.__vccOpts||d;for(const[m,l]of S)h[m]=l;return h},X=["onClick"],H=L({__name:"Tab",props:{tabs:{type:Array,default:()=>[]},tabIndex:{type:Number,default:0}},emits:["tabChange"],setup(d,{emit:S}){const h=d,m=S;let l=e.ref(0);const n=a=>{l.value=a};e.watch(()=>l.value,a=>{m("tabChange",a)});const s=e.ref(),r=e.ref([]),u=a=>{a&&r.value.push(a)},g=a=>a.offsetWidth+_(a,"marginLeft")+_(a,"marginRight")+2*_(a,"borderWidth"),_=(a,i)=>+window.getComputedStyle(a)[i].replace("px","");return e.watch(()=>h.tabIndex,a=>{l.value=a;let i=r.value[l.value],t=i.offsetLeft+g(i)-s.value.offsetWidth>0?i.offsetLeft+g(i)-s.value.offsetWidth:0;s.value.scrollTo({left:t,behavior:"smooth"})}),(a,i)=>(e.openBlock(),e.createElementBlock("div",{class:"tabs scroll-tabs",ref_key:"tabsWrapper",ref:s},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(d.tabs,(t,f)=>(e.openBlock(),e.createElementBlock("span",{ref_for:!0,ref:u,key:f,class:e.normalizeClass(["tab-item",{active:f===e.unref(l)}]),onClick:v=>n(f)},e.toDisplayString(t),11,X))),128))],512))}},[["__scopeId","data-v-ae81a61b"]]),V=L({__name:"Swiper",props:{swiperIndex:{type:Number,default:0},loadingEnd:{type:Boolean,default:!1}},emits:["slideChange"],setup(d,{expose:S,emit:h}){const m=d;let l=0,n=e.ref(0);const s=e.ref(),r=e.ref();let u=[],g=0;const _=e.computed(()=>l*n.value),a=h;let i=e.reactive([]);e.onMounted(()=>{l=s.value.offsetWidth,n.value=r.value.children.length,u=Array.from(r.value.children),u.forEach(o=>{o.style.width=l+"px"}),g=document.getElementById("bannerContent").clientHeight,r.value.style.height=u[0].clientHeight+"px",i=new Array(n.value).fill(0)});let t=e.ref(0),f=e.ref(0),v=e.ref(0),E=e.ref(0),y=e.ref(0),R=e.ref(0),b=!1;const C=e.computed(()=>-t.value*l+R.value),k=o=>{f.value=o.targetTouches[0].clientX,v.value=o.targetTouches[0].clientY,E.value=0,y.value=0,b=!1},c=()=>{if(R.value=0,E.value===0||y.value===0)return;let o=Math.abs(f.value-E.value);E.value<f.value&&o>100&&t.value<n.value-1&&t.value++,E.value>f.value&&o>100&&t.value>0&&t.value--},x=o=>{E.value=o.targetTouches[0].clientX,y.value=o.targetTouches[0].clientY;let T=E.value-f.value,I=y.value-v.value;if(!(Math.abs(T)>Math.abs(I))){O()||N(u,t.value);return}let w=Math.abs(f.value-E.value);w<30||(E.value<f.value&&t.value<n.value-1&&(R.value=-w,O()&&!b&&(A(u,t.value,t.value+1),b=!0)),E.value>f.value&&t.value>0&&(R.value=w,O()&&!b&&(A(u,t.value,t.value-1),b=!0)))},A=(o,T,I)=>{let w=document.documentElement.scrollTop-g;i[T]=w,o.forEach(($,G)=>{if(G!==T){let K=i[G]||0;$.style.marginTop=`${-K+w}px`}})},N=(o,T)=>{o.forEach((I,w)=>{w!==T&&(I.style.marginTop="0px")}),i=new Array(n.value).fill(0)};e.watch(()=>t.value,o=>{a("slideChange",o)}),e.watch(()=>m.swiperIndex,(o,T)=>{if(t.value=o,O()){let I=document.documentElement.scrollTop-g;i[T]=I,r.value.style.height=u[o].clientHeight+"px",u.forEach((w,$)=>{w.style.marginTop="0px"}),document.documentElement.scrollTop=g+(i[o]||0)}}),e.watch(()=>m.loadingEnd,o=>{o&&e.nextTick(()=>{r.value.style.height=u[t.value].clientHeight+"px"})});const J=()=>u.length,O=()=>document.documentElement.scrollTop>=g;return S({getSwiperLength:J}),(o,T)=>(e.openBlock(),e.createElementBlock("div",{class:"swiper",ref_key:"swiper",ref:s,onTouchstartPassive:k,onTouchendPassive:c,onTouchmovePassive:x},[e.createElementVNode("div",{class:"swiper-item",ref_key:"swiperList",ref:r,style:e.normalizeStyle({width:_.value+"px",transform:"translateX("+C.value+"px)"})},[e.renderSlot(o.$slots,"default",{},void 0,!0)],4)],544))}},[["__scopeId","data-v-d55aacb3"]]),p={PULLING:"pulling",RELEASING:"releasing",REFRESHING:"refreshing",REFRESHED:"refreshed"},M={LOAD_MORE:"loadMore",LOADING:"loading",NO_MORE_DATA:"noMoreData"},P={class:"scroll-view"},F={class:"content"},Y={class:"loading-text"},W={class:"main-content"},U={class:"load-more-text"},D=100,z=L({__name:"ScrollView",props:{loadingEnd:{type:Boolean,default:!1},hasMore:{type:Boolean,default:!0},noMoreDataText:{type:String,default:"没有更多数据"}},emits:["pulldownRefresh","pullupLoadMore"],setup(d,{emit:S}){const h=d,m=S;let l=e.ref(!0),n=e.ref(p.PULLING),s=e.ref(M.LOAD_MORE),r=e.ref(0),u=e.computed(()=>{switch(n.value){case p.PULLING:return"下拉刷新";case p.RELEASING:return"松手刷新";case p.REFRESHING:return"刷新中";case p.REFRESHED:return"刷新成功"}}),g=e.computed(()=>{switch(s.value){case M.LOAD_MORE:return"上拉加载更多";case M.LOADING:return"加载中";case M.NO_MORE_DATA:return"没有更多数据啦"}});e.watch(()=>h.loadingEnd,c=>{c&&(l.value?s.value=M.LOAD_MORE:(n.value=p.REFRESHED,r.value=0))}),e.watch(()=>h.hasMore,c=>{c?s.value=M.LOAD_MORE:s.value=M.NO_MORE_DATA});let _=e.ref(0),a=e.ref(0),i=e.ref(0),t=e.ref(0),f=e.ref(!1);const v=c=>{n.value!==p.REFRESHING&&(n.value=p.PULLING,_.value=c.targetTouches[0].clientX,a.value=c.targetTouches[0].clientY,f.value=document.documentElement.scrollTop===0)},E=c=>{if(n.value===p.REFRESHING)return;i.value=c.targetTouches[0].clientX,t.value=c.targetTouches[0].clientY;let x=i.value-_.value,A=t.value-a.value;if(!(Math.abs(x)>Math.abs(A))&&!(a.value>t.value)&&f.value){r.value=Math.abs(t.value-a.value);let N=(100-r.value*.5)/100;N=Math.max(.5,N),r.value=r.value*N,r.value<50?n.value=p.PULLING:n.value=p.RELEASING,r.value>D&&(r.value=D)}},y=c=>{if(r.value<50){r.value=0;return}l.value=!1,setTimeout(()=>{m("pulldownRefresh")},500),n.value=p.REFRESHING},R=e.ref();let b=null;const C=()=>{document.addEventListener("touchstart",v),document.addEventListener("touchmove",E),document.addEventListener("touchend",y),b=new IntersectionObserver(([c])=>{c.isIntersecting&&s.value===M.LOAD_MORE&&(l.value=!0,setTimeout(()=>{m("pullupLoadMore")},500),s.value=M.LOADING)}),b.observe(R.value)},k=()=>{document.removeEventListener("touchstart",v),document.removeEventListener("touchmove",E),document.removeEventListener("touchend",y),b.disconnect()};return e.onMounted(()=>{C()}),e.onBeforeUnmount(()=>{k()}),(c,x)=>(e.openBlock(),e.createElementBlock("div",P,[e.createElementVNode("div",F,[e.createElementVNode("div",{style:e.normalizeStyle({height:`${e.unref(r)}px`}),class:e.normalizeClass(["pull-up-refresh",{animation:e.unref(n)==e.unref(p).REFRESHED||e.unref(n)==e.unref(p).PULLING&&!e.unref(r)}])},[e.renderSlot(c.$slots,"refresh-indicator",{state:e.unref(n)},()=>[e.createElementVNode("span",Y,e.toDisplayString(e.unref(u)),1)],!0)],6),e.createElementVNode("div",W,[e.renderSlot(c.$slots,"default",{},void 0,!0),e.createElementVNode("div",{class:e.normalizeClass(["pull-down-load-more"]),ref_key:"loadMore",ref:R},[e.renderSlot(c.$slots,"load-more-indicator",{state:e.unref(s)},()=>[e.createElementVNode("span",U,e.toDisplayString(e.unref(g)),1)],!0)],512)])])]))}},[["__scopeId","data-v-0b7ee9f1"]]),j={class:"banner-content",id:"bannerContent"},q={class:"tabs-wrapper"},B=L({__name:"index",props:{tabs:{type:Array,default:()=>[]},loadingEnd:{type:Boolean,default:!1},hasMore:{type:Boolean,default:!0}},emits:["pulldownRefresh","pullupLoadMore","activeChange"],setup(d,{emit:S}){const h=d,m=S;let l=e.ref(0),n=e.ref(h.hasMore),s=new Array(h.tabs.length).fill(!0);s[l]=h.hasMore;const r=t=>{n.value=s[t],l.value=t},u=t=>{n.value=s[t],l.value=t};e.watch(()=>l.value,t=>{m("activeChange",t)}),e.watch(()=>h.hasMore,t=>{n.value=t,s[l.value]=t});const g=()=>{m("pulldownRefresh")},_=()=>{m("pullupLoadMore")},a=e.ref(),i=()=>{if(!(h.tabs.length===a.value.getSwiperLength()))throw new Error("The number of tabs and swipers does not match")};return e.onMounted(()=>{i()}),(t,f)=>(e.openBlock(),e.createBlock(z,{hasMore:e.unref(n),loadingEnd:d.loadingEnd,onPulldownRefresh:g,onPullupLoadMore:_},{"refresh-indicator":e.withCtx(({state:v})=>[e.renderSlot(t.$slots,"refresh-indicator",{state:v},void 0,!0)]),"load-more-indicator":e.withCtx(({state:v})=>[e.renderSlot(t.$slots,"load-more-indicator",{state:v},void 0,!0)]),default:e.withCtx(()=>[e.createElementVNode("div",j,[e.renderSlot(t.$slots,"banner-content",{},void 0,!0)]),e.createElementVNode("div",q,[e.createVNode(H,{tabs:d.tabs,tabIndex:e.unref(l),onTabChange:u},null,8,["tabs","tabIndex"])]),e.createVNode(V,{loadingEnd:d.loadingEnd,swiperIndex:e.unref(l),onSlideChange:r,ref_key:"swiperRef",ref:a},{default:e.withCtx(()=>[e.renderSlot(t.$slots,"default",{},void 0,!0)]),_:3},8,["loadingEnd","swiperIndex"])]),_:3},8,["hasMore","loadingEnd"]))}},[["__scopeId","data-v-e3e9e46f"]]);return{install(d){d.component("MultiTabSwiper",B)},MultiTabSwiper:B}});