123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- <template>
- <view :class="[
- 'gui-flex', 'gui-columns', 'gui-sbody',
- fullPage ? 'gui-flex1':'' ,
- refresh || loadmore ? 'gui-flex1' : ''
- ]">
- <!-- 自定义头部 -->
- <view
- class="gui-header gui-transition-all"
- v-if="customHeader"
- id="guiPageHeader"
- ref="guiPageHeader"
- :style="'height:'
- +(headerSets.height+statusBarHeight)+'px; z-index:'
- +headerSets.zIndex+';'+headerStyle">
- <!-- 状态栏 -->
- <view
- class="gui-page-status-bar"
- :style="'height:'+statusBarHeight+'px;'+statusBarStyle"></view>
- <!-- 头部插槽 -->
- <view
- class="gui-flex gui-columns gui-justify-content-center"
- @tap.stop.prevnet="headerTap"
- :style="{height:headerSets.height+'px'}">
- <slot name="gHeader"></slot>
- </view>
- </view>
- <!-- 自定义头部占位 -->
- <view
- v-if="customHeader && isHeaderSized"
- :style="'height:'+(headerSets.height+statusBarHeight)+'px; '+ headerSizedStyle + ';'"></view>
- <!-- 页面主体 -->
- <view
- class="gui-flex gui-columns"
- v-if="!refresh && !loadmore"
- id="guiPageBody"
- ref="guiPageBody"
- :class="[fullPage?'gui-flex1':'']">
- <slot name="gBody"></slot>
- </view>
- <!-- 刷新加载主体 -->
- <view class="gui-flex gui-columns gui-flex1"
- v-if="refresh || loadmore"
- id="guiPageBody"
- ref="guiPageBody"
- :style="{
- marginTop:fixedTopMargin+'px',
- height:refreshBodyHeight+'px'
- }">
- <scroll-view
- class="gui-relative"
- :scroll-y="true"
- :show-scrollbar="false"
- :style="{
- height:refreshBodyHeight+'px',
- opacity:refreshBodyHeight < 1 ? 0 : 1
- }"
- @touchstart="touchstart"
- @touchmove="touchmove"
- @touchend="touchend"
- @scroll="scroll"
- :scroll-top="scrollTop"
- @scrolltolower="loadmorefun">
- <view>
- <gui-refresh
- ref="guiPageRefresh"
- @reload="reload"
- :refreshText="refreshText"
- :refreshBgColor="refreshBgColor"
- :refreshColor="refreshColor"
- :refreshFontSize="refreshFontSize"></gui-refresh>
- </view>
- <slot name="gBody"></slot>
- <view
- v-if="loadmore"
- class="gui-page-loadmore">
- <gui-loadmore
- ref="guipageloadmore"
- :loadMoreText="loadMoreText"
- :loadMoreColor="loadMoreColor"
- :loadMoreFontSize="loadMoreFontSize"></gui-loadmore>
- </view>
- </scroll-view>
- </view>
- <!-- 页面底部 -->
- <!-- 底部占位 -->
- <view v-if="customFooter"
- :style="{height:footerHeight}"></view>
- <view class="gui-page-footer gui-border-box"
- :class="[isSwitchPage?'gui-switch-page-footer':'']"
- v-if="customFooter"
- id="guiPageFooter"
- ref="guiPageFooter"
- :style="{
- height:footerHeight,
- 'background-image':footerSets.bg,
- 'z-index':footerSets.zIndex
- }">
- <view>
- <slot name="gFooter"></slot>
- </view>
- <view
- :style="'height:'+iphoneXButtomHeight+'; '+ iphoneXButtomStyle"></view>
- </view>
- <!-- 右下角悬浮挂件 -->
- <view
- class="gui-page-pendant"
- :style="{
- right:pendantSets.right, bottom:pendantSets.bottom,
- width:pendantSets.width, zIndex:pendantSets.zIndex}">
- <slot name="gPendant"></slot>
- </view>
- <!-- 吸顶元素 -->
- <view
- class="gui-page-fixed-top"
- ref="guiPageFixedTop"
- id="guiPageFixedTop"
- :style="{
- top:fixedTop+'px',
- zIndex:fixedTopZIndex
- }">
- <slot name="gFixedTop"></slot>
- </view>
- <!-- 全屏 loading -->
- <gui-page-loading ref="guipageloading"></gui-page-loading>
- </view>
- </template>
- <script>
- // #ifdef APP-NVUE
- const dom = weex.requireModule('dom');
- // #endif
- export default{
- name : 'gui-page',
- props : {
- fullPage : {type:Boolean, default:false},
- customHeader : {type:Boolean, default:false},
- headerSets : {type:Object , default:function(){return {height:44, zIndex:100}}},
- headerStyle : {type:String , default:'background-color:#FFFFFF;'},
- isHeaderSized : {type:Boolean, default:true},
- statusBarStyle : {type:String , default:'background-color:#FFFFFF;'},
- customFooter : {type:Boolean, default:false},
- footerSets : {type:Object , default:function(){return {height:100, zIndex:100, bg:'linear-gradient(to bottom, #FFFFFF,#FFFFFF)'}}},
- pendantSets : {type:Object , default:function(){return {width:'100rpx', right:'25rpx', bottom:'100rpx', zIndex:100};}},
- isLoading : {type:Boolean, default:false},
- isSwitchPage : {type:Boolean, default:false},
- iphoneXButtomStyle : {type:String, default:''},
- headerSizedStyle : {type:String, default:''},
- fixedTopZIndex : {type:Number, default:2},
- /* 刷新 */
- refresh : {type:Boolean, default:false},
- refreshText : {type:Array, default:function () {
- return ['继续下拉刷新','松开手指开始刷新','数据刷新中','数据已刷新'];
- }},
- refreshBgColor : {type:Array, default:function () {
- return ['#FFFFFF','#FFFFFF','#FFFFFF','#63D2BC'];
- }},
- refreshColor : {type:Array, default:function () {
- return ['rgba(69, 90, 100, 0.6)','rgba(69, 90, 100, 0.6)','#63D2BC','#FFFFFF'];
- }},
- refreshFontSize : {type:String, default:'26rpx'},
-
- /* 加载更多 */
- loadmore : {type:Boolean, default:false},
- loadMoreText : {type:Array, default:function () {
- return ['','更多数据加载中', '已加载全部数据'];
- }},
- loadMoreColor : {type:Array, default:function () {
- return ['rgba(69, 90, 100, 0.6)', 'rgba(69, 90, 100, 0.6)', 'rgba(69, 90, 100, 0.8)'];
- }},
- loadMoreFontSize : {type:String, default:'26rpx'},
- apiLoadingStatus : {type:Boolean, default:false}
- },
- data() {
- return {
- footerHeight : '100rpx',
- iphoneXButtomHeight : '0rpx',
- statusBarHeight : 0,
- // #ifdef APP-NVUE
- animateCount : 0,
- // #endif
- headerTapNumber : 0,
- fixedTop : 0,
- refreshBodyHeight : 0,
- loadMoreTimer : null,
- fixedTopMargin : 0,
- scrollTop : 0,
- srcollTimer : null
- }
- },
-
- mounted:function(){
- if(this.isLoading){
- this.pageLoadingOpen();
- }
- // 刷新相关
- setTimeout(()=>{
- if(this.refresh || this.loadmore){
- this.getDomSize('guiPageBody', (res)=>{
- this.refreshBodyHeight = res.height;
- this.getDomSize('guiPageFixedTop', (res)=>{
- if(res.height){
- this.refreshBodyHeight -= res.height;
- this.fixedTopMargin = res.height;
- }
- })
- });
- }
- },200);
- },
- watch:{
- isLoading : function (val) {
- if(val){
- this.pageLoadingOpen();
- }else{
- this.pageLoadingClose();
- }
- }
- },
- created:function(){
- this.footerHeight = this.footerSets.height + 'rpx';
- // #ifdef H5
- if(this.customHeader){
- this.fixedTop = this.headerSets.height;
- }else{
- this.fixedTop = 44;
- }
- // #endif
- try {
- var system = uni.getSystemInfoSync();
- if(system.model){
- system.model = system.model.replace(' ', '');
- system.model = system.model.toLowerCase();
- this.statusBarHeight = system.statusBarHeight;
- var res1 = system.model.indexOf('iphonex');
- if(res1 > 5){res1 = -1;}
- var res2 = system.model.indexOf('iphone1');
- if(res2 > 5){res2 = -1;}
- if(res1 != -1 || res2 != -1){
- this.iphoneXButtomHeight = '50rpx';
- this.footerHeight = (this.footerSets.height + 50 ) + 'rpx';
- }
- }
- // #ifdef MP-ALIPAY
- this.statusBarHeight = 0;
- // #endif
- // #ifdef APP-PLUS
- this.iphoneXButtomHeight = '0rpx';
- this.footerHeight = this.footerSets.height + 'rpx';
- if(plus.navigator.isFullscreen()){
- this.statusBarHeight = 0;
- }
- // #endif
- if(this.isSwitchPage){
- this.iphoneXButtomHeight = '0rpx';
- this.footerHeight = this.footerSets.height + 'rpx';
- }
- // #ifndef H5
- if(this.customHeader){
- this.fixedTop = this.headerSets.height + this.statusBarHeight;
- }else{
- this.fixedTop = 0;
- }
- // #endif
- } catch (e){return null;}
- },
- methods:{
- pageLoadingOpen : function(){
- this.getRefs('guipageloading',0,(ref)=>{
- this.$refs.guipageloading.open();
- });
- },
- pageLoadingClose : function(){
- this.getRefs('guipageloading',0,(ref)=>{
- ref.close();
- });
- },
- // 下拉刷新相关
- touchstart : function (e){
- if(!this.refresh){return false;}
- if(this.apiLoadingStatus){return false;}
- this.$refs.guiPageRefresh.touchstart(e);
- },
- touchmove : function(e){
- if(!this.refresh){return false;}
- if(this.apiLoadingStatus){return false;}
- this.$refs.guiPageRefresh.touchmove(e);
- },
- touchend : function (e) {
- if(!this.refresh){return false;}
- if(this.apiLoadingStatus){return false;}
- this.$refs.guiPageRefresh.touchend(e);
- },
- scroll:function(e){
- if(this.srcollTimer != null){
- clearTimeout(this.srcollTimer);
- }
- this.srcollTimer = setTimeout(()=>{
- this.$refs.guiPageRefresh.scroll(e);
- this.$emit('scroll', e);
- this.scrollTop = e.detail.scrollTop;
- }, 100);
- },
- setScrollTop : function (scrollTop){
- this.scrollTop = scrollTop;
- },
- endReload : function(){
- this.$refs.guiPageRefresh.endReload();
- },
- reload : function(){
- if(this.apiLoadingStatus){return false;}
- this.$emit('reload');
- if(this.loadmore){this.$refs.guipageloadmore.stoploadmore();}
- },
- // 获取元素尺寸
- getDomSize : function(domIDOrRef, fun, count){
- if(!count){count = 1;}
- if(count >= 50){
- fun({width:0, height:0});
- return false;
- }
- // #ifndef APP-NVUE
- uni.createSelectorQuery().in(this).select('#'+domIDOrRef).boundingClientRect().exec((res)=>{
- if(res[0] == null){
- count += 1;
- setTimeout(()=>{this.getDomSize(domIDOrRef, fun, count);}, 50);
- }else{
- fun(res[0]);
- return ;
- }
- });
- // #endif
- // #ifdef APP-NVUE
- var el = this.$refs[domIDOrRef];
- dom.getComponentRect(el, (res) => {
- if(res.result == false){
- count += 1;
- setTimeout(()=>{this.getDomSize(domIDOrRef, fun, count);}, 50);
- }else{
- fun(res.size);
- return ;
- }
- });
- // #endif
-
- },
- stopfun : function(e){e.stopPropagation(); return null;},
- headerTap : function(){
- this.headerTapNumber ++;
- if(this.headerTapNumber >= 2){
- this.$emit('gotoTop');
- this.headerTapNumber = 0;
- }else{
- setTimeout(()=>{this.headerTapNumber = 0;}, 1000);
- }
- },
- getRefs : function(ref, count, fun){
- if(count >= 50){
- fun(this.$refs[ref]);
- return false;
- }
- var refReturn = this.$refs[ref];
- if(refReturn){
- // #ifdef APP-NVUE
- fun(refReturn);
- return;
- // #endif
- // #ifndef APP-NVUE
- if(refReturn._data){
- fun(refReturn);
- return;
- }
- // #endif
- }else{
- count++;
- setTimeout(()=>{
- this.getRefs(ref, count, fun);
- }, 100);
- }
- },
- loadmorefun : function () {
- if(!this.loadmore){return false;}
- if(this.apiLoadingStatus){return false;}
- // 获取加载组件状态看一下是否还能继续加载
- // 保证触底只执行一次加载
- if(this.loadMoreTimer != null){clearTimeout(this.loadMoreTimer);}
- this.loadMoreTimer = setTimeout(() => {
- var status = this.$refs.guipageloadmore.loadMoreStatus;
- if(status != 0){return null;}
- this.$refs.guipageloadmore.loading();
- this.$emit('loadmorefun');
- }, 80);
- },
- stoploadmore : function(){
- this.$refs.guipageloadmore.stoploadmore();
- },
- nomore : function () {
- this.$refs.guipageloadmore.nomore();
- }
- }
- }
- </script>
- <style scoped>
- .gui-sbody{width:750rpx;}
- .gui-page-loading{width:750rpx; position:fixed; left:0; top:0; bottom:0; flex:1; z-index:99999;}
- .gui-page-loading-points{width:20rpx; height:20rpx; border-radius:50rpx; margin:10rpx;}
- /* #ifndef APP-NVUE */
- .gui-sbody{min-height:calc(100vh - var(--window-top) - var(--window-bottom));}
- @keyframes pageLoading1{0% {opacity:0.5; transform:scale(1);} 40% {opacity:1; transform:scale(1.5);} 60%{opacity:0.5; transform:scale(1);}}
- @keyframes pageLoading2{20% {opacity:0.5; transform:scale(1);} 60% {opacity:1; transform:scale(1.5);} 80% {opacity:0.5; transform:scale(1);}}
- @keyframes pageLoading3{40% {opacity:0.5; transform:scale(1);} 80% {opacity:1; transform:scale(1.5);} 100% {opacity:0.5; transform:scale(1);}}
- .animate1{animation:pageLoading1 1.2s infinite linear;}
- .animate2{animation:pageLoading2 1.2s infinite linear;}
- .animate3{animation:pageLoading3 1.2s infinite linear;}
- /* #endif */
- .gui-header{width:750rpx; position:fixed; left:0; top:0;}
- .gui-page-footer{width:750rpx; position:fixed; left:0; bottom:0;}
- /* #ifdef H5 */
- .gui-switch-page-footer{bottom:50px;}
- /* #endif */
- .gui-page-status-bar{width:750rpx;}
- .gui-page-pendant{position:fixed;}
- .gui-page-fixed-top{position:fixed; top:44px; left:0px; width:750rpx; z-index:99998; overflow:hidden;}
- .gui-page-loadmore{padding-bottom:30rpx;}
- </style>
|