SoFunction
Updated on 2025-04-11

Mescroll search and application in vue and various pit filling treatments

Parent component processing:

<template>
    <div class="wrap">
      <!-- Search box -->
      <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">   
        <!-- My recent followers -->
        <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>
       <!-- Protocol pop-up layer -->
      <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>
      <!-- Proportional pop-up layer -->
      <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: 'Search for the TA you are looking for',
         keyword: '',
         list: [],
         timerKey: null,
         dataList:[],//List data         totalPage:1,
         popuShow:false,//Protocol pop-up layer         isScale:false,//Proportional pop-up layer         scaleValue:'',//Share into proportion         userId:'',
         isActive:true,//The operation protocol button is displayed in gray         sencond:5,//Second         btntxt:'', //The text display of the button of the operation protocol layer         scaleValue:'',//Share into proportion         scaleDesc:'',//Performance pop-up description         scaleBtn:'',
         scaleCount:'50%',//Default share ratio         successInvite: [],//No invitation by default         protocolTitle:'',//Protocol title         protocolCon:'' //Protocol content      };
    },
    components:{FastChoice,PopUp,scale, SearchContent},
    watch: {
      keyword () {
        if (!){
          return;
        }
      }
    },
    mounted() {
      (); 
    },
    methods: {
      //invite      inviteClick (item) {
       //Click the invitation to not be operated       if(() > -1 || ){
         return;
       }
        = true;
        = ;
        = 'After the invitation is successful, you can obtain part of the user's income. Choosing the share ratio recognized by both parties can increase the invitation success rate~';
        = 'Send an invitation';
        = '50%';//The invitation ratio is uniformly 50%      },
      //Click to send an invitation      sendAjaxClick (value){
         = value;
         = true;
         = false;
         = true;
         = 5 ;
        ();
      },
      //5s time countdown      timer() {
        if ( > 0) {
          ="Read Agree and confirm the invitation("++"s)";
          --;
          t=setTimeout(, 1000);     
        } else{
           = false;
           = 5;
          ="Readed agree and confirmed invitation";  
        }
      },
      //Readed agree and confirmed      confirmProtocol () {
        if(){
          return false;
        }
        ();
      },
      //Send an invitation request      sendAjax () {
        ();
        let dd = ();
        this.$(_basePath + '/activity/page20191018/',{userId: ,shareRate:}).then((res) => {
          () ;
          ("The invitation has been sent, and the other party will notify you after accepting it.",2000);
          ();
        }).catch(() => {})
      },  
      //Close the operation protocol pop-up window      closeActionClick() {
         = false;
        clearTimeout(t);//Clear the countdown      },
       //Close the proportional pop-up window      closeScale () {
         = false; 
      },
      clear () {
         = "";
        this.$refs["input"].focus();
      },
      protocolAjax () {
         this.$(_basePath + '/activity/page20191018/',{type:0}).then((res) => {
          = ;
          = ;
        }).catch(() => {})
      }
    },
  };
</script>
<style lang="scss" scoped>
 @import "search";
</style>

Subcomponent processing:

<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()">
              <div class="showImg">
                <img :src="" />
                <template v-if="">
                  <em v-if="" class="icon c_kol"></em>
                </template>
                <template v-else>
                  <em class="icon c_company" v-if=" == '1'"></em>
                  <em class="icon c_person" v-if=" == '0'"></em>
                </template>
                
              </div>
              <div class="showInfo">
                <div class="name">{{}}</div>
                <div class="attentionCount">
                  {{ || 0}}People pay attentionTA
                </div>
              </div>
            </div>
            <div class="sendBtn" :class="{active: || (() > -1 ) }" @click="inviteClick()">
              <span v-if=" || () > -1">Invited</span>
              <span v-else>invite</span>
            </div>
          </li> 
        </ul> 
        
      </div>
    </div>
    <empty v-show="isEmpty">
      <p class="note">Nani,I can't find this person…</p>
    </empty>
  </div>  
</template>

