vue滚动分页加载以及监听事件处理
1 <template> 2 <div class="bodyContainer"> 3 <div class="allContent" id="pageTop"> 4 <!-- 经纪人 --> 5 <div class="brokerBlock" v-show="isBroker && !loading"> 6 <broker :list="brokerInfo" v-show="Object.keys(brokerInfo).length>0" @change="protocolClick" @remove="reomoveBrokerClick"></broker> 7 </div> 8 <!-- 我的艺人 --> 9 <div class="con artistCon" v-show="artistTotal > 0"> 10 <div class="title " :class="{isFixed:!isBroker}" id="artistTitle"> 11 我的艺人<span class="gray">({{artistTotal}}位)</span> 12 </div> 13 <ul class="artistList"> 14 <li class="box artistItem" v-for="item of artistInfoList" :key="item.userInfo.userId" > 15 <div class="personBlock"> 16 <div class="person" @click="openUserClick(item.userInfo.userId)"> 17 <div class="showImg"> 18 <img :src="item.userInfo.userThumUrl" /> 19 <template v-if="item.userInfo.kolFlag"> 20 <div class="icon c_kol" v-if="item.userInfo.kolFlag"></div> 21 </template> 22 <template v-else> 23 <div class="icon c_company" v-if="item.userInfo.upSignType == '1'"></div> 24 <div class="icon c_person" v-if="item.userInfo.upSignType == '0'"></div> 25 </template> 26 </div> 27 <div class="name" :class="{artistName:item.isRelease || item.status>=1}">{{item.userInfo.nickName}}</div> 28 <div class="situation" v-if="item.isRelease">关系已解除</div> 29 <div class="situation" v-if="item.status == 1">帐号已冻结</div> 30 <div class="situation" v-if="item.status == 2">帐号已暂停</div> 31 </div> 32 <div class="action" v-if="item.userInfo"> 33 <em class="chatIcon" v-if="item.userInfo.userId" @click="openChatClick(item.userInfo.userId)"></em> 34 <em v-if="!item.isRelease" class="revisionIcon" @click="revisionClick(item)"></em> 35 <em v-if="!item.isRelease" class="removeIcon" @click="removeArtistClick(item.userInfo.hwUserId)"></em> 36 </div> 37 </div> 38 <div v-if="!item.isRelease" class="works">本周作品更新 {{item.weekOpusNum}}</div> 39 <div class="divideInfo" v-if="!item.isRelease"> 40 <span v-if="item.shareRate">TA的分成占比{{item.shareRate}}</span> 41 <span v-if="item.shareAmount">· 累计分取 {{regFenToYuan(item.shareAmount)}}</span> 42 </div> 43 <div class="divideInfo" v-if="item.isRelease && item.shareAmount"> 44 <span>累计分得{{regFenToYuan(item.shareAmount)}}</span> 45 </div> 46 <div v-if="item.isRelease" class="inviteAgainBtn" :class="{active:successInvite.indexOf(item.userInfo.hwUserId) > -1 }" @click="inviteClick(item.userInfo.hwUserId)">重新邀请</div> 47 <div class="tips" v-if="item.remark">{{item.remark}}</div> 48 <div v-if="!item.isRelease" class="protocol" @click="protocolClick">合作协议</div> 49 </li> 50 </ul> 51 <!-- 上拉加载 --> 52 <div class="loadTxt"><em v-if="lock" class="rotate"></em>{{loadTxt}}</div> 53 </div> 54 <!-- 全局加载 --> 55 <div class="loadContainer" v-if="loading"><em class="rotate"></em>正在加载中...</div> 56 <!-- 数据为空 --> 57 <empty v-if="Object.keys(brokerInfo).length < 1 && artistTotal < 1 && !loading"> 58 <p class="note">你还没有经纪人和艺人哦</p> 59 <router-link class="invite" :to="inviteLink">邀请艺人</router-link> 60 </empty> 61 </div> 62 63 <router-link class="rule" :to="ruleLink">查看规则</router-link> 64 <div class="inviteBlock" v-if="Object.keys(brokerInfo).length > 0 || artistTotal > 0"> 65 <router-link class="inviteArtistBtn" :to="inviteLink">邀请艺人</router-link> 66 </div> 67 <!-- 协议弹出层 --> 68 <pop-up @change="closeLayer" v-if="popuShow"> 69 <template v-if="protocolPopShow"> 70 <h2 class="title">{{protocolTitle}}</h2> 71 <div class="content" v-html="protocolCon"></div> 72 <div class="confirmBtn" @click="closeNoClick">确认</div> 73 </template> 74 <template v-else-if="actionPopShow"> 75 <h2 class="title">{{protocolTitle}}</h2> 76 <div class="content" v-html="protocolCon"></div> 77 <div class="confirmBtn" :class="{active:isActive}" @click="confirmProtocol">{{btntxt}}</div> 78 <div class="popCloseCon" @click="closeActionClick"></div> 79 </template> 80 <template v-else-if="removePopshow"> 81 <div class="content center"> 82 解除关系后经纪人将不再获得艺人的收益分成,对方同意后将在下个结算账期生效 83 </div> 84 <div class="action"> 85 <div class="btn confirmRemove" @click="confirmRemoveClick">确认解除</div><div class="btn noConfirmRemove" @click="closeLayer">我再想想</div> 86 </div> 87 </template> 88 </pop-up> 89 <!-- 比例弹出层 --> 90 <scale @change="closeScale" @send="sendAjaxClick" :number="scaleCount" :scaleBtn="scaleBtn" :scaleDesc="scaleDesc" v-show="isScale" :userId="userId"></scale> 91 </div> 92 </template> 93 <script> 94 import broker from './components/broker'; 95 import empty from './components/empty'; 96 import PopUp from './components/PopUp'; 97 import scale from './components/scale'; 98 const pageSize=6; 99 let t=''; 100 export default { 101 name: "Index", 102 data() { 103 return { 104 popuShow:false, //弹窗展示 105 protocolPopShow:false,//经纪人协议 106 actionPopShow:false,//操作协议层 107 removePopshow:false,//解除确认操作层 108 isScale:false,//比例弹出层 109 ruleLink: '/rule.html', 110 inviteLink:'/search.html', 111 userId:'', 112 isActive:true,//操作协议按钮灰色显示 113 sencond:5,//秒数 114 btntxt:'', //操作协议层按钮文字显示 115 scaleValue:'',//分成比例 116 scaleDesc:'',//比例弹窗描述 117 scaleBtn:'', 118 scaleCount:'50%', 119 personValue:'',//艺人还是经纪人 120 brokerInfo:{}, //经纪人列表 121 artistInfoList:[], //查询艺人列表 122 artistTotal:0,//查询艺人列表总数 123 isShow:false, // 是否显示滚动条 124 successInvite:[],//发送邀请成功的华为id取数 125 totalPage:1, 126 paramsValue:[], 127 searchBarFixed:'', 128 isBroker:true, 129 offsetTop:0, 130 loading: true, //一开始页面就要加载 131 pageNo:1,//当前页 132 lock : false, //当在请求数据时,滚动时锁定不能再发送分页请求 133 loadTxt:'' , 134 protocolTitle:'',//协议标题 135 protocolCon:'' //协议内容 136 }; 137 }, 138 components:{broker,empty,PopUp,scale}, 139 mounted: function () { 140 this.protocolAjax(); 141 this.broker(); 142 this.featchData(); 143 144 window.addEventListener('scroll', this.handleScroll); 145 }, 146 watch:{ 147 $route(to,from){ 148 window.scrollTo(0,20); 149 if(to.name == 'index'){ 150 window.addEventListener('scroll', this.handleScroll); 151 } else { 152 window.removeEventListener('scroll', this.handleScroll) 153 } 154 } 155 }, 156 methods: { 157 handleScroll () { 158 let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;//滚动条滚动的长度 159 let _offsetHeight = document.querySelector('#pageTop').offsetHeight; //是指元素内容的高度 160 let brokeHeight = document.querySelector('.brokerBlock').offsetHeight; //经纪人内容高度 161 let clientHeightValue = document.documentElement.clientHeight || document.body.clientHeight; 162 163 console.log("scrollTop",scrollTop,"_offsetHeight",_offsetHeight,"brokeHeight",brokeHeight,"clientHeightValue",clientHeightValue) 164 if(scrollTop > brokeHeight){ //滚动条滚动的距离超过经纪人的内容高度 165 this.isBroker = false; 166 }else{ 167 this.isBroker = true; 168 } 169 if(this.pageNo > 1){ 170 //距离底部距离50就加载数据 171 if(_offsetHeight - clientHeightValue - scrollTop <= 50 ){ 172 if (this.totalPage <= this.pageNo) { 173 setTimeout(() => { 174 //mui.toast("已经没有更多了~"); 175 this.loadTxt='当当当~已经到底啦~'; 176 }, 300) 177 return; 178 }else{ 179 this.featchData(); 180 } 181 } 182 } 183 }, 184 //获取数据函数 185 featchData:function (){ 186 //如果已经在加载数据,不可以重复加载 187 if (this.lock) return; 188 this.lock = true; 189 this.loadTxt='正在加载中...'; 190 this.$request.post(_basePath + '/activity/page20191018/queryArtistList.html',{pageNo:this.pageNo,pageSize:pageSize}).then((res) => { 191 this.artistTotal = res.total; 192 193 this.totalPage = res.total % pageSize > 0 ? Math.floor(res.total / pageSize + 1) : res.total / pageSize; 194 let result = []; 195 res.artistInfoList.forEach((item) =>{ 196 result.push(item.userInfo.hwUserId) 197 }) 198 this.$request.post(_basePath + '/activity/page20191018/batchQueryUserAccount.html',{userIdList:result}).then((res2) => { 199 res2.userAccountDetailList.forEach((item,i) =>{ 200 res.artistInfoList[i].status = item.status; 201 }) 202 this.artistInfoList = res.artistInfoList; 203 }).catch(() => {}); 204 205 this.artistInfoList = [...this.artistInfoList, ...res.artistInfoList]; 206 ++this.pageNo; 207 this.lock = false; 208 this.loading = false; 209 this.loadTxt=''; 210 }).catch(() => { 211 this.lock = false; 212 this.loading = false; 213 }) 214 }, 215 //查询经纪人列表 216 broker () { 217 this.$request.post(_basePath + '/activity/page20191018/queryBroker.html').then((res) => { 218 let result = []; 219 result.push(res.brokerInfo.userInfo.hwUserId) 220 this.$request.post(_basePath + '/activity/page20191018/batchQueryUserAccount.html',{userIdList:result}).then((res2) => { 221 res.brokerInfo.status = res2.userAccountDetailList[0].status; 222 this.brokerInfo = res.brokerInfo; 223 }).catch(() => {}); 224 }).catch(() => {}) 225 }, 226 //点击调起个人主页 227 openUserClick (item) { 228 console.log(item) 229 var userId = item; 230 mui.openClient({"pageType": "userHome","userId":item}); 231 }, 232 //点击调起聊天窗口 233 openChatClick (item){ 234 console.log(item) 235 var userId = item; 236 mui.openClient({"pageType": "chat","userId":item}); 237 }, 238 //艺人解除关系 239 removeArtistClick (id) { 240 //1:艺人,0 – 不是(只是校验是否可以解约 241 this.userId = id; 242 this.personValue = 1; 243 this.releaseRelationship (1,0); 244 }, 245 //经纪人解除关系 246 reomoveBrokerClick (id) { 247 this.userId = id; 248 this.personValue = 0; 249 this.releaseRelationship (0,0); 250 }, 251 //重新调整分成比例 252 revisionClick (item) { 253 this.isScale = true; 254 this.userId = item.userInfo.hwUserId; 255 this.scaleCount = item.shareRate; 256 this.scaleDesc = '调整分成需对方确认,选择双方都认可的分成比例可以提高调整成功率哦~'; 257 this.scaleBtn = '确认调整'; 258 }, 259 //重新邀请 260 inviteClick (id) { 261 if(this.successInvite.indexOf(id) > -1){ 262 return; 263 } 264 this.isScale = true; 265 this.userId = id; 266 this.scaleDesc = '邀请成功后你可获取该用户部分收益,选择双方都认可的分成比例可以提高邀请成功率哦~'; 267 this.scaleBtn = '发送邀请'; 268 this.scaleCount = '50%';//邀请比例统一为50% 269 }, 270 //点击发送邀请 271 sendAjaxClick (value){ 272 273 this.scaleValue = value; 274 this.popuShow = true; 275 this.actionPopShow = true;//操作协议层展示 276 this.isScale = false; 277 this.isActive = true; 278 this.sencond = 5 ; 279 this.timer(); 280 }, 281 //5s时间倒计时 282 timer () { 283 if (this.sencond > 0) { 284 if(this.scaleDesc.indexOf("调整") > -1){ 285 this.btntxt="已阅读同意并确认调整("+this.sencond+"s)"; 286 }else{ 287 this.btntxt="已阅读同意并确认邀请("+this.sencond+"s)"; 288 } 289 this.sencond--; 290 t=setTimeout(this.timer, 1000); 291 } else{ 292 this.isActive = false; 293 this.sencond = 5; 294 if(this.scaleDesc.indexOf("调整") > -1){ 295 this.btntxt="已阅读同意并确认调整"; 296 }else{ 297 this.btntxt="已阅读同意并确认邀请"; 298 } 299 300 } 301 }, 302 //已阅读同意并确认 303 confirmProtocol () { 304 if(this.isActive){ 305 return false; 306 } 307 if(this.scaleDesc.indexOf("调整") > -1){ 308 //比例调整请求 309 this.revisionAjax(); 310 }else{ 311 //邀请请求 312 this.sendAjax(); 313 } 314 315 }, 316 //发送邀请请求 317 sendAjax () { 318 this.$request.post(_basePath + '/activity/page20191018/inviteArtist.html',{userId: this.userId,shareRate:this.scaleValue}).then((res) => { 319 mui.toast("已发送邀请,对方接受后会通知你哦",2000); 320 this.successInvite.push(this.userId); 321 this.closeActionClick(); 322 }).catch(() => {}) 323 }, 324 //调整比例请求 325 revisionAjax () { 326 this.$request.post(_basePath + '/activity/page20191018/adjustShareRate.html',{userId: this.userId,shareRate:this.scaleValue}).then((res) => { 327 mui.toast("已发送调整消息,对方接受后会通知你哦",2000); 328 this.closeActionClick(); 329 }).catch(() => {}) 330 }, 331 //解除关系操纵请求 332 releaseRelationship (a,b) { 333 //a 0:经纪人 1艺人 334 //b 0:校验 1:可以解约请求 335 this.$request.post(_basePath + '/activity/page20191018/releaseRelationship.html',{userId: this.userId,role:a,realRelease:b}).then((res) => { 336 // mui.toast("已发送解除消息,对方接受后会通知你哦",2000); 337 if(res.releaseStatus == '0'){ //不能解约 338 mui.toast(res.remark,2000) 339 }else if(res.releaseStatus == 1){ //可解约 340 this.popuShow = true; 341 this.actionPopShow = false; 342 this.protocolPopShow = false; 343 this.removePopshow = true; 344 }else if(res.releaseStatus == 2){ 345 mui.toast("已发送解除消息,对方接受后会通知你哦",2000); 346 } 347 }).catch(() => {}) 348 }, 349 //确认解除 350 confirmRemoveClick(){ 351 this.closeLayer(); 352 console.log(this.personValue); 353 this.releaseRelationship (this.personValue,1) 354 }, 355 356 //关闭操作协议弹窗 357 closeActionClick() { 358 this.popuShow = false; 359 this.actionPopShow = false; 360 clearTimeout(t);//清除倒计时 361 }, 362 //点击合作协议 363 protocolClick(){ 364 this.protocolPopShow = true; 365 this.popuShow = true; 366 }, 367 368 //关闭弹窗 369 closeLayer(){ 370 this.popuShow = false; 371 this.actionPopShow = false; 372 this.protocolPopShow = false; 373 this.removePopshow = false; 374 clearTimeout(t);//清除倒计时 375 }, 376 //关闭解除操作确认 377 closeNoClick () { 378 this.popuShow = false; 379 this.protocolPopShow = false; 380 }, 381 //关闭分成比例弹窗 382 closeScale(){ 383 this.isScale = false; 384 }, 385 //分转为元 386 regFenToYuan (fen) { 387 var num = fen; 388 num=fen*0.01; 389 num+=''; 390 var reg = num.indexOf('.') >-1 ? /(\d{1,3})(?=(?:\d{3})+\.)/g : /(\d{1,3})(?=(?:\d{3})+$)/g; 391 num=num.replace(reg,'$1'); 392 num = this.toDecimal2(num) 393 return num 394 }, 395 toDecimal2 (x) { 396 var f = parseFloat(x); 397 if (isNaN(f)) { 398 return false; 399 } 400 var f = Math.round(x * 100) / 100; 401 var s = f.toString(); 402 var rs = s.indexOf('.'); 403 if (rs < 0) { 404 rs = s.length; 405 s += '.'; 406 } 407 while (s.length <= rs + 2) { 408 s += '0'; 409 } 410 return s; 411 }, 412 //协议请求 413 protocolAjax() { 414 this.$request.post(_basePath + '/activity/page20191018/queryProtocol.html',{type:0}).then((res) => { 415 this.protocolTitle = res.title; 416 this.protocolCon = res.content; 417 }).catch(() => {}) 418 } 419 }, 420 destroyed() { 421 window.removeEventListener('scroll', this.handleScroll) 422 } 423 }; 424 </script> 425 426 <style lang="scss" scoped> 427 @import "index"; 428 .artistCon{padding-bottom:1.8rem;} 429 .loadTxt{ 430 margin-top:.2rem; 431 height:.4rem; 432 line-height:.4rem; 433 text-align:center; 434 color:#B6B3C5; 435 font-size:.24rem; 436 } 437 438 .allContent{ 439 overflow:auto; 440 -webkit-overflow-scrolling: touch; 441 442 } 443 #pageTop{ 444 .isFixed{ 445 position:fixed; 446 top:0; 447 z-index:100; 448 height:.9rem; 449 background: #121223; 450 width:100%; 451 } 452 } 453 </style>
注意事项
1、监听滚动处理scroll
1 mounted: function () { 2 this.protocolAjax(); 3 this.broker(); 4 this.featchData(); 5 6 window.addEventListener('scroll', this.handleScroll); 7 },
2、跳到另外一个页面再此返回手机上会出现一个黑屏,触摸才会把黑屏去掉,解决办法就是在返回页面的时候,再滚动到顶部
1 watch:{ 2 $route(to,from){ 3 window.scrollTo(0,20); 4 if(to.name == 'index'){ 5 window.addEventListener('scroll', this.handleScroll); 6 } else { 7 window.removeEventListener('scroll', this.handleScroll) 8 } 9 } 10 },
3、scroll完以后要destroy
1 destroyed() { 2 window.removeEventListener('scroll', this.handleScroll) 3 }
4、分页滚动处理
1 //获取数据函数 2 featchData:function (){ 3 //如果已经在加载数据,不可以重复加载 4 if (this.lock) return; 5 this.lock = true; 6 this.loadTxt='正在加载中...'; 7 this.$request.post(_basePath + '/activity/page20191018/queryArtistList.html',{pageNo:this.pageNo,pageSize:pageSize}).then((res) => { 8 this.artistTotal = res.total; 9 10 this.totalPage = res.total % pageSize > 0 ? Math.floor(res.total / pageSize + 1) : res.total / pageSize; 11 let result = []; 12 res.artistInfoList.forEach((item) =>{ 13 result.push(item.userInfo.hwUserId) 14 }) 15 this.$request.post(_basePath + '/activity/page20191018/batchQueryUserAccount.html',{userIdList:result}).then((res2) => { 16 res2.userAccountDetailList.forEach((item,i) =>{ 17 res.artistInfoList[i].status = item.status; 18 }) 19 this.artistInfoList = res.artistInfoList; 20 }).catch(() => {}); 21 22 this.artistInfoList = [...this.artistInfoList, ...res.artistInfoList]; 23 ++this.pageNo; 24 this.lock = false; 25 this.loading = false; 26 this.loadTxt=''; 27 }).catch(() => { 28 this.lock = false; 29 this.loading = false; 30 }) 31 },
1 handleScroll () { 2 let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;//滚动条滚动的长度 3 let _offsetHeight = document.querySelector('#pageTop').offsetHeight; //是指元素内容的高度 4 let brokeHeight = document.querySelector('.brokerBlock').offsetHeight; //经纪人内容高度 5 let clientHeightValue = document.documentElement.clientHeight || document.body.clientHeight; 6 7 console.log("scrollTop",scrollTop,"_offsetHeight",_offsetHeight,"brokeHeight",brokeHeight,"clientHeightValue",clientHeightValue) 8 if(scrollTop > brokeHeight){ //滚动条滚动的距离超过经纪人的内容高度 9 this.isBroker = false; 10 }else{ 11 this.isBroker = true; 12 } 13 if(this.pageNo > 1){ 14 //距离底部距离50就加载数据 15 if(_offsetHeight - clientHeightValue - scrollTop <= 50 ){ 16 if (this.totalPage <= this.pageNo) { 17 setTimeout(() => { 18 //mui.toast("已经没有更多了~"); 19 this.loadTxt='当当当~已经到底啦~'; 20 }, 300) 21 return; 22 }else{ 23 this.featchData(); 24 } 25 } 26 } 27 },