zoukankan      html  css  js  c++  java
  • 微信小程序实现按首字母检索城市列表

    不说废话,上效果图

    因为我有多处要用到,所以我这里是写成自定义组件的,你也可以直接改成在page页面编写:

    布局左边一个scroll-view,显示城市列表,右边一个view显示字母列表,城市列表这边有首字母显示,给这个添加这个字母的ID,然后给右边的26个字母添加点击事件,点击的时候获取到点击的是哪个字母,给scroll-view的scroll-into-view赋值相应的字母,它左边就可以跳到相应的地方,再给scroll-view 加一个scroll-with-animation,让它跳转的时候有动画效果;

    首先,我们来看看wxml

    <view class='city_box' style='{{styles}}'>
          <view class='city_left'>
              <scroll-view scroll-y style='100%;height:100%;' scroll-with-animation scroll-into-view='{{cityListId}}'>
                  <view class='city_locate' data-types='locate' catchtap='cityTap'>
                      <text class='city_locate_title'>自动定位</text>
                      <text class='city_locate_text' style='{{!locateCity&&"color:#33b9ff;"}}'>{{locateCity||'点击定位'}}</text>
                  </view>
                  <view class='national' data-types='national' catchtap='cityTap'>全国</view>
                  <view class='new_city'>
                      <view class='new_city_title'>热门城市</view>
                      <view class='new_city_box'>
                          <text class='new_city_text' wx:for='{{newcity}}' wx:key='this' data-types='new' catchtap='cityTap' data-val='{{item}}'>{{item}}</text>
                      </view>
                  </view>
                  <view class='city_list_box'>
                    <block wx:for='{{citylist}}' wx:key='this' wx:for-item='letterItem' wx:for-index='letterIndex'>
                      <view class='city_first_letter' id='{{letterItem.letter}}'>{{letterItem.letter}}</view>
                      <text class='city_name' wx:for='{{letterItem.data}}' wx:key='this' data-types='list' catchtap='cityTap' data-index='{{index}}' data-val='{{item}}'>{{item.cityName}}</text>
                    </block>
                  </view>
              </scroll-view>
          </view>
          <view class='city_right'>
              <text class='letter_item' wx:for='{{letter}}' wx:key='this' catchtap='letterTap' data-item='{{item}}'>{{item}}</text>
          </view>
      </view>

    然后wxss

    .city_box{
      height:100%;
      background: #fff;
      display: flex;
    }
    .city_left{
      flex: 1;
    }
    .city_right{
       60rpx;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
    }
    .letter_item{
      flex: 1;
      display: block;
      font-size: 24rpx;
      color: #33B9FF;
      text-align: center;
    }
    .city_locate,.national{
      height: 80rpx;
      line-height: 80rpx;
      border-bottom: 1px solid #efefef;
      font-size: 28rpx;
      color: #333;
      padding-left: 25rpx;
    }
    .city_locate_title{
      color: #999;
      margin-right: 20rpx;
    }
    .new_city{
      background: #efefef;
      font-size: 28rpx;
    }
    .new_city_title{
      line-height: 50rpx;
      color: #999;
      padding-left: 25rpx;
      margin-bottom: 20rpx;
    }
    .new_city_box{
      display: flex;
      flex-wrap: wrap;
    }
    .new_city_text{
       200rpx;
      text-align: center;
      line-height: 70rpx;
      background: #fff;
      border-radius: 35rpx;
      margin:0 0 22rpx 22rpx;
    }
    .city_first_letter{
      line-height: 40rpx;
      height: 40rpx;
      padding-left: 25rpx;
      font-size: 28rpx;
      background: #eee;
      color: #999;
    }
    .city_name{
      display: block;
      line-height: 80rpx;
      height: 80rpx;
      border-bottom: 1px solid #efefef;
      font-size: 28rpx;
      color: #333;
      padding-left: 25rpx;
    }

    然后是json文件,因为我这里是组件,所以是下面这样,如果你不是的组件,那么不要这句

    {
    "component": true
    }

    最后JS,因为我这里是写的一个组件,所以是Component而不是Page

    import qqmap from '../../utils/map.js';
    Component({
      properties: {
        styles:{//这个是可以自定义最外层的view的样式
          type:String,
          value:'',
          observer: function (newval, oldval) {
            // 监听改变
            console.log(newval, oldval);
          }
        }
      },
      data: {
        //下面是字母排序
        letter: ["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"],
        cityListId: '',
        //下面是城市列表信息,这里只是模拟数据
        citylist: [{ "letter": "A", "data": [{ "id": "v7", "cityName": "安徽" }] }, { "letter": "B", "data": [{ "id": "v10", "cityName": "巴中" }, { "id": "v4", "cityName": "包头" }, { "id": "v1", "cityName": "北京" }] }, { "letter": "C", "data": [{ "id": "v15", "cityName": "成都" }] }, { "letter": "D", "data": [{ "id": "v21", "cityName": "稻城" }] }, { "letter": "G", "data": [{ "id": "v17", "cityName": "广州" }, { "id": "v29", "cityName": "桂林" }] }, { "letter": "H", "data": [{ "id": "v9", "cityName": "海南" }, { "id": "v3", "cityName": "呼和浩特" }] }, { "letter": "L", "data": [{ "id": "v24", "cityName": "洛阳" }, { "id": "v20", "cityName": "拉萨" }, { "id": "v14", "cityName": "丽江" }] }, { "letter": "M", "data": [{ "id": "v13", "cityName": "眉山" }] }, { "letter": "N", "data": [{ "id": "v27", "cityName": "南京" }] }, { "letter": "S", "data": [{ "id": "v18", "cityName": "三亚" }, { "id": "v2", "cityName": "上海" }] }, { "letter": "T", "data": [{ "id": "v5", "cityName": "天津" }] }, { "letter": "W", "data": [{ "id": "v12", "cityName": "乌鲁木齐" }, { "id": "v25", "cityName": "武汉" }] }, { "letter": "X", "data": [{ "id": "v23", "cityName": "西安" }, { "id": "v28", "cityName": "香港" }, { "id": "v19", "cityName": "厦门" }] }, { "letter": "Z", "data": [{ "id": "v8", "cityName": "张家口" }] }],
        //下面是热门城市数据,模拟数据
        newcity: ['北京', '上海', '广州', '深圳', '成都', '杭州'],
        // citySel: '全国',
        locateCity: ''
      },
      methods: {
        //点击城市
        cityTap(e) {
          const val = e.currentTarget.dataset.val || '',
            types = e.currentTarget.dataset.types || '',
            Index = e.currentTarget.dataset.index || '',
            that=this;
          let city = this.data.citySel;
          switch (types) {
            case 'locate':
              //定位内容
              city = this.data.locateCity;
              break;
            case 'national':
              //全国
              city = '全国';
              break;
            case 'new':
              //热门城市
              city = val;
              break;
            case 'list':
              //城市列表
              city = val.cityName;
              break;
          }
          if(city){
            wx.setStorage({
              key: 'city',
              data: city
            })
        //点击后给父组件可以通过bindcitytap事件,获取到cityname的值,这是子组件给父组件传值和触发事件的方法
    this.triggerEvent('citytap', { cityname: city }); }else{ console.log('还没有'); this.getLocate(); } }, //点击城市字母 letterTap(e) { const Item = e.currentTarget.dataset.item; this.setData({ cityListId: Item }); console.log(this.data.cityListId); }, //调用定位 getLocate(){ let that=this; new qqmap().getLocateInfo().then(function (val) {//这个方法在另一个文件里,下面有贴出代码 console.log(val); if (val.indexOf('市') !== -1) {//这里是去掉“市”这个字 console.log(val.indexOf('市') - 1); val = val.slice(0, val.indexOf('市')); console.log(val); } that.setData({ locateCity: val }); //把获取的定位和获取的时间放到本地存储 wx.setStorageSync('locatecity', { city: val, time: new Date().getTime() }); }); } }, ready(){ console.log(getApp()); let that = this, cityOrTime = wx.getStorageSync('locatecity')||{}, time = new Date().getTime(), city=''; if (!cityOrTime.time||(time - cityOrTime.time > 1800000)){//每隔30分钟请求一次定位 this.getLocate(); }else{//如果未满30分钟,那么直接从本地缓存里取值 that.setData({ locateCity: cityOrTime.city }) } } })

    然后是引用的map.js,这里需要用到腾讯地图的微信小程序sdk获取当前经纬度的详情信息,然后取到当前城市,这是腾讯地图微信小程序JavaScript SDK,可以去查看教程,这里用到的是地址解析功能;

    const wxqqmap = require('../libs/qqmap-wx-jssdk.min.js'),
          qqwxmap = new wxqqmap({
            key: 'GTDBZ-WFSRX-JOT4W-7WYBD-Z2CTO-7QBEM' // 必填,这里最好填自己申请的的
          }); 
    import util from './util.js';
    const qq='sdfsdf';
    export default class qqmap{//获取定位信息
      getLocateInfo(){
        let that=this;
        return new Promise(function (resolve, reject) {
                that.location().then(function(val){
                  //如果通过授权,那么直接使用腾讯的微信小程序sdk获取当前定位城市
                  qqwxmap.reverseGeocoder({
                    location: {
                      latitude: val.latitude,
                      longitude: val.longitude
                    },
                    success: function (res) {
                      console.log(res.result.address_component.city);
                      resolve(res.result.address_component.city);//返回城市
                    },
                    fail: function (res) {
                      reject(res);
                    },
                    complete: function (res) {
                      console.log(res);
                    }
                  });
                    
                  },function(error) {
                    //如果用户拒绝了授权,那么这里会提醒他,去授权后再定位
                    console.log('shibai');
                    wx.showModal({
                      title: '',
                      content: '自动定位需要授权地理定位选项',
                      confirmText: '去授权',
                      success(res) {
                        if (res.confirm) {
                          wx.openSetting({
                            success(res) {
                              console.log(res);
                              that.getLocateInfo();
                            }
                          })
                        }
                      }
                    })
    
                  })
              
        })
      }
      
    //定位,获取当前经纬度
      location(){   
        return new Promise(function (resolve, reject) {  
          wx.getLocation({
            altitude: true,
            success: function (res) {
              resolve(res);
            },fail(res){
              reject(res);
            }
          })
        });
        
      }  
    
      
    }

    然后在引用这个组件的时候,在引用的页面的json文件里要添加这一句

    {
      "usingComponents":{
        "citylist":"../../component/cityListCom/cityListCom"
      }
    }

    然后在引用的wxml界面添加组件,styles是设置的组件的变量,我这里是可以改变组件最外层的样式,bindcitytap是上面组件js里的点击城市方法里提到的事件

    <citylist styles='max-height:100%;' bindcitytap='cityTap'></citylist>

    然后在引用的界面的js里,写个cityTap事件,获取传过来的值

    // pages/cityList/cityList.js
    Page({
      data: {
        winHeight:0
      },
    //监听传值,后面自己做处理了 cityTap(e){ console.log(
    'fasdfsdfsdfds'); console.log(e); const cityName=e.detail.cityname; wx.navigateBack(); }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { const win = wx.getSystemInfoSync(); console.log(win); this.setData({ winHeight: win.windowHeight }); } })

    这样就可以了。

    如果不想写成组件的,想直接写在一个页面里面,需要改一下

    首先wxml里面去掉圈起来的这句

    WXSS里面添加page{height:100%;}

    JS里面改成这样

    import qqmap from '../../utils/map.js';//这里的路径看你自己的文件路径
    Page({
      data: {
        //下面是字母排序
        letter: ["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"],
        cityListId: '',
        //下面是城市列表信息,这里只是模拟数据
        citylist: [{ "letter": "A", "data": [{ "id": "v7", "cityName": "安徽" }] }, { "letter": "B", "data": [{ "id": "v10", "cityName": "巴中" }, { "id": "v4", "cityName": "包头" }, { "id": "v1", "cityName": "北京" }] }, { "letter": "C", "data": [{ "id": "v15", "cityName": "成都" }] }, { "letter": "D", "data": [{ "id": "v21", "cityName": "稻城" }] }, { "letter": "G", "data": [{ "id": "v17", "cityName": "广州" }, { "id": "v29", "cityName": "桂林" }] }, { "letter": "H", "data": [{ "id": "v9", "cityName": "海南" }, { "id": "v3", "cityName": "呼和浩特" }] }, { "letter": "L", "data": [{ "id": "v24", "cityName": "洛阳" }, { "id": "v20", "cityName": "拉萨" }, { "id": "v14", "cityName": "丽江" }] }, { "letter": "M", "data": [{ "id": "v13", "cityName": "眉山" }] }, { "letter": "N", "data": [{ "id": "v27", "cityName": "南京" }] }, { "letter": "S", "data": [{ "id": "v18", "cityName": "三亚" }, { "id": "v2", "cityName": "上海" }] }, { "letter": "T", "data": [{ "id": "v5", "cityName": "天津" }] }, { "letter": "W", "data": [{ "id": "v12", "cityName": "乌鲁木齐" }, { "id": "v25", "cityName": "武汉" }] }, { "letter": "X", "data": [{ "id": "v23", "cityName": "西安" }, { "id": "v28", "cityName": "香港" }, { "id": "v19", "cityName": "厦门" }] }, { "letter": "Z", "data": [{ "id": "v8", "cityName": "张家口" }] }],
        //下面是热门城市数据,模拟数据
        newcity: ['北京', '上海', '广州', '深圳', '成都', '杭州'],
        // citySel: '全国',
        locateCity: ''
      },
    
        //点击城市
        cityTap(e) {
          console.log(e)
          const val = e.currentTarget.dataset.val || '',
            types = e.currentTarget.dataset.types || '',
            Index = e.currentTarget.dataset.index || '',
            that = this;
          let city = this.data.citySel;
          switch (types) {
            case 'locate':
              //定位内容
              city = this.data.locateCity;
              break;
            case 'national':
              //全国
              city = '全国';
              break;
            case 'new':
              //热门城市
              city = val;
              break;
            case 'list':
              //城市列表
              city = val.cityName;
              break;
          }
          if (city) {
            wx.setStorage({
              key: 'city',
              data: city
            })
                //点击后给父组件可以通过bindcitytap事件,获取到cityname的值,这是子组件给父组件传值和触发事件的方法
            this.triggerEvent('citytap', { cityname: city });
          } else {
            console.log('还没有');
            this.getLocate();
          }
    
        },
        //点击城市字母
        letterTap(e) {
          const Item = e.currentTarget.dataset.item;
          this.setData({
            cityListId: Item
          });
          console.log("..............."+this.data.cityListId);
        },
        //调用定位
        getLocate() {
          let that = this;
          new qqmap().getLocateInfo().then(function (val) {//这个方法在另一个文件里,下面有贴出代码
            console.log(val);
            if (val.indexOf('市') !== -1) {//这里是去掉“市”这个字
              console.log(val.indexOf('市') - 1);
              val = val.slice(0, val.indexOf('市'));
              console.log(val);
            }
            that.setData({
              locateCity: val
            });
            //把获取的定位和获取的时间放到本地存储
            wx.setStorageSync('locatecity', { city: val, time: new Date().getTime() });
          });
        },
    
      onShow() {
        console.log(getApp());
        let that = this,
          cityOrTime = wx.getStorageSync('locatecity') || {},
          time = new Date().getTime(),
          city = '';
        if (!cityOrTime.time || (time - cityOrTime.time > 1800000)) {//每隔30分钟请求一次定位
          this.getLocate();
        } else {//如果未满30分钟,那么直接从本地缓存里取值
          that.setData({
            locateCity: cityOrTime.city
          })
        }
    
    
      }
    })

    然后运行就可以了

    完结

     想了解更多的小程序的知识请添加微信小程序开发交流群:368506119

  • 相关阅读:
    项目成本管理(三)
    项目成本管理(二)
    项目成本管理(一)
    男士香水
    荷兰猛兽-梅尔文训练体能
    PP学习笔记-业务基础
    SAP入行就业
    PP学习笔记02
    BZOJ 3012: [Usaco2012 Dec]First! 字典树 + tarjan
    CF319E Ping-Pong 线段树 + vector + 思维
  • 原文地址:https://www.cnblogs.com/xjwy/p/8317144.html
Copyright © 2011-2022 走看看