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

更新日期: 2019-09-28阅读: 1.8k标签: 搜索

父组件处理:

<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


链接: https://fly63.com/article/detial/6176

好看css搜索框样式_分享8款纯CSS搜索框

最简单实用的CSS3搜索框样式,纯CSS效果无需任何javascript,其中部分搜索框在点击的时候有动画特效,搜索框的应用也是比较普通的,代码如下!

如何使用robots禁止各大搜索引擎爬虫爬取网站

都会有一句由于robots.txt文件存在限制指令无法提供内容描述,.原来一般来说搜索引擎爬取网站时都会,先读取下robots.txt文件,并依照里面所设定的规则去爬取网站。

Lucene全文检索入门使用

全文检索是计算机程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置。当用户查询时根据建立的索引查找,类似于通过字典的检索字表查字的过程

程序员应该掌握的 10 个搜索技巧

在今天,用户可以通过搜索引擎轻松找出自己想要的信息,但还是难以避免结果不尽如人意的情况。实际上,用户仅需掌握几个常用技巧即可轻松化解这种尴尬。下面介绍 10 个在进行 Google 搜索时可以使用的便捷技巧

隐藏搜索框:CSS 动画正反向序列

顶部菜单栏中放置搜索框是一个常见的场景,但如果搜索功能使用的不那么频繁,同时菜单栏中内容本来就比较拥挤,再放一个完整的搜索框在那就显得不那么美观。因此也有一个挺常见的做法是,只放一个搜索图标,需要时再显示整个搜索框

程序员如何查资料(百度、谷歌搜索技巧汇总)

intitle——把搜索范围限定在网页标题中;inurl——把搜索范围限定在url链接中;site——把搜索范围限定在特定站点中;精确匹配、加减号、通配符精确匹配:可以用双引号和书名号

JS基本搜索算法实现与170万条数据下的性能测试

今天让我们来继续聊一聊js算法,通过接下来的讲解,我们可以了解到搜索算法的基本实现以及各种实现方法的性能,进而发现for循环,forEach,While的性能差异,我们还会了解到如何通过web worker做算法分片

ECMAScript 提案:.findLast()和.findLastIndex()从尾到头搜索数组

今天来看一个 ECMAScript 提案:findLast() 和 findLastIndex()。提案原因:在 JavaScript 中,可以通过 find() 和 findIndex() 查找数组中的值。不过,这些方法从数组的开始进行遍历

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!