美文网首页
mpvue iview-webapp框架的一些坑

mpvue iview-webapp框架的一些坑

作者: 大梦无痕 | 来源:发表于2019-05-27 17:20 被阅读0次

    iview 框架 index 组件在ios 中由于层级关系字母索引被挡住问题

    框架代码修改

    <view class="i-index i-class">
        <scroll-view 
            scroll-y 
            style="overflow: visible;"
            style="{{parse.setScrollStyle(height)}}" 
            bindscroll="handlerScroll"
            scroll-top="{{scrollTop}}">
            <slot></slot>
            <view class="i-index-tooltip" style="{{ isTouches ? 'display:block' : 'display:none' }}">{{currentName}}</view>
        </scroll-view>
         <view class="i-index-fixed" 
            catchtouchstart="handlerTouchMove" 
            catchtouchmove="handlerTouchMove" 
            catchtouchend="handlerTouchEnd">
            <view class="i-index-fixed-item" 
                wx:for="{{fixedData}}" 
                wx:key="{{index}}" 
                data-index="{{index}}" 
                catchtap="handlerFixedTap">
                {{item}}
            </view>
        </view>  
       
    </view>
    <wxs module="parse">
        module.exports = {
           setScrollStyle : function(height){
               var units = ['%','px','rem','rpx','em','rem'];
               var hasUnits = false;
               for( var i = 0; i < units.length;i++ ){
                   var u = units[i];
                   if( height.indexOf( u ) > -1 ){
                       hasUnits = true;
                       break;
                   }
               }
               return 'height:'+ ( hasUnits ? height : height+'px' )+';overflow: visible';
           }
        }
    </wxs>
    
    Component({
        externalClasses: ['i-class'],
        properties : {
            height : {
                type : String,
                value : '300'
            },
            itemHeight : {
                type : Number,
                value : 18
            },
            scrollTop:{
                type : Number,
                value : 0
            }
        },
        relations : {
            '../index-item/index' : {
                type : 'child',
                linked(){
                    this.setData({
                        fixedData : []
                    })
                    this._updateDataChange();
                },
                linkChanged () {
                    this._updateDataChange();
                },
                unlinked () {
                    this.setData({
                        fixedData : []
                    })
                    this._updateDataChange();
                }
            }
        },
        data : {
            scrollTop : 0,
            fixedData : [],
            current : 0,
            timer : null,
            startTop : 0,
            itemLength : 0,
            currentName : '',
            isTouches : false
        },
        methods : {
            loop(){},
            _updateDataChange( ){
                
                const indexItems = this.getRelationNodes('../index-item/index');
                const len = indexItems.length;
                const fixedData = this.data.fixedData;
                
                /*
                 * 使用函数节流限制重复去设置数组内容进而限制多次重复渲染
                 * 暂时没有研究微信在渲染的时候是否会进行函数节流
                */
                if (len > 0) {
    
                    if( this.data.timer ){
                        clearTimeout( this.data.timer )
                        this.setData({
                            timer : null
                        })
                    }
                    
                    this.data.timer = setTimeout(()=>{
                        const data = [];
                        indexItems.forEach((item) => {
                            if( item.data.name && fixedData.indexOf( item.data.name ) === -1 ){
                                data.push(item.data.name);
                                item.updateDataChange();
                            }
                        })
                        this.setData({
                            scrollTop:0,
                            fixedData : data,
                            itemLength : indexItems.length
                        })
                        //组件加载完成之后重新设置顶部高度
                        this.setTouchStartVal();
                    },0);
                    this.setData({
                        timer : this.data.timer
                    })
                    
                }
            },
            handlerScroll(event){
                const detail = event.detail;
                
                const scrollTop = detail.scrollTop;
                
                const indexItems = this.getRelationNodes('../index-item/index');
                indexItems.forEach((item,index)=>{
                    let data = item.data;
                    let offset = data.top + data.height;
                   
                    if( scrollTop < offset && scrollTop >= data.top ){
                        
                        this.setData({
                            current : index,
                            currentName : data.currentName
                        })
                    }
                })
            },
            getCurrentItem(index){
                const indexItems = this.getRelationNodes('../index-item/index');
                let result = {};
                if(indexItems[index-1]){
                    result = indexItems[index-1].data;
                    result.total = indexItems.length;
                    return result;
                }
                
            },
            triggerCallback(options){
                this.triggerEvent('change',options)
            },
            handlerFixedTap(event){
                const eindex = event.currentTarget.dataset.index;
                const item = this.getCurrentItem(eindex);
                
                this.setData({
                    scrollTop : item.top - data.scrollTop,
                    currentName : item.currentName,
                    isTouches : true
                })
                
                this.triggerCallback({
                    index : eindex,
                    current : item.currentName
                })
            },
            handlerTouchMove(event){
                const data = this.data;
                const touches = event.touches[0] || {};
                const pageY = touches.pageY;
                const rest = pageY - data.startTop;
                let index = Math.ceil( rest/data.itemHeight );
                index = index >= data.itemLength ? data.itemLength -1 : index;
                const movePosition = this.getCurrentItem(index);
    
               /*
                * 当touch选中的元素和当前currentName不相等的时候才震动一下
                * 微信震动事件
               */
                if(!movePosition){
                    return false;
                }
                if( movePosition.name !== this.data.currentName ){
                    wx.vibrateShort();
                }
                this.setData({
                    scrollTop : movePosition.top,
                    currentName : movePosition.name,
                    isTouches : true
                })
    
                this.triggerCallback({
                    index : index,
                    current : movePosition.name
                })
            },
            handlerTouchEnd(){
                this.setData({
                    isTouches : false
                })
            },
            setTouchStartVal(){
                
                const className = '.i-index-fixed';
                const query = wx.createSelectorQuery().in(this);
                query.select( className ).boundingClientRect((res)=>{
                    console.log(res)
                    if(res&&res.top){
                        this.setData({
                            startTop : res?res.top:0
                        })
                    }
                    
                }).exec()
            }
        }
    })
    

    页面代码

    <template>
        <div class="container">
            <div class="containerTop">
                <div class="search">
                    <div :class="isInput?'search-left col-8':'search-left'">
                        <i-icon type="search" i-class="icon-b" size="24" />
                        <i-input i-class="input-b" 
                            @focus="focus" 
                            maxlength="10000" 
                            :value="value" 
                            type="text" 
                            @change="getChange" 
                            placeholder="搜索目的地" />
                    </div>
                    <div v-show="isInput" class="search-right" @click="isInput=false">取消</div>
                </div>
                <div class="tabs">
                    <i-tabs :current="current" @change="tabsSelect" color="#19be6b">
                        <i-tab key="1" title="国内" i-class="tab"></i-tab>
                        <i-tab key="2" title="海外" i-class="tab"></i-tab>
                    </i-tabs>
                </div>
                <!--热门城市-->
                <div class="hot" v-show="!isInput">
                    <div class="title">热门城市</div>
                    <i-row>
                        <i-col span="8" v-for="(item,index) in hotList" v-if="index<12" :key="index">
                            <div class="x-btn" @click="setSite(item,'nameChn')">{{item.nameChn}}</div>
                        </i-col>
                    </i-row>
                </div>
            <!--索引index组件-->
                <div class="view" v-show="!isInput">
                    <i-index height="100%" v-if="siteList&&current==1" :scrollTop="scrollTop">
                        <i-index-item
                            v-for="(item,index) in siteList" :key="index"
                            :name="item.key">
                            <div class="i-index-demo-item" @click="setSite(item1,'name')"  v-for="(item1,inx) in item.list" :key="inx">
                                {{item1.name}}
                            </div>
                        </i-index-item>
                    </i-index>
                    <i-index height="100%" v-if="siteList&&current==2" :scrollTop="scrollTop">
                        <i-index-item
                            v-for="(item,index) in siteList" :key="index"
                            :name="item.key">
                            <div class="i-index-demo-item" @click="setSite(item1,'name')"  v-for="(item1,inx) in item.list" :key="inx">
                                {{item1.name}}
                            </div>
                        </i-index-item>
                    </i-index>
                </div>
            </div>
            <!--搜索列表-->
            <div class="search-list" v-show="isInput">
                <i-cell-group v-for="(item,index) in searchList" :key="index">
                    <i-cell 
                        is-link
                        :title="item.nameChn" 
                        i-class="bor-b" 
                        @click="setSite(item,'nameChn')">
                    </i-cell>
                </i-cell-group>
            </div>
        </div>
    </template>
    <script>
        import { mapActions, mapState} from "vuex";
        export default{
            components:{
                
            },
            async onShow(){
                if(this.site.nation=="中国"){
                    this.init(this.siteInlandList);
                    this.current = 1;
                }else{
                    this.init(this.siteForeignList);
                    this.current = 2;
                }
            },
            computed:{
                ...mapState({
                    siteInlandList:state=>state.siteList,
                    siteForeignList:state=>state.siteForeignList,
                    site:state=>state.site
                })
            },
            data(){
                return {
                    current:1,
                    scrollTop:0,//index索引距离顶部距离高度
                    value:"",
                    siteList:null,
                    isInput:false,//是否获取到焦点
                    hotList:[],
                    searchList:[]
                }
            },
            methods:{
                //选项卡切换
                tabsSelect(obj){
                    this.current = obj.mp.detail.key ;
                    if(this.current==1){
                        this.init(this.siteInlandList);
                    }else{
                        this.init(this.siteForeignList);
                    }
                },
                focus(){
                    this.isInput = true;
                    this.search();
                },
                getChange(value){
                    this.value = value.mp.detail.detail.value;
                    this.search();
                },
                //点击搜索列表
                setSite(item,filed){
                    var data = {
                        city:item[filed],
                        ...item,
                        showCon:true
                    };
                    if(this.current==1){
                        data.nation = "中国";
                    }else{
                        data.nation = "海外";
                    }
                    
                    this.isInput = false ;
                    this.$store.commit("SET_SITE",data);
                    wx.navigateBack();
                },
                //搜索列表
                search(){
                    this.searchList = this.hotList.filter((e)=>{
                        return e.nameChn.indexOf(this.value)>-1||this.value.indexOf(e.nameChn)>-1;
                    })
                },
                init(data){
                    this.siteList = null;
                    this.searchList = [];
                    this.value = this.$store.state.site.city;
                    this.hotList = data;
                    this.searchList = data;
                    //设置
                    var cities = data;
                    //const words = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
                    let wordsList = [];
                    cities.forEach((item)=>{
                        wordsList.push(item.nameEng.substring(0,1));
                    })
                    var words = wordsList.filter((e,i,slef)=>{
                        return slef.indexOf(e)==i
                    })
                    words = words.sort(function compareFunction(param1, param2) {
                            return param1.localeCompare(param2,"zh");
                        }
                    )
                    let storeCity = new Array(words.length);
                    words.forEach((item,index)=>{
                        storeCity[index] = {
                            key : item,
                            list : []
                        }
                    })
                    
                    cities.forEach((item)=>{
                        let firstName = item.nameEng.substring(0,1);
                        let index = words.indexOf(firstName);
                        storeCity[index].list.push({
                            name : item.nameChn,
                            key : firstName,
                            cityId:item.cityId,
                            countryId:item.countryId,
                            nameEng:item.nameEng,
                        });
                    })
                    this.siteList = [];
                    this.siteList = storeCity;
                }
            },
            onLoad(){
                var than = this ;
                wx.getSystemInfo({
                    success:function(res){
                        than.scrollTop = parseInt((res.screenWidth/750)*680);
                    }
                })
            }
            
        }
    </script>
    <style lang="css">
        ::-webkit-scrollbar {
          width: 0;
          height: 0;
          color: transparent;
        }
        view{
            overflow: visible;
        }
        .tab{
            padding: 0 20rpx;
        }
        /*搜索*/
        .search{
            width: 674rpx;
            margin: 0 auto;
            height: 70rpx;
            overflow: hidden;
        }
        .search-left{
            overflow: hidden;
            border-radius: 14rpx;
            width: 100%;
            background: #f8faf9;
            padding-left: 16rpx;
            float: left;
            position: relative;
        }
        .containerTop{
            height: 680rpx;
        }
        .col-8{
            width: 80%;
        }
        .search-left .icon-b{
            color: #07c687;
            display: inline-block;
            vertical-align: middle;
        }
        .search-left .input-b{
            padding: 0;
            padding: 0;
            display:inline-block;
            vertical-align: middle;
            background: none;
            width: 80%;
        }
        .search-right{
            float: left;
            font-size: 28rpx;
            color: #ccc;
            line-height: 70rpx;
            padding-left: 20rpx;
        }
        /*下划线*/
        .bor-b{
            border-bottom:2rpx solid #ccc ;
        }
        .search-list{
            width: 674rpx;
            margin: 0 auto;
            position: absolute;
            left: 38rpx;
            top: 70rpx;
            bottom: 0;
            overflow: auto;
        }
        .hot{
            width: 674rpx;
            margin: 0 auto;
            position: relative;
            z-index: 1;
        }
        .hot .title{
            font-size: 30rpx;
            color: #222;
            line-height: 30rpx;
            padding-top: 30rpx;
            margin-bottom: 10rpx;
        }
        .hot .x-btn{
            height: 60rpx;
            line-height: 60rpx;
            margin: 12rpx 20rpx;
            text-align: center;
            background: #fafafa;
            border: 2rpx solid #ddd;
            font-size: 28rpx;
            color: #222;
        }
        /*索引*/
        .view{
            width: 100%;
            position: absolute;
            top:680rpx;
            bottom: 0;
            z-index: 1000;
        }
        .i-index-demo-item{
            padding: 20rpx;
            border-bottom: 2rpx solid #ccc;
        }
    </style>
    
    image.png
    image.png

    相关文章

      网友评论

          本文标题:mpvue iview-webapp框架的一些坑

          本文链接:https://www.haomeiwen.com/subject/hhohtctx.html