美文网首页
小程序中实现城市选择列表

小程序中实现城市选择列表

作者: 超人鸭 | 来源:发表于2019-10-18 17:31 被阅读0次

    直入主题,实现什么蛇皮东西呢?大概是这个样子:

    image.png
    点击右边字母表的某个字母能跳转,然后搜索:
    image.png
    先一步一步来,首先渲染出这个城市列表,为了方便而且中国的城市名称基本不会有变动,所以我直接把城市的数据全部写在一个对象里面导出,当然不可能手写,大家百度就可以拿得到,这里我提供一个:中国所有城市按拼音排序json文件
    然后大家把这个文件的 cities对象整个复制出来,在你的小程序的某个js文件中:
    image.png
    然后在你要用的地方就可以引用:
    import {citys} from '../../base/citys.js'  // 你的路径
    

    这样就可以得到全部城市的信息,然后去遍历,但是这个citys是个对象,在小程序中去wx:for一个对象,然后对象的每个属性才是数组,会是怎么样的呢?
    其实就是跟遍历二维数组一样,进行双层遍历,然后区别我在下面再讲,先看代码:

    <view wx:for="{{citys}}"
              wx:for-index="key"  // 重命名wx:for的索引
              wx:for-item="value"  // 重命名wx:for的循环项
              wx:key="{{key}}">
      <view id="{{key}}" class="search-title">{{key}}</view>  // 每一组的标题也就是A、B、C...
      <view wx:for="{{value}}"
                wx:key="{{index}}"
                class="item-label">
        <text>{{item.name}}</text>
      </view>
    </view>
    

    第一层循环是去循环对象,wx:for的索引名称默认是index,如果是去遍历对象,那这个索引就是对象的key,也就是ABCD,所以我将它改名为key,然后将每一个循环项的名称改为value,就是上面的每一个数组,第二层遍历就是正常的遍历数组,这样就可以遍历出整个城市列表。

    • 接下来是右边的字母表
      拿同样的数据去遍历就可以,这次只需要显示出对象的key就可以:
    <view class="alphabet">
      <view wx:for="{{citys}}"
                wx:for-index="key"
                wx:key="{{key}}"
                class="alphabet-item"
                catchtap="chooseCitys"
                data-id="{{key}}">
                {{key}}
      </view>
    </view>
    

    接下来是实现点击字母表的字母跳转到列表的指定位置,看我上面的两段代码,在城市列表的每一组标题我给绑定了id,是用对象的key绑定,也就是A、B、C、D...,然后在字母表的每一个字母也绑定了自定义属性data-id,同样也是用key绑定,这样和上面的标题对应上,接下来就是实现。
    首先我们要跳转到指定位置,超人鸭看了小程序的组件文档,发现了一个叫scroll-view的组件,这是它的部分属性:


    image.png

    我圈住的属性就是实现跳转的关键,传入一个元素id,就可以跳转到指定元素的位置,我们把城市列表都包裹中scroll-view组件里面,并写上相应属性:

    <scroll-view scroll-y="true"
                 style="height:100%;"
                 scroll-into-view="{{id}}">
      // 城市列表
    </scroll-view>
    

    这里需要注意的一个点是设置scroll-view组件的方向为纵向的时候需要为组件指定高度。
    给scroll-into-view动态的绑定一个id,需要在data中定义id这个变量
    然后在字母表的点击事件中改变这个id,记得我们上面给每个字母绑定了自定义属性data-id="{{key}}",在点击事件中可以拿到:

      chooseCitys(event) {  // 点击字母表跳转到指定的城市列表
        const id = event.target.dataset.id
        console.log(id)
        this.setData({
          id
        })
      }
    

    这样就完成了点击字母表进行跳转的功能,接下来是搜索,回到一开始的城市列表数据,每个城市都有中文名和拼音,所以可以实现通过名称或者拼音实现搜索,这是搜索框:

    <input class="search-input" placeholder="请输入城市中文名或拼音" bindinput="handleInput"></input>
    

    然后先看我一开始贴的demo图,搜索之后,整个页面是显示搜索结果,我自己的实现方式是在原来的页面上加一个层,设置z-index遮住原来的页面,先看看wxml:

    <view class="search-content" hidden="{{!isShow}}">
      <scroll-view scroll-y style="height:100%;">
        <view wx:for="{{searchCitys}}" wx:key="{{index}}">
          <text>{{item.name}}</text>
        </view>
        <view wx:if="{{!searchCitys.length}}">没有匹配数据</view>
      </scroll-view>
    </view>
    

    看看这一个view的样式:

    .search-content{
      position: absolute;
      top: 110rpx;  // 搜索框的高度
      left: 0;
      bottom: 0;
      right: 0;
      z-index: 3;
    }
    

    然后上面定义两个变量,一个是isShow控制这一层的出现与消失,第二个是searchCitys,也就是搜索出来的结果,都需要在data中定义,然后逻辑在input的输入事件中执行,上面定义了bindinput="handleInput"

    handleInput(event){  // 输入框输入或改变事件
      let value = event.detail.value  // 获取输入框中的值
      let list = []  // 临时变量
      this.setData({
        isShow: true  // 显示
      })
      if(value == '') {  // 如果清空输入框
        this.setData({
          isShow: false,  // 隐藏
          searchCitys: []  // 清空搜索结果
        })
        return   // 不再往下执行(重要!)
      }
      for(let k in citys) {  // 进行匹配,citys就是全部城市数据
        citys[k].forEach((item) => {
          if(item.spell.indexOf(value) != -1 || item.name.indexOf(value) != -1) {
            list.push(item)
          }
        })
      }
      this.setData({
        searchCitys: list  // 赋值
      })
    }
    

    这样就实现了搜索框一输入就会显示那一层搜索结果的页面,如果清空搜索结果就会自动隐藏,同时实现了搜索功能与提示:


    image.png

    这次超人鸭是在原来的功能上提炼出这个功能来写博文,代码也都是盲改,逻辑是没错的,但如果代码有错误或者有其他方法,欢迎指教哦。

    相关文章

      网友评论

          本文标题:小程序中实现城市选择列表

          本文链接:https://www.haomeiwen.com/subject/iywimctx.html