vant indexBar地区索引级联选择

49 篇文章 1 订阅
5 篇文章 0 订阅

要求:使用van组件的indexBar索引栏实现地区的联动效果。

效果:

思路:

1.修改vant组件的indexBar变成规定样式;

2.将组件写成循环现实,并添加点击事件;

3.点击地区确定方法;

4.点击顶部方法;

5.点击列表方法;

6.字母排序方法;

相关代码实现:

1. 样式框架

<!-- 地区弹出层 -->
<div class="map-popup">
    <van-action-sheet v-model="showPicker" title="请选择查看区域">
        <ul class="address-box">
            <li>
                <span :class="{'address-active': address.city=='请选择'}" @click="handleTopToAddress('city',0, address.city)">{{ address.city }}</span>
                <span :class="{'address-active': address.district=='请选择'}" @click="handleTopToAddress('district',1, address.district)">{{ address.district }}</span>
                <span :class="{'address-active': address.town=='请选择'}" @click="handleTopToAddress('town',2, address.town)">{{ address.town }}</span>
                <span :class="{'address-active': address.village=='请选择'}" @click="handleTopToAddress('village',3, address.village)">{{ address.village }}</span>
            </li>
            <li>
                <van-button @click="handleSubmit">确定</van-button>
            </li>
        </ul>
        <van-index-bar highlight-color="#3378E0" :sticky="false" :index-list="indexList" >
            <div v-for="(item,index) in addressData" :key="index">
                <van-index-anchor :index="item.letter"></van-index-anchor>
                <van-cell v-for="(ite,index) in item.data" :key="index" :title="ite.name" @click="handleListToAddress(addressIndex+1,ite.name)"></van-cell>
            </div>
        </van-index-bar>
    </van-action-sheet>
</div>

2.点击弹出该地区选择框

// 点击地区弹出
handleToAddressShow() {
    this.showPicker = true;
    const addressKeyArr = ['city', 'district', 'town', 'village'];
    let addressArr = [];
    addressArr = Object.values(this.address);
    let _index = addressArr.findIndex(item => item == '');
    let _ind = !!_index && _index != -1 ? _index - 1 : 3;
    if (addressKeyArr[_ind]) {
        this.handleToAddress(addressKeyArr[_ind], _ind + 1, addressArr[_ind], this.currData);
    }
},

3. 点击地区确定

// 地区确定
    handleSubmit() {
        this.addressValue = '';
        for (let key in this.address) {
            if (this.address[key] == '请选择') {
                this.address[key] = '';
            } else if (this.address[key]) {
                this.addressValue = this.address[key];
            }
        }
        this.showPicker = false;
    },

 4.点击顶部地区

// 点击顶部地区
    handleTopToAddress(key, index, name) {
        var data = this.getCurChild(name);
        if (key == 'city') {
            this.address = {
                city:name,
                district:'',
                town:'',
                village:''
            }
        } else if (key == 'district') {
            this.address.town = '';
            this.address.village = '';
        } else if (key == 'town') {
            this.address.village = '';
        }
        this.handleToAddress(key, index + 1, data);
    },

5.点击列表地区

// 点击底部地区
    handleListToAddress(index, name) {
        var data = this.getCurChild(name);
        var  addressKey = this.addressKeyArr[index-1];
        this.address[addressKey] = name;
        if (addressKey == 'city') {
            this.address.district = this.address.district ? this.address.district : '请选择';
        } else if (addressKey == 'district') {
            this.address.town = this.address.town ? this.address.town : '请选择';
        } else if (addressKey == 'town') {
            this.address.village = this.address.village ? this.address.village : '请选择';
        }
        this.handleToAddress(addressKey, index, data);
    },

6.获取下一级的数据回调显示

// 获取下一级的数据回调显示
    getCurChild(name) {
        var _data = [];
        var _land = this.land;
        var getCurChildList = function (data) {
            data.forEach(function (item) {
                if (item.children) {
                    if (item.name === name) {
                        _data = item.children;
                    } else {
                        getCurChildList(item.children);
                    }
                }
            });
        };
        getCurChildList(_land.children);
        return _data;
    },

7.公共方法:根据data来显示列表数据

 // 公共方法:根据data来显示列表数据
    handleToAddress(key, index, data) {
        this.addressIndex = index;
        this.addressData = [];
        this.currData = [];
        if (data && data.length > 0) {
            this.addressData = this.initAddress(data);
            this.currData = data;
        } 
        if (key == 'city') {
            this.addressData = this.initAddress(this.land.children);
        }
    },

8.根据首字母排序

initAddress(arr) {
        if (!String.prototype.localeCompare) return null;
        var letters = '*ABCDEFGHJKLMNOPQRSTWXYZ'.split('');
        var zh = '阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀'.split('');
        var segs = [];
        var curr;
        letters.forEach(function (item, i) {
            curr = {
                letter: item,
                data: [],
            };
            arr.forEach(function (item2) {
                if ((!zh[i - 1] || zh[i - 1].localeCompare(item2.name) <= 0) && item2.name.localeCompare(zh[i]) == -1) {
                    curr.data.push(item2);
                }
            });
            if (curr.data.length) {
                segs.push(curr);
                curr.data.sort(function (a, b) {
                    return a.name.localeCompare(b.name);
                });
            }
        });
        this.indexList = [];
        segs.forEach(v => {
            this.indexList.push(v.letter);
        });
        return segs;
    },

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值