网络编程
位置:首页>> 网络编程>> JavaScript>> vue中的mescroll搜索运用及各种填坑处理

vue中的mescroll搜索运用及各种填坑处理

作者:huanghuamei206023  发布时间:2024-04-30 10:26:39 

标签:vue,mescroll

父组件处理:


<template>
   <div class="wrap">
     <!-- 搜索框 -->
     <div class="searchInputArea">
       <div class="searchBarBox">
         <div class="inputWrap" >
           <form onsubmit="javascript:return false" action>
             <input :placeholder = "placeholderStr" type="search" ref = "input" v-model="keyword" />
             <span class="clearBtn" v-show="keyword" @click="clear"></span>  
           </form>  
         </div>
       </div>
     </div>
     <div class="myFastChoiceBlock" v-show="!keyword">  
       <!-- 最近伙伴和我的关注 -->
       <fast-choice :successInvite="successInvite" @invite="inviteClick"></fast-choice>
     </div>  
     <div class="searchContainer">      
       <search-content :searchName="keyword" :successInvite="successInvite" @inviteClick="inviteClick" v-if="keyword !== ''"></search-content>
     </div>
      <!-- 协议弹出层 -->
     <pop-up @change="closeLayer" v-if="popuShow">
       <h2 class="title">{{protocolTitle}}</h2>
       <div class="content" v-html="protocolCon"></div>
       <div class="confirmBtn" :class="{active:isActive}" @click="confirmProtocol">{{btntxt}}</div>
       <div class="popCloseCon" @click="closeActionClick"></div>
     </pop-up>
     <!-- 比例弹出层 -->
     <scale @change="closeScale" @send="sendAjaxClick" :number="scaleCount" :scaleBtn="scaleBtn" :scaleDesc="scaleDesc" v-show="isScale" :userId="userId"></scale>
   </div>
</template>
<script>
 import FastChoice from './components/fastChoice';
 import PopUp from './components/PopUp';
 import scale from './components/scale';
 import SearchContent from './components/searchContent';
 const pageSize=10;
 let t='';
 export default {
   name: "Search",
   data() {
     return {
        placeholderStr: '搜一搜你想找的TA',
        keyword: '',
        list: [],
        timerKey: null,
        dataList:[],//列表数据
        totalPage:1,
        popuShow:false,//协议弹出层
        isScale:false,//比例弹出层
        scaleValue:'',//分成比例
        userId:'',
        isActive:true,//操作协议按钮灰色显示
        sencond:5,//秒数
        btntxt:'', //操作协议层按钮文字显示
        scaleValue:'',//分成比例
        scaleDesc:'',//比例弹窗描述
        scaleBtn:'',
        scaleCount:'50%',//默认分成比例
        successInvite: [],//默认未邀请
        protocolTitle:'',//协议标题
        protocolCon:'' //协议内容
     };
   },
   components:{FastChoice,PopUp,scale, SearchContent},
   watch: {
     keyword () {
       if (!this.keyword){
         return;
       }
     }
   },
   mounted() {
     this.protocolAjax();
   },
   methods: {
     //邀请
     inviteClick (item) {
      //点击邀请过的不予操作
      if(this.successInvite.indexOf(item.hwUserId) > -1 || item.inviteStatus){
        return;
      }
      this.isScale = true;
      this.userId = item.hwUserId;
      this.scaleDesc = '邀请成功后你可获取该用户部分收益,选择双方都认可的分成比例可以提高邀请成功率哦~';
      this.scaleBtn = '发送邀请';
      this.scaleCount = '50%';//邀请比例统一为50%
     },
     //点击发送邀请
     sendAjaxClick (value){
       this.scaleValue = value;
       this.popuShow = true;
       this.isScale = false;
       this.isActive = true;
       this.sencond = 5 ;
       this.timer();
     },
     //5s时间倒计时
     timer() {
       if (this.sencond > 0) {
         this.btntxt="已阅读同意并确认邀请("+this.sencond+"s)";
         this.sencond--;
         t=setTimeout(this.timer, 1000);    
       } else{
         this.isActive = false;
         this.sencond = 5;
         this.btntxt="已阅读同意并确认邀请";  
       }
     },
     //已阅读同意并确认
     confirmProtocol () {
       if(this.isActive){
         return false;
       }
       this.sendAjax();
     },
     //发送邀请请求
     sendAjax () {
       console.log(this.scaleValue);
       let dd = this.scaleValue.toString();
       this.$request.post(_basePath + '/activity/page20191018/inviteArtist.html',{userId: this.userId,shareRate:this.scaleValue}).then((res) => {
         this.successInvite.push(this.userId) ;
         mui.toast("已发送邀请,对方接受后会通知你哦",2000);
         this.closeActionClick();
       }).catch(() => {})
     },  
     //关闭操作协议弹窗
     closeActionClick() {
       this.popuShow = false;
       clearTimeout(t);//清除倒计时
     },
      //关闭分成比例弹窗
     closeScale () {
       this.isScale = false;
     },
     clear () {
       this.keyword = "";
       this.$refs["input"].focus();
     },
     protocolAjax () {
        this.$request.post(_basePath + '/activity/page20191018/queryProtocol.html',{type:0}).then((res) => {
        this.protocolTitle = res.title;
        this.protocolCon = res.content;
       }).catch(() => {})
     }
   },
 };
