模拟vant indexBar实现城市列表
Posted ws-zhangbo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟vant indexBar实现城市列表相关的知识,希望对你有一定的参考价值。
<template> <div class="selectCityMain" ref="DOM" id="pageId"> <div ref="Box"> <!-- <div v-if="letter.length > 0" class="now-sort">{{letter}}</div> --> <div :class="[‘now-letter‘, fadeFlag?‘fadeIn‘:‘‘]">{{ letter }}</div> <div class="letterBox"> <p :class="idx === activtIndex ? ‘active‘:‘‘" v-for="(item, idx) in letterList" :key="idx" @click="scrollSelect(idx)">{{ item }}</p> </div> <div> <div class="hostCityBox"> <div class="base-wrap" v-for="(item, index) in quickPanelData" :classesAttr="item" :key="index" > <div class="title">{{item.title}}</div> <div class="panel host" ref="host"> <span class="item ellipsis" v-for="(cy,idx) in item.data" :key="idx" @click="selectCity(cy)" >{{cy}}</span> </div> </div> </div> <div class="cityListBox" ref="left"> <div class="base-wrap" v-for="(tle,tleIdx) in listData" :key="tleIdx"> <div class="title_bar">{{tle.initial}}</div> <div class="panel"> <p class="cityName border_bottom" v-for="(city,idx1) in tle.list" :key="idx1" @click="selectCity(city.name)" >{{city.name}}</p> </div> </div> </div> </div> </div> </div> </template> <script> import request from ‘@/utils/request‘ export default { data() { return { cityname: "", citycode: "", city: "", province: "", listData: [], letterList: [], letter: "", fadeFlag: false, scrolly: 0, activtIndex:0, quickPanelData: [ { title: "当前城市", navName: "当", data: [‘杭州市‘], }, { title: "热门城市", navName: "热", data: [ "北京市" ], } ], listHeight: [] }; }, watch:{ listData() { this.$nextTick(() =>{ this._getHeight() let page = document.getElementById(‘pageId‘); // 先给页面注册滚动事件 page.addEventListener("scroll", this.handleScroll, true); }) } }, async created() { this.getCityList(); }, mounted() { }, destroyed () { window.removeEventListener(‘scroll‘, this.handleScroll) }, methods: { handleScroll() { var scrollTop = document.getElementById(‘pageId‘).scrollTop; this.listHeight.forEach((item, index) => { if (this.listHeight[index] < scrollTop && this.listHeight[index + 1] > scrollTop) { this.activtIndex = index } }) }, // 获取城市列表 getCityList() { request({ url: `wxArea/search`, method: ‘get‘ }).then((res) => { let arr = []; for (let key in res) { let obj = { initial: null, list: null }; obj.initial = res[key].initial; obj.list = res[key].list; arr.push(obj); } this.listData = arr; // 提取字母列表 this.quickPanelData.forEach((item, index) => { const navItem = item.navName || item.title || "标题"; this.letterList.push(navItem); }); // 处理城市列表数据 this.listData.forEach((item, index) => { this.letterList.push(item.initial); }); }) }, //计算滚动条滚动的距离 scrollSelect(index) { this.letter = this.letterList[index]; this.fadeFlag = true; this.activtIndex = index; this.Timer = setTimeout(() => { this.fadeFlag = false; }, 1000); document.getElementById(‘pageId‘).scrollTop = this.listHeight[index]; }, _getHeight() { let rightItems = document.getElementsByClassName("base-wrap") let height = 0 this.listHeight.push(height) for(let i = 0; i < rightItems.length; i++){ let item = rightItems[i] height += item.clientHeight this.listHeight.push(height) } }, //点击选择城市 selectCity(name) { this.cityname= name; // this.$store.commit("changeCityName", name); // this.$router.push({ path: "/home" }); }, async onSelected(data) { //选择城市动态更新到首页 this.cityname = data.city.value; // this.$store.commit("changeCityName", this.cityname); // this.$router.push({ path: "/home" }); } } }; </script> <style lang="less" scoped> .selectCityMain { width: 100%; height: 100vh; background-color: #f2f2f2; overflow-y: auto; position: relative; .letterBox { font-size: 0.44rem; position: fixed; top: 3.56rem; right: 0.42rem; color: #999; z-index: 2; p { width:0.64rem; height:0.64rem; text-align: center; } .active{ border-radius: 50%; color: #fff; background: rgba(254,140,0,1); } } .now-letter { font-size: 60px; color: #ccc; position: fixed; top: 50%; left: 50%; transform: translate3d(-50%, -50%, 0); opacity: 0; z-index: 2; &.fadeIn { animation: fade 1s linear 0ms; opacity: 1; } } .now-sort { position: absolute; top: 0; left: 0; width: 100%; display: flex; align-items: center; box-sizing: border-box; font-size: 14px; padding: 10px; background: #ccc; } .hostCityBox { width: 100%; .base-wrap { overflow: hidden; .title { display: flex; align-items: center; box-sizing: border-box; font-size: 0.52rem; padding: 0.48rem 0.48rem 0.32rem; color: #999; // background: #ccc; } .panel { display: flex; flex-wrap: wrap; padding: 0 0.48rem; .item { width: 3.2rem; height: 1.44rem; font-size: 0.56rem; text-align: center; line-height: 1.44rem; background:rgba(255,255,255,1); border-radius:0.16rem; border:0.02rem solid rgba(229,229,229,1); } &::after { display: block; content: ""; width: 200px; border: 1px solid transparent; } } } } .cityListBox { width: 100%; .title_bar { display: flex; align-items: center; box-sizing: border-box; font-size: 0.52rem; padding: 0.28rem 0.48rem; color: #999; // background: #ccc; } .panel { display: flex; flex-wrap: wrap; padding: 0 0.48rem; box-sizing: border-box; color: #333; background-color: #fff; .cityName { position: relative; font-size: 0.64rem; width: 100%; padding: 0.5rem 0; display: flex; align-items: center; } } } } </style>
以上是关于模拟vant indexBar实现城市列表的主要内容,如果未能解决你的问题,请参考以下文章
揭秘 antd mobile “IndexBar” 的实现思路
揭秘 antd mobile “IndexBar” 的实现思路
揭秘 antd mobile “IndexBar” 的实现思路
APP开发-Vue3+Vant实现不同地区动态获取天气信息功能