小程序实现带索引的城市列表

本文实例为大家分享了小程序实现带索引的城市列表的具体代码,供大家参考,具体内容如下

效果

网上找的很多的效果右边的索引不会按左边滑动区域高亮处理所以自己写了个

代码实现

因为我的城市数据没有而项目里先有的是省市区代码数据所以要先处理一下数据
用来获取首字母:

//用来获取首字母
import py from '../../utils/strChineseFirstPY'
checkCh(ch) {
      let uni = ch.charCodeAt(0);
      //如果不在汉字处理范围之内,返回原字符,也可以调用自己的处理函数
      if (uni > 40869 || uni < 19968) {
        return ch;
      } //dealWithOthers(ch);
      //检查是否是多音字,是按多音字处理,不是就直接在strChineseFirstPY字符串中找对应的首字母
      return (py.oMultiDiff[uni] ? py.oMultiDiff[uni] : (py.strChineseFirstPY.charAt(uni - 19968)));
    }

利用首字母讲城市数据整理:

//用来获取首字母
/**
     * @name: 
     * @test: test font
     * @msg: 
     * @param {*} data 数组
     * @param {*} field 依据那个字段排序
     * @return {*}
     */
    data_letter_sort (data, field) {
      let list = new Array();
      let letter = ''
      for (let i = 0; i < data.length; i++) {
        // 首字母 转 大写英文
        letter = (data[i][field]).substr(0, 1).toUpperCase();
        // 创建 字母 分组
        if (!(letter in list)) {
          list[letter] = new Array();
        }
        // 字母 分组 添加 数据
        list[letter].push(data[i]);
      }
       // 转换 格式 进行 排序;
      let resault = new Array();
      for (let key in list) {
        resault.push({
          letter: key,
          list: list[key]
        });
      }
      resault.sort(function (x, y) {
        return x.letter.charCodeAt(0) - y.letter.charCodeAt(0);
      });
      // 转换 数据 格式
      let json_sort = {}
      for (let i = 0; i < resault.length; i++) {
        json_sort[resault[i].letter] = resault[i].list;
      }
      return json_sort;
    },

处理过后的数据为按首字母排序的一个对象

然后难点就在右边的索引怎么按照左边的区域来进行高亮显示
首先我想的是获取每个字母距离上边的高度然后页面滑动时进行高度判断

//获取城市数据的首字母列表
for (let key in this.cityList) {
      let obj = {
        py: key,
        active: false
      }
      if (obj.py == 'A') {
        obj.active = true
      }
      wx.createSelectorQuery().select('#'+ key).boundingClientRect(function(rect){
        obj.top = rect.top     // 节点的上边界坐标
      }).exec()
      //pylist是用来渲染右边索引列表的
      this.pyList.push(obj);
    }
//滑动时间
scroll(e) {
      let scrollTop = e.target.scrollTop
      this.pyList.map(item => {
        if ((scrollTop - item.top)>-76) {
          this.pyList.map(item => {
          //active是用来是否高亮显示
            item.active = false
          })
          item.active = true
          return
        }
      })
    },

整体代码

<!--
 * @Descripttion: 
 * @version: 
 * @Author: Songtutu
 * @Date: 2021-04-06 10:30:36
 * @LastEditors: Songtutu
 * @LastEditTime: 2021-04-08 13:40:32
-->
<template>
  <div class="main">
    <div class="search">
        <div class="search-box">
          <img :src="imglist.map_search"/>
          <input placeholder="请输入城市名称" @focus="focus" :focus="true" v-model="search" type="digit" -splaceholdertyle="font-size:14px;color: rgba(0, 0, 0, 0.3);" confirm-type="search" @confirm='doSearch'/>
        </div>
      </div>
    <!-- 城市列表 -->
    <scroll-view scroll-y="true" scroll-with-animation="true" enable-back-to-top="true" class="city-list" @scroll="scroll" :scroll-top="scrollTop" v-show="searchList.length == 0">
      
      <div class="dw-box">
        <div>定位城市:{{city}}</div>
        <img :src="imglist.map_sx" @click="sx()"/>
      </div>
      <div :id='key' class="city-group" v-for="(value, key, index) in cityList" :key="index">
        <div  class="city-group-title">{{key}}</div>
        <div class="city-item" :id="i == value.length -1?key:''" v-for="(item, i) in value" :key="i">
          {{item.cityName}}
        </div>
      </div>
    </scroll-view>
    <div class="search-list" v-show="searchList.length != 0">
      <div class="city-item" v-for="(item, i) in searchList" :key="i">
        {{item.cityName}}
      </div>
    </div>
    <div class="py-box" v-show="searchList.length == 0">
      <div class="py-item" :class="item.active?'active':''" v-for="(item, index) in pyList" :key="index" @click="clickPy(item, index)">{{item.py}}</div>
    </div>
  </div>
