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(()=>{ (666); // Hide the drop-down loading status () },1000) }, // Pull-up callbackupCallback(mescroll){ setTimeout(()=>{ let pageNum = == 0 ? 1: ; // Page number, default starting from 1 let pageSize = ; (pageNum, pageSize).then((res)=>{ (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!