微信小程序(同城小程序)_总结一(实现城市切换和搜索)

一、前言                                                                           

  •      城市切换
  •      城市搜索

二、基本内容                                                                    

1、豆瓣接口文档

  https://douban-api-docs.zce.me/

2、城市切换用到的接口

获取城市列表
https://douban.uieee.com/v2/loc/list
   

3、获取和处理城市

         3.1、index页面:

      (1)一开始加载程序在index页面中调用全局的getUserInfo() 和getLocation()方法获取到用户当前的信息

// pages/location/index/index.js
var app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    userInfo:{},
    motto:'豆瓣同城'

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that = this;
    //获取用户信息
    app.getUserInfo(function(userInfo){
      console.log(userInfo)
      that.setData({
        userInfo:userInfo
      })
    })
    //获取位置
    app.getLocation();
  },

//点击页面将当前用户的位置信息传到另一个location页面
  bindmottotap:function(event){
    var loc = ""
    if(app.globalData.latitude && app.globalData.longitude){
      loc = "?latitude=" + app.globalData.latitude + "&&longitude=" + app.globalData.longitude
    }
    wx.redirectTo({
      url: '/pages/location/location'+loc, 
    })

  }
})

     

      3.2、location页面

     (1)初始化的时候获取到index页面传来的参数

onLoad: function (options) {
    console.log(options)
    if (options.laitude && options.longitude){
      console.log("latitude:" + options.laitude+ ", longitude:"+options.longitude)
    }
    //获取用户当前的城市转化为小写
    if(typeof app.globalData.userInfo.city == 'string'){
      var cityUid = app.globalData.userInfo.city.toLowerCase()
      app.globalData.cityUid = cityUid
    }
this.
getLocationListData()
}

     (2)在onload中调用getLocationListData方法获取到若干个城市信息

  /*获取城市列表 */
  getLocationListData:function(){
    var that = this
    wx.showToast({
      title: '加载中',
      icon:'loading',
      duration:10000
    });
    var cityListURL = app.globalData.doubanBase + app.globalData.loc_list_url  //https://douban.uieee.com/v2/loc/list
    wx.request({
      url: cityListURL,
      data:{
        "start": 0,
        "count": 500
      },
      method:'GET',
      header:{
        'content-type':'json'
      },
      success:function(res){
        var citys = res.data.locs//
        that.handleLocationListData(citys) //处理获取到的城市信息
      },
      complete:function(){
        wx.hideToast()
      }  
    })
   
  },

       获取到的城市信息如下:

                     

      (3)处理上面获取到的城市信息

 //处理城市信息
  handleLocationListData(citys){
    var locs={};   //设置空对象,存放一个一个城市信息
    for(let cityId in citys){
      var loc = citys[cityId] //遍历数组,将每个城市对象取出来
      locs[loc.uid]=loc  //以各自对象中的uid为属性,存下每个城市对象
                                 //比如:locs["beijing"]={"beijin":{parent: "china", habitable: "yes", id: "108288", name: "北京", uid: "beijing"}}
    }
    //默认加载当前城市的活动,用户登录的城市
    var cityUid = app.globalData.cityUid
    var currentLoc = null;
    if(!locs[cityUid]){//如果用户登录的城市没有在获取到的城市列表中
      currentLoc = locs[this.data.defaultUid]//显示一个默认的城市
    }else{
      currentLoc = locs[cityUid]
    }
  
    app.globalData.locId= currentLoc.categoryId 
    app.globalData.city = currentLoc.name
    app.globalData.locs = locs//得到所有城市,存在全局变量中
    this.setData({
      "city":app.globalData.city,
      "currentLoc":currentLoc//设置当前城市,组合之后有三个属性
    })
    console.log(currentLoc.id)
    this.getActicityByLocationId(currentLoc.id)
  }

         城市信息处理完成之后得到:

locs                        
 