</script>
<style lang="scss" scoped>
@import "search";
</style>

子组件处理:


<template>
 <div>
   <div ref="mescroll" class="mescroll">
     <div class="search-content wrapper" ref="scroller" >
       <ul>
         <li class="item" v-for="(item,index) in dataList" :key="index">
           <div class="personBlock" @click="openUserClick(item.userDetail.userId)">
             <div class="showImg">
               <img :src="item.userDetail.userThumUrl" />
               <template v-if="item.userDetail.kolFlag">
                 <em v-if="item.userDetail.kolFlag" class="icon c_kol"></em>
               </template>
               <template v-else>
                 <em class="icon c_company" v-if="item.userDetail.upSignType == '1'"></em>
                 <em class="icon c_person" v-if="item.userDetail.upSignType == '0'"></em>
               </template>

</div>
             <div class="showInfo">
               <div class="name">{{item.userDetail.nickName}}</div>
               <div class="attentionCount">
                 {{item.userDetail.fansCount || 0}}人关注TA
               </div>
             </div>
           </div>
           <div class="sendBtn" :class="{active:item.userDetail.inviteStatus || (successInvite.indexOf(item.userDetail.hwUserId) > -1 ) }" @click="inviteClick(item.userDetail)">
             <span v-if="item.userDetail.inviteStatus || successInvite.indexOf(item.userDetail.hwUserId) > -1">已邀请</span>
             <span v-else>邀请</span>
           </div>
         </li>
       </ul>

</div>
   </div>
   <empty v-show="isEmpty">
     <p class="note">纳尼,竟然找不到这个人…</p>
   </empty>
 </div>  
</template>

<script>
import MeScroll from 'mescroll.js';
import 'mescroll.js/mescroll.min.css';
import Empty from './empty';
const pageSize=10;
export default {
 name: 'SearchContent',
 props: {
   searchName: {
     type: String,
     default: ''
   },
   successInvite: {
     type: Array,
     default: []
   }
 },
 data() {
   return {
     dataList: [],
     mescroll: null, //mescroll实例对象
     totalPage:1,
     isEmpty:false
   }
 },
 components:{
   Empty
 },
 watch: {
   'searchName' () {
     this.dataList = [];//要清空,不然有时候会出现上拉加载不了
     this.searchName !== '' && this.mescroll.resetUpScroll();
   }
 },
 mounted () {
   console.log(this.searchName)
   this.mescroll = new MeScroll(this.$refs.mescroll, { //在mounted初始化mescroll,确保此处配置的ref有值
     down:{isLock: true}, //下拉刷新的配置. (如果下拉刷新和上拉加载处理的逻辑是一样的,则down可不用写了)            
     up: {
         callback: this.upCallback,
         // 以下是一些常用的配置,当然不写也可以的.
         page: {
           num: 0, //当前页 默认0,回调之前会加1; 即callback(page)会从1开始
           size: 10, //每页数据条数,默认10
         },
         htmlLoading: '<p class="upwarp-progress mescroll-rotate"></p><p class="upwarp-tip">正在加载中..</p>',
         htmlNodata: '<p class="upwarp-nodata" style="height:.4rem">当当当~已经到底啦~</p>',
         noMoreSize: 1, //如果列表已无数据,可设置列表的总数量要大于5才显示无更多数据;
         isBounce: true,
     },
     down:{
       use:false
     },
   });
 },
 methods: {
    //点击调起个人主页
   openUserClick (item) {
     console.log(item)
     var userId = item;
      mui.openClient({"pageType": "userHome","userId":item});
   },
    //上拉回调 page = {num:1, size:10}; num:当前页 ,默认从1开始; size:每页数据条数,默认10
   upCallback(page) {
     //联网请求
     this.$request.post(_basePath + '/activity/page20191018/searchAll.html', {hintKey:this.searchName,searchType:91,pageNo:page.num,pageSize:page.size,actionSource:'07'}).then((response) => {
         if(response && response.resultList){
          // 请求的列表数据
           let result = response.resultList[0];
           let arr = result.list;
           // 如果是第一页需手动置空列表
           if (page.num === 1) this.dataList = []
           // 把请求到的数据添加到列表
           this.dataList = this.dataList.concat(arr)
           // 数据渲染成功后,隐藏下拉刷新的状态
           this.totalPage = result.total % pageSize > 0 ? Math.floor(result.total / 10 + 1) : result.total / 10;//计算总页数超过就不loadMore
           this.$nextTick(() => {
               this.mescroll.endSuccess(arr.length);
               this.mescroll.endByPage(arr.length, this.totalPage)
           })
         }else{
           this.isEmpty = true;
           this.mescroll.endErr();
         }          
     }).catch(() => {
         this.mescroll.endErr();
     })
   },
   inviteClick(item) {
     this.$emit('inviteClick',item);
   }
}

}
</script>

