mpvue iview-webapp框架的一些坑

2019-05-27  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读