currentLoc

   cityUid: 

   

   categoryId:
   name:
   
  app.globalData.locId= currentLoc.categoryId
 
  app.globalData.city = currentLoc.name
  app.globalData.locs = locs//得到所有城市
   
   
   

      (4)点击城市切换的时候,将当前城市的id ,name, uid传过去

 //跳转到城市选择页面
  bindLocation:function(event){
    var parameter = "?id=" + this.data.currentLoc.id + "&&name=" + this.data.currentLoc.name + "&&uid=" + this.data.currentLoc.uid;
    console.log(this.data.currentLoc)
    wx.navigateTo({

      url: '/pages/location/select-city/select-city' + parameter
    });
  },

      3.3、城市切换页面

     

     (1)gps定位城市,页面一加载的时候获取到当前用户的城市信息

 onLoad: function (options) {
    console.log(options)
    var id = options.id;
    var uid = options.uid;
    var name = options.name;
    var gpsCity = {
      "id": id,
      "uid": uid,
      "name": name
    }
    var city = app.globalData.city  //是location中currentLoc.name
    var locs = app.globalData.locs  //全部的城市信息
    console.log(locs)
    console.log(city)
    this.setData({
      locs: locs,  //得到全部的城市信息
      gpsCity:gpsCity //组装gps定位城市属性
    })
    
    this.processCityListData(locs)
  },

    (2)根据之前获取到的一大堆城市信息表中,将这些城市信息分类处理

             处理一:自定义热门城市数组, 根据数组用map函数从所有的loc中筛选出热门城市对象

             处理二:遍历所有城市,将首字母获取出来,并排序

             处理三:根据首字母,将所有的城市分组