</template>
<script>
import py from '../../utils/strChineseFirstPY'
import area from '../../utils/area1'
export default {
  data() {
    return {
      cityList: [],
      imglist: [],
      search:'',
      city: '',
      pyList: [],
      scrollTop: 0,
      searchList: []
    }
  },
  created() {
    let title = "选择城市"
    let frontColor = "#000000"
    let backgroundColor = "#ffffff"
    wx.setNavigationBarTitle({
      title
    })
    wx.setNavigationBarColor({
      frontColor, //前景颜色值,包括按钮、标题、状态栏的颜色,仅支持 #ffffff 和 #000000,
      backgroundColor
    });
    const imgurl = "图片根目录"
    this.imglist = {
      map_search: `${imgurl}map_search.png`,
      map_sx: `${imgurl}map_sx.png`
    }
    area.region.map(item => {
      item.mallCityList.map(i => {
        this.cityList.push(i)
      })
    })
    this.cityList.map(item => {
      item.py = this.checkCh(item.cityName.charAt(0))
    })
    this.cityList = this.data_letter_sort(this.cityList, 'py')
    console.log(this.cityList)
  },
  mounted() {
    for (let key in this.cityList) {
      let obj = {
        py: key,
        active: false
      }
      if (obj.py == 'A') {
        obj.active = true
      }
      wx.createSelectorQuery().select('#'+ key).boundingClientRect(function(rect){
        obj.top = rect.top     // 节点的上边界坐标
      }).exec()
      this.pyList.push(obj);
    }
  },
  methods: {
    focus() {
      if (!this.search) {
        this.searchList = []
      }
    },
    doSearch() {
      this.searchList = []
      for(let key in this.cityList) {
        this.cityList[key].map(item => {
          if (item.cityName.indexOf(this.search) != -1) {
            this.searchList.push(item)
          }
        })
      }
    },
    clickPy(item) {
      this.scrollTop = item.top - 44
    },
    scroll(e) {
      let scrollTop = e.target.scrollTop
      this.pyList.map(item => {
        if ((scrollTop - item.top)>-76) {
          this.pyList.map(item => {
            item.active = false
          })
          item.active = true
          return
        }
      })
    },
    sx() {
      this.getLocation()
    },
    /**
     * 定位授权
     */
    getLocation() {
      const that = this;
      //调用自带位置获取
      wx.getSetting({
        success(res) {
          if (!res.authSetting["scope.userLocation"]) {
            wx.authorize({
              scope: "scope.userLocation",
              success() {
                that.localDetail();
              },
              fail() {
                wx.showModal({
                  title: "提示",
                  content: "获取当前位置需要授权哦~",
                  success(res) {
                    if (res.confirm) {
                      wx.openSetting({
                        success: res => {
                          if (res.authSetting["scope.userLocation"]) {
                            that.localDetail();
                          }
                        }
                      });
                    } else if (res.cancel) {
                    }
                  }
                });
              }
            });
          } else {
            that.localDetail();
          }
        }
      });
    },
    localDetail() {
      wx.getLocation({
        type: "gcj02", //返回可以用于wx.openLocation的经纬度
        success: function(res) {
          console.log(res)
        }
      });
    },
    /**
     * @name: 
     * @test: test font
     * @msg: 
     * @param {*} data 数组
     * @param {*} field 依据那个字段排序
     * @return {*}
     */
    data_letter_sort (data, field) {
      let list = new Array();
      let letter = ''
      for (let i = 0; i < data.length; i++) {
        // 首字母 转 大写英文
        letter = (data[i][field]).substr(0, 1).toUpperCase();
        // 创建 字母 分组
        if (!(letter in list)) {
          list[letter] = new Array();
        }
        // 字母 分组 添加 数据
        list[letter].push(data[i]);
      }
       // 转换 格式 进行 排序;
      let resault = new Array();
      for (let key in list) {
        resault.push({
          letter: key,
          list: list[key]
        });
      }
      resault.sort(function (x, y) {
        return x.letter.charCodeAt(0) - y.letter.charCodeAt(0);
      });
      // 转换 数据 格式
      let json_sort = {}
      for (let i = 0; i < resault.length; i++) {
        json_sort[resault[i].letter] = resault[i].list;
      }
      return json_sort;
    },
    checkCh(ch) {
      let uni = ch.charCodeAt(0);
      //如果不在汉字处理范围之内,返回原字符,也可以调用自己的处理函数
      if (uni > 40869 || uni < 19968) {
        return ch;
      } //dealWithOthers(ch);
      //检查是否是多音字,是按多音字处理,不是就直接在strChineseFirstPY字符串中找对应的首字母
      return (py.oMultiDiff[uni] ? py.oMultiDiff[uni] : (py.strChineseFirstPY.charAt(uni - 19968)));
    }
  }
}
</script>
<style scoped>
.search-list {
  margin-top: 68rpx;
  background: white;
  width: 100%;
  height: auto;
}
.active {
  width: 16px;
  height: 16px;
  background: #005F28;
  line-height: 16px;
  border-radius: 50%;
  color: white;
  text-align: center;
}
.py-box {
  width: 16px;
  text-align: center;
  height: auto;
  position: fixed;
  top: 142px;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.4);
  font-size: 14px;
  right:9px;
}
.search {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 99;
  background: white;
  padding-bottom: 8px;
}
.city-item {
  margin: 0 32px 0px 16px;
  height: 40px;
  line-height: 40px;
  font-size: 14px;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.9);
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.city-list {
  background: white;
  height: 100vh;
  position: relative;
}
.city-list .city-group-title {
  position: sticky;
  top: 33px;
  width: 100%;
  font-size: 14px;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.4);
  padding: 0px 16px;
  height: 32px;
  line-height: 32px;
  background: #F5F5F5;
  box-sizing: border-box;
}
.main{
  min-height: 100vh;
  background: #F5F5F5;;
  padding-top: 6px;
}
.search-box {
  margin-top: 6px;
  margin: 0 auto;
  width: 343px;
  display: flex;
  height: auto;
  padding: 6px 8px;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 4px;
}
.search-box img {
  width: 16px;
  height: 16px;
  margin-top: 2px;
  margin-right: 4px;
}
.search-box input {
  height: 20px;
  font-size: 14px;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.9);
  line-height: 20px;
}
.dw-box {
  margin-top: 32px;
  height: 44px;
  display: flex;
  line-height: 44px;
  padding: 0 16px;
  font-size: 14px;
  font-weight: 400;
  color: #005F28;

}
.dw-box div {
  flex: 1;
  text-align: left;
}
.dw-box img {
  margin-top: 14px;
  width: 16px;
  height: 16px;
}
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 微信小程序实现全国机场索引列表

    本文为大家分享了微信小程序实现MUI索引列表的具体代码,供大家参考,具体内容如下 效果展示图 实现的原理 '当前选择机场'和右侧的导航栏采用的是固定定位: 左侧的展示窗口的滚动采用的是scroll-view组件: 选择中的字母提示是自己WXSS样式制作. WXML <view class="right-nav"> <view bindtap="getCurrentCode" class="{{chooseIndex == index ?

  • 小程序实现带索引的城市列表

    本文实例为大家分享了小程序实现带索引的城市列表的具体代码,供大家参考,具体内容如下 效果 网上找的很多的效果右边的索引不会按左边滑动区域高亮处理所以自己写了个 代码实现 因为我的城市数据没有而项目里先有的是省市区代码数据所以要先处理一下数据用来获取首字母: //用来获取首字母 import py from '../../utils/strChineseFirstPY' checkCh(ch) {       let uni = ch.charCodeAt(0);       //如果不在汉字处理

  • react native带索引的城市列表组件的实例代码

    城市列表选择是很多app共有的功能,比如典型的美图app.那么对于React Native怎么实现呢? 要实现上面的效果,首先需要对界面的组成简单分析,界面的数据主要由当前城市,历史访问城市和热门城市组成,所以我们在提供Json数据的时候就需要将数据分为至少3部分. const ALL_CITY_LIST = DATA_JSON.allCityList; const HOT_CITY_LIST = DATA_JSON.hotCityList; const LAST_VISIT_CITY_LIST

  • 微信小程序实现带刻度尺滑块功能

    摘要: 与自带的slider不同的是,它是通过手势滑动标尺得到取值,而不是通过滑动滑块本身. 效果图 场景 当一屏显示不下,例如年龄体重选择,金额选择等大区间需要的选择器,相比自带的picker要直观一些. 思路: 先画一个scrollView 2 装进canvas lineTo画刻度线段,lineTo+fill画出三角形游标,fillText描绘文本标签 通过bindscroll监听刻度尺触摸事件 渲染取值到页面 基本布局 <scroll-view scroll-x="true"

  • 微信小程序实现带参数的分享功能(两种方法)

    微信小程序分享功能的实现方法有两种: 第一种 在page.js中实现onShareAppMessage,便可在小程序右上角选择分享该页面 onShareAppMessage: function () { return { title: '弹出分享时显示的分享标题', desc: '分享页面的内容', path: '/page/user?id=123' // 路径,传递参数到指定页面. } } 第二种 自定义按钮实现分享,在page中添加一个带有open-type='share'的button标签

  • 微信小程序项目总结之点赞 删除列表 分享功能

    小程序点赞功能 思路:在后台没有给你接口自己模拟数据 data:{ likes:{ iszan:false, num:0 } } 1.遍历评论列表 判断点击的id 2.如果id相同 判断是否点赞过 如果为true -1 如果为false +1 3.更新数据 bindlike:function(e){ var newData = this.data.release.map(function(item){ if (item.id == e.currentTarget.dataset.id){ con

  • 微信小程序获取当前位置和城市名

    1, 获取当前地理位置,首先要拿到用户的授权wx.openSetting: 2,微信的getLocation接口,获取当前用户的地理位置(微信返回的是经纬度,速度等参数): 3,微信没有将经纬度直接转换为地理位置,借用腾讯位置服务中关于微信小程序的地理转换JS SDK 的API(返回信息中包括国家,省,市,区,经纬度等地理位置) 步骤描述清楚以后,下面就开始按步骤操作了:(本文仅仅讲述如何获取用户地理位置的授权) 图示为获取用户地理位置授权弹窗 在用户首次进入某页面(需要地理位置授权)时候,在页

  • 微信小程序实现带放大效果的轮播图

    本文实例为大家分享了微信小程序实现带放大效果的轮播图,供大家参考,具体内容如下 效果如图 WXML <!-- 轮播图 --> <view class='Carousel'> <view class="recommend"> <view class="swiper-container"> <swiper class="swiper" autoplay="auto" inter

  • 微信小程序用户盒子、宫格列表的实现

    最近在学习小程序,看到别人九宫格的做法,就留个笔记,也分享给大家 效果图如下所示 .wxml <view class='user-box' style="margin-top:20rpx;"> <view class='ctn'> <view class='list' wx:for="{{4}}" wx:key data-index="{{index}}"> <image mode="width

  • 微信小程序实现字母索引菜单

    本文实例为大家分享了微信小程序实现字母索引菜单的具体代码,供大家参考,具体内容如下 wxml文件 <view class="container"> <view class="content">   <view class="all-food">     <view class="food">全部食物</view>       <scroll-view class

  • 微信小程序实现根据字母选择城市功能

    今天开发一个小程序,里面涉及到区域选择,看了网上的一些版本,感觉写的不全,有可能是我的理解能力还不够吧.今天我就结合网上的答案,在根据自己的需求,重新整理一份.希望对大家有帮助.先看看截图: 项目截图 下面我们把代码梳理一下. 一.创建index.wxml文件 在pages->index文件夹下,新建index.wxml文件,代码如下: class="title"> class="title_list" value="{{cityName}}&

随机推荐