<style lang="scss" scoped>
.mescroll {
 position: fixed;
 top: .9rem;
 bottom: 0;
 left:0;
 height: auto;
}
.search-content{
 padding:0 .24rem;
 background: #121223;
 ul{
   height:auto;
   .item{
     display:flex;
     justify-content:space-between;
     align-items:center;
     width:100%;
     height:1.56rem;
     .personBlock{
       display:flex;
       justify-content: flex-start;
       align-items: center;
       .showImg{
         position:relative;
         width:1rem;
         height:1rem;
         margin-right:.16rem;
         border:.02rem solid #51516D;
         border-radius:50%;
         box-sizing: border-box;
         img{width:100%;height:100%;border-radius:50%}
         .icon{
           position: absolute;
           bottom:0;
           right:0;
           width:.28rem;
           height:.28rem;
           background-image:url();
           background-repeat:no-repeat;
           background-size:contain;
           &.c_company{background-image:url(../../images/c_company.png);}
           &.c_person{background-image:url(../../images/c_person.png);}
           &.c_kol{background-image:url(../../images/kol.png);}
         }
       }
       .showInfo{
         .name{font-size:.3rem;color:#fff;font-weight:500;line-height:.42rem;text-align:left;}
         .attentionCount{font-size:.26rem;font-weight:400;color:#716D80;text-align:left;}
       }
     }

.sendBtn{
       width:1.44rem;
       height:.56rem;
       line-height:.56rem;
       background:#FF005E;
       border-radius:.28rem;
       color:#fff;
       text-align:center;
       &.active{background:#2C2B41;color:#fff}
     }
   }
 }
}  

</style>

填坑处理:

1、用户未输入搜索关键词时,mescroll不能就直接初始话,要在用户输入的时候才能初始化,所以子组件就接受了父组件的keyword,并用

v-if="keyword !== ''"来判断加载子组件的条件,然后子组件通过监听keyword的变化,重置mescroll:如下:


watch: {
   'searchName' () {
     this.dataList = [];//要清空,不然有时候会出现上拉加载不了
     this.searchName !== '' && this.mescroll.resetUpScroll();
   }
 },

2、搜索完以后点击搜索输入框右边里的关闭按钮,发现其他列表不能滑动。解决方法:要加:isBounce: true,

ps:下面看下mescroll vue使用

github: https://github.com/mescroll/mescroll

官方文档:http://www.mescroll.com

最好按照官方文档来

开启初始化完毕之后自动执行上拉加载的回调,保证一进入页面,就去加载数据

上拉刷新的时候,或者tab切换的时候,先将数据置空

page 和 pageSize使用upOption中的,并且num默认为0

代码:


// html
<mescroll-uni top="100" @down="downCallback" @up="upCallback" @init="mescrollInit" :up="upOption" :down="downOption">

//data:
// 下拉刷新的常用配置
downOption: {
use: true, // 是否启用下拉刷新; 默认true
auto: false, // 是否在初始化完毕之后自动执行下拉刷新的回调; 默认true
},
// 上拉加载的常用配置
upOption: {
use: true, // 是否启用上拉加载; 默认true
auto: true, // 是否在初始化完毕之后自动执行上拉加载的回调; 默认true
textNoMore:'我是有底线的 >_<',
page: {
num:0,
size: 4
}
},
list:[],

//methods:
// 下拉回调
downCallback(mescroll){
mescroll.setPageNum(1)
this.list = []
mescroll.resetUpScroll();
setTimeout(()=>{
console.log(666);
// 隐藏下拉加载状态
mescroll.endErr()
},1000)
},
// 上拉回调
upCallback(mescroll){
setTimeout(()=>{
let pageNum = mescroll.num == 0 ? 1: mescroll.num; // 页码, 默认从1开始
let pageSize = mescroll.size;
this.getPageList(pageNum, pageSize).then((res)=>{
 mescroll.endSuccess(res)
})
},1000)
}

总结

以上所述是小编给大家介绍的vue中的mescroll搜索运用及各种填坑处理,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

来源:https://www.cnblogs.com/huanghuamei206023/archive/2019/10/29/11760999.html

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com