//处理城市的函数
  processCityListData:function(locs){
    if(locs && typeof locs =="object"){
      var hotCity = this.data.hotCityUid.map(function(item, index, input){
        console.log(item, index, input)//beijing 0 ,shanghai 1 ,guangzhou 2 
        return locs[item] //筛选出热门城市,locs:  { parent: "china", habitable: "yes", id: "108288", name: "北京", uid: "beijing" }
      })
      //按字母排序
      var keys = Object.keys(locs)// 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。
      keys.sort()
      console.log(locs) // anshan: { parent: "liaoning", habitable: "yes", id: "118125", name: "鞍山", uid: "anshan" }
      console.log(keys)//anshan
      var cityList = {}
      var letterList = []
      for(let idx in keys){ //遍历排序好的城市
        var key = keys[idx]
        console.log(key)//jinhua
        var letter = key.substring(0,1)//首字母
      
        var city = locs[key] //获取到的城市对象
        console.log(city)
        if(!cityList[letter]){
          cityList[letter]=[]
          letterList.push(letter)//将首字母放进一个单独的数组中

        }
        console.log(letterList)//1", "a", "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "q", "s", "t", "w", "x", "y", "z"
        cityList[letter].push(city)//按照首字母将城市分组


      }

      console.log("cityList: " + cityList)
      this.setData({
        "hotCity":hotCity,//对象数组 "id": id,"uid": uid, "name": name
        "letterList":letterList,//存首字母的对象的数组[1", "a", "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n"] 

"cityList":cityList//对象,每一个对象里面存着一个个条件相同的数组数组 }) } },

       3.4、处理点击

     (1)选择城市进行切换,

       

      html代码:

 <text class='hot-city-title'>热门城市</text>
  <view class='hot-city'>
    <view class='hot-city-content'>
    <block wx:for="{{hotCity}}" wx:key="key" wx:for-item="city">
     <!--点击的时候将自定义属性传进去--> 
 <text class='gps-loc city-box' data-id='{{city.id}}' data-name='{{city.name}}' data-uid='{{city.uid}}' bindtap='handleSelected'>{{city.name}}</text>
    </block>
    </view>
  </view>

      handleSelected函数:

 //城市选择
  handleSelected:function(event){
   console.log(event.target.dataset)//自定义参数带过来,然后更改请求的地址
    var id = event.target.dataset.id;
    var name = event.target.dataset.name
    var uid = event.target.dataset.uid
    var currentLoc = {
      "id": id, "name": name, "uid": uid
    };
    wx.navigateTo({
      url:"/pages/location/location",
      success:function(){
        app.globalData.reflesh = true;
        app.globalData.locId = id;//当前城市的id
        app.globalData.city = name; //城市名称
        app.globalData.cityUid = uid;//城市uid
        app.globalData.currentLoc = currentLoc;//当前城市对象,包含id uid name
      }
    })
    console.log(app.globalData.currentLoc)

  }

   (2)城市查询

          

  <view class="page-session page-session-spacing">
    <view class="search-session">
      <icon type="search" size="16"></icon>
      <block wx:if="{{!searching}}" wx:key="key">
        <text class="search-holder" bindtap="bindSearch">输入城市名称查询</text>
      </block>
      <block wx:elif="{{searching}}">
        <input class="search-input" placeholder-class="search-placeholder" value="" placeholder="输入城市名称查询" focus="true"  bindconfirm='handleConfirm'  bindblur='handleBlur' bindinput='handleInput'/>
        <text class="cancel" bindtap="handleCancel">取消</text>
      </block>
    </view>
  </view>
  <block wx:if="{{searching}}">
    <view class="select-city-body {{searching ? 'select-city-body-cover':'select-city-body-hidden'}}" catchtap="handleCancel">  </view>   
  
      <view class='city-list-wrapper'>
        <view class='city-list'>
          <block wx:for="{{searchLetterList}}" wx:for-item="letter">
            <text class='list-title'>{{letter}}</text>
            <view class='list-content'>
            <block wx:for="{{searchCityList[letter]}}" wx:for-item="city">
                <text class="city-block" data-id="{{city.id}}" data-name="{{city.name}}" data-uid="{{city.uid}}" bindtap="bindCityTap">{{city.name}}</text>
            </block>
            </view>
            
          </block>
        </view>
      </view>
  
    <block wx:if="{{showSearchNone}}">
    <view class='search-none'>这里是空的</view>
    </block>
  </block>

对输入框注册监听事件

  //处理输入
  handleInput: function(event){
    console.log(event)
   var value = event.detail.value
    console.log(value) //获取输入的内容

    var searchLocs = {}  //定义收索的城市对象
    var searchCityList = {}//定义收索的城市列表
    var searchLetterList=[]//将搜索到的城市分组
    var readyData={
      "searchLocs": searchLocs,
      "searchCityList": searchCityList,
      "searchLetterList": searchLetterList,
      "showSearchNone":false  //控制显示隐藏
    }
    if(value==""){
      this.setData(readyData)//输入为空,给data添加一个readyData属性
      return;
    }
    console.log(this.data.locs)//所有的没有处理的城市信息
    var locKeys = Object.keys(this.data.locs) 
    console.log(locKeys)//["118181", "beijing", "shanghai", "guangzhou", "shenzhen"]
    for(let idx in locKeys){
      var key = locKeys[idx]
      if(key.indexOf(value)!=-1){//如数字母,如果匹配到了,就将找到的城市加入到搜到的城市中
        searchLocs[key] = this.data.locs[key]
      }else if(this.data.locs[key].name.indexOf(value)!=-1){//如果输入汉字的时候找到了,就将当前城市对象也加入里面
        (searchLocs[key] = this.data.locs[key])
      }
    }


  var keys = Object.keys(searchLocs) //得到属性
  var keyLength = keys.length
  if(keyLength==0){ //如果长度为0,说明没有相同的
    readyData["showSearchNone"]=true
    this.setData(readyData)
    return;
  }

  keys.sort();
  for(let idx in keys){
    var key = keys[idx]
    var letter = key.substring(0,1)
    var city = searchLocs[key]
    if(!searchCityList[letter]){
      searchCityList[letter]=[]
      searchLetterList.push(letter)
    }
    searchCityList[letter].push(city)
  }
   readyData["searchLocs"] = searchLocs
   readyData["searchCityList"] = searchCityList
    readyData["searchLetterList"] = searchLetterList
   this.setData(readyData)
  console.log(readyData)
  },

三、总结                                                                           

虽然现在走得很慢,但不会一直这么慢
原文地址:https://www.cnblogs.com/xxm980617/p/10952885.html