<script>
import MeScroll from '';
import '/';
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 instance object      totalPage:1,
      isEmpty:false
    }
  },
  components:{
    Empty 
  },
  watch: {
    'searchName' () {
       = [];//Empty it, otherwise sometimes the pull-up will not be loaded       !== '' && ();
    }
  },
  mounted () {
    ()
     = new MeScroll(this.$, { //Initialize mescroll in mounted to ensure that the ref configured here has a value      down:{isLock: true}, //The configuration of pull-down refresh. (If the logic of pull-down refresh and pull-up load processing is the same, then down is not required)      up: {
          callback: ,
          // The following are some commonly used configurations, of course it is OK to not write them.          page: {
            num: 0, //The current page is 0 by default, and 1 will be added before the callback; that is, callback(page) will start from 1            size: 10, //The number of data strips per page is 10 by default          },
          htmlLoading: '<p class="upwarp-progress mescroll-rotate"></p><p class="upwarp-tip">Loading..</p>',
          htmlNodata: '<p class="upwarp-nodata" style="height:.4rem">Dangdangdang~It's already over~</p>',
          noMoreSize: 1, //If there is no data on the list, you can set that the total number of the list must be greater than 5 before there is no more data to be displayed;          isBounce: true,
      },
      down:{
        use:false
      },
    });
  },
  methods: {
     //Click to click to redirect your personal homepage    openUserClick (item) {
      (item)
      var userId = item;
       ({"pageType": "userHome","userId":item});
    },
     //Pull-up callback page = {num:1, size:10}; num: Current page, default starting from 1; size: Number of data strips per page, default 10    upCallback(page) {
      //Internet request      this.$(_basePath + '/activity/page20191018/', {hintKey:,searchType:91,pageNo:,pageSize:,actionSource:'07'}).then((response) => {
          if(response && ){
           // Requested list data            let result = [0];
            let arr = ;
            // If it is the first page, you need to manually empty the list            if ( === 1)  = []
            // Add the requested data to the list             = (arr)
            // After the data rendering is successful, hide the state of pull-down refresh             =  % pageSize > 0 ? ( / 10 + 1) :  / 10;//Calculate the total number of pages and do not loadMore            this.$nextTick(() => {
                ();
                (, )
            }) 
          }else{
             = true;
            ();
          }          
      }).catch(() => {
          ();
      })
    },
    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/);}
          }
        }
        .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>

Fill pit treatment:

1. When the user does not enter the search keyword, mescroll cannot be started directly. It can only be initialized when the user enters it. Therefore, the child component accepts the parent component's keyword and uses

v-if="keyword !== ''"To determine the conditions for loading the subcomponent, then the subcomponent will reset the mescroll by listening to the changes in keyword: as follows:

watch: {
    'searchName' () {
       = [];//Empty it, otherwise sometimes the pull-up will not be loaded       !== '' && ();
    }
  },

2. After searching, click the close button on the right side of the search input box and find that other lists cannot slide. Solution: add: isBounce: true,

ps: Let's take a look at the use of mescroll vue

github: /mescroll/mescroll

Official Documentation:

It is best to follow the official documentation

After the initialization is enabled, the callback loading is automatically executed to ensure that the data is loaded as soon as it enters the page.

When pulling up and refreshing, or when tab switches, put the data empty first

page and pageSize use the one in upOption, and num defaults to 0

Code:

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

//data:
// Common configurations for pull-down refreshdownOption: {
 use: true, // Whether to enable drop-down refresh; default true auto: false, // Whether to automatically execute the callback for pull-down refresh after initialization; default true},
// Common configurations for pull-up loadingupOption: {
 use: true, // Whether to enable pull-up loading; default true auto: true, // Whether to automatically execute the callback loading after initialization; default true textNoMore:'I have a bottom line >_<',
 page: {
 num:0,
 size: 4
 }
},
list:[],

//methods:
// Pull down callbackdownCallback(mescroll){
 (1)
  = []
 (); 
 setTimeout(()=&gt;{
 (666);
 // Hide the drop-down loading status ()
 },1000)
},
// Pull-up callbackupCallback(mescroll){
 setTimeout(()=&gt;{
 let pageNum =  == 0 ? 1: ; // Page number, default starting from 1 let pageSize = ;
 (pageNum, pageSize).then((res)=&gt;{
  (res)
 })
 },1000)
}

Summarize

The above is the search and application of mescroll in vue introduced to you and various pit filling processing. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!
If you think this article is helpful to you, please reprint it. Please indicate the source, thank you!