<template> 
 | 
    <view class="t-index-address"> 
 | 
        <scroll-view class="t-index-address__scroll-view" :scroll-into-view="scrollview" :scroll-y="true" 
 | 
            :enable-flex="true"> 
 | 
            <view :id="group.initial" v-for="group in cityList" :key="group.initial"> 
 | 
                <view class="t-index-address__anchor" style="background-color: #ffffff;"> 
 | 
                    <text>{{ group.initial }}</text> 
 | 
                </view> 
 | 
                <view class="t-index-address__list"> 
 | 
                    <view class="t-index-address__cell" v-for="(city, index) in group.list" :key="index" 
 | 
                        @click="$emit('select', city)"> 
 | 
                        <text>{{ city.name }}</text> 
 | 
                    </view> 
 | 
                </view> 
 | 
            </view> 
 | 
        </scroll-view> 
 | 
        <view class="t-index-address__sidebar"> 
 | 
            <view class="t-index-address__index" :style="{ color: activeIndex === group.initial ? '#00BC12' : '' }" v-for="group in cityList" :key="group.initial" 
 | 
                @touchstart.stop.prevent="onTouchMove(group.initial)" @touchend.stop.prevent="onTouchStop" 
 | 
                @touchcancel.stop.prevent="onTouchStop"> 
 | 
                <span>{{ group.initial }}</span> 
 | 
            </view> 
 | 
        </view> 
 | 
        <view class="t-index-address__alert" v-if="touchmove"> 
 | 
            <text>{{ activeIndex }}</text> 
 | 
        </view> 
 | 
    </view> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
    import cityList from "./cities.json"; 
 | 
  
 | 
    export default { 
 | 
        data() { 
 | 
            return { 
 | 
                scrollview: "A", 
 | 
                cityList: [], 
 | 
                activeIndex: "A", 
 | 
                touchmove: false, 
 | 
            }; 
 | 
        }, 
 | 
        watch: { 
 | 
            activeIndex(value) { 
 | 
                this.scrollview = value; 
 | 
            }, 
 | 
        }, 
 | 
        methods: { 
 | 
            search(val) { 
 | 
                let arr = JSON.parse(JSON.stringify(cityList)) 
 | 
                arr.forEach(item => { 
 | 
                    item.list = item.list.filter((child) => child.name.indexOf(val) !== -1) 
 | 
                }) 
 | 
                this.cityList = arr.filter(item => item.list.length > 0); 
 | 
            }, 
 | 
            initCityList() { 
 | 
                this.cityList = cityList; 
 | 
            }, 
 | 
            onTouchMove(index) { 
 | 
                this.activeIndex = index; 
 | 
                this.touchmove = true; 
 | 
            }, 
 | 
            onTouchStop() { 
 | 
                this.touchmove = false; 
 | 
            }, 
 | 
        }, 
 | 
        mounted() { 
 | 
            this.initCityList(); 
 | 
        }, 
 | 
    }; 
 | 
</script> 
 | 
  
 | 
<style lang="scss" scoped> 
 | 
    .t-index-address { 
 | 
        height: 100%; 
 | 
  
 | 
        &__scroll-view { 
 | 
            width: 100%; 
 | 
            height: 100%; 
 | 
            max-height: 100vh; 
 | 
        } 
 | 
  
 | 
        &__anchor { 
 | 
            padding: 15rpx 30rpx; 
 | 
            width: 100%; 
 | 
            font-size: 28rpx; 
 | 
            font-weight: 500; 
 | 
            color: #606266; 
 | 
            background-color: rgb(245, 245, 245); 
 | 
        } 
 | 
  
 | 
        &__list { 
 | 
            padding: 0 70rpx 0 30rpx; 
 | 
        } 
 | 
  
 | 
        &__cell { 
 | 
            height: 100rpx; 
 | 
            line-height: 100rpx; 
 | 
            border-bottom: 1rpx solid #f2f2f2; 
 | 
  
 | 
            &:last-child { 
 | 
                border: none; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        &__sidebar { 
 | 
            position: fixed; 
 | 
            top: 50%; 
 | 
            right: 0; 
 | 
            transform: translateY(-50%); 
 | 
            z-index: 99; 
 | 
        } 
 | 
  
 | 
        &__index { 
 | 
            padding: 10rpx 20rpx; 
 | 
            font-size: 22rpx; 
 | 
            font-weight: 500; 
 | 
            line-height: 1; 
 | 
        } 
 | 
  
 | 
        &__alert { 
 | 
            position: fixed; 
 | 
            top: 50%; 
 | 
            right: 90rpx; 
 | 
            z-index: 99; 
 | 
            margin-top: -60rpx; 
 | 
            width: 120rpx; 
 | 
            height: 120rpx; 
 | 
            font-size: 50rpx; 
 | 
            color: #fff; 
 | 
            border-radius: 24rpx; 
 | 
            background-color: rgba(0, 0, 0, 0.5); 
 | 
            display: flex; 
 | 
            justify-content: center; 
 | 
            align-items: center; 
 | 
        } 
 | 
    } 
 | 
</style> 
 |