微信小程序-根据城市首字母定位城市列表(包含搜索和热门城市)已封装成组件可以直接用

先给大家上效果图:
整体效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

想上传视频给你们看整体效果的,看了一下好麻烦哦~
接下来进入正题:文件目录图
在这里插入图片描述
废话不多说直接上代码了啊~
city.js文件里是一些配置数据,你们也可以直接写在组件的js文件data里,只是为了给你展示一下,这些城市列表数据按理来说应该都是后端给你返回的,城市列表的首字母展示不一定就是26个字母,也可以根据已有的城市首字母去展示。

// city.js 
let citylist = [{ "letter": "A", "data": [{ "cityId": "v7", "cityName": "安徽" }] }, { "letter": "B", "data": [{ "cityId": "v10", "cityName": "巴中" }, { "cityId": "v4", "cityName": "包头" }, { "cityId": "v1", "cityName": "北京" }] }, { "letter": "C", "data": [{ "cityId": "v15", "cityName": "成都" }] }, { "letter": "D", "data": [{ "cityId": "v21", "cityName": "稻城" }] }, { "letter": "G", "data": [{ "cityId": "v17", "cityName": "广州" }, { "cityId": "v29", "cityName": "桂林" }] }, { "letter": "H", "data": [{ "cityId": "v9", "cityName": "海南" }, { "cityId": "v3", "cityName": "呼和浩特" }] }, { "letter": "L", "data": [{ "cityId": "v24", "cityName": "洛阳" }, { "cityId": "v20", "cityName": "拉萨" }, { "cityId": "v14", "cityName": "丽江" }] }, { "letter": "M", "data": [{ "cityId": "v13", "cityName": "眉山" }] }, { "letter": "N", "data": [{ "cityId": "v27", "cityName": "南京" }] }, { "letter": "S", "data": [{ "cityId": "v18", "cityName": "三亚" }, { "cityId": "v2", "cityName": "上海" }] }, { "letter": "T", "data": [{ "cityId": "v5", "cityName": "天津" }] }, { "letter": "W", "data": [{ "cityId": "v12", "cityName": "乌鲁木齐" }, { "cityId": "v25", "cityName": "武汉" }] }, { "letter": "X", "data": [{ "cityId": "v23", "cityName": "西安" }, { "cityId": "v28", "cityName": "香港" }, { "cityId": "v19", "cityName": "厦门" }] }, { "letter": "Z", "data": [{ "cityId": "v8", "cityName": "张家口" }] }]

let hotCity = [{ "cityId": "v1", "cityName": "北京" }, { "cityId": "v2", "cityName": "上海" }, { "cityId": "v27", "cityName": "南京" }, { "cityId": "v15", "cityName": "成都" }, { "cityId": "v17", "cityName": "广州" }, { "cityId": "v25", "cityName": "武汉" }, { "cityId": "v19", "cityName": "厦门" }]

let letter = ["hot","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"]

// 获取所有城市列表
function cityRes(cityName) {
  let allcity = [];
  citylist.forEach(v => {
    v.data.forEach(v1 => { allcity.push(v1) })
  })

  let cityRes = allcity.filter(v => {
    if (v.cityName.includes(cityName)) {
      return v;
    }
  });

  return cityRes

}

module.exports = {
  citylist,
  hotCity,
  letter,
  cityRes
}

在微信小程序里创建components文件,把我们的城市列表(citylist)组件文件放在此下面。
下面展 citylist.js基本所以逻辑都在这里了,城市的定位可以去使用腾讯地图微信小程序sdk(qqmapsdk),或者你们有别的方法也可以使用,这里不多赘述。

// citylist.js
import city from "../../utils/city.js"
Component({
  /**
   * 组件的属性列表
   */
  properties: {

  },

  /**
   * 组件的初始数据
   */
  data: {
    hidden: true,
    showCity: true,
    cityData: {},
  },

  lifetimes: {
    attached: function () {
      // 在组件实例进入页面节点树时执行
      this.setData({
        cityData: city
      })
    },
    detached: function () {
      // 在组件实例被从页面节点树移除时执行
    },
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 输入事件
    inputTap(e) {
      let keywords = e.detail.value;
      this.setData({
        keywords,
        showCity: false
      })
      let cityRes = city.cityRes(keywords)
      this.setData({
        cityRes,
      })

    },

    // 输入框回车搜索事件
    confirmTap(e) {
      let keywords = e.detail.value;
      this.setData({
        keywords,
        showCity: false
      })
      let cityRes = city.cityRes(keywords)
      this.setData({
        cityRes,
      })
    },

    //选择城市
    selectCity: function (e) {
      var dataset = e.currentTarget.dataset;
      let usualData = this.data.usualData;

      wx.showToast({
        icon: "none",
        title: dataset.cityname,
      })
    },
    touchstart: function (e) {
      this.setData({
        index: e.currentTarget.dataset.index,
        Mstart: e.changedTouches[0].pageX
      });
    },
    touchmove: function (e) {
      var history = this.data.historyList;
      var move = this.data.Mstart - e.changedTouches[0].pageX;
      history[this.data.index].x = move > 0 ? -move : 0;
      this.setData({
        historyList: history
      });
    },
    touchend: function (e) {
      var history = this.data.historyList;
      var move = this.data.Mstart - e.changedTouches[0].pageX;
      history[this.data.index].x = move > 100 ? -180 : 0;
      this.setData({
        historyList: history
      });
    },

    //获取文字信息
    getPy: function (e) {
      this.setData({
        hidden: false,
        showPy: e.target.id,
      })
    },

    setPy: function (e) {
      this.setData({
        hidden: true,
        scrollTopId: this.data.showPy
      })
    },

    //滑动选择城市
    tMove: function (e) {
      var y = e.touches[0].clientY,
        offsettop = e.currentTarget.offsetTop;

      //判断选择区域,只有在选择区才会生效
      if (y > offsettop) {
        var num = parseInt((y - offsettop) / 12);
        this.setData({
          showPy: this.data._py[num]
        })
      };
    },

    //触发全部开始选择
    tStart: function () {
      this.setData({
        hidden: false
      })
    },

    //触发结束选择
    tEnd: function () {
      this.setData({
        hidden: true,
        scrollTopId: this.data.showPy
      })
    },

    // 输入框删除icon事件
    delTap() {
      this.setData({
        keywords: "",
        showCity: true,
      })
    },
  }
})

下面展示 citylist.wxml

<!--components/citylist/citylist.wxml-->
<!--pages/citylist/citylist.wxml-->
<view class="city-body">
  <!-- 搜索城市 -->
  <view class="search-bar">
    <view class="search-row">
      <view class="input-box">
        <image src="/images/search.png"></image>
        <input placeholder="请输入城市名称查询" confirm-type="search" bindinput="inputTap" bindconfirm="confirmTap" value="{{keywords}}"></input>
        <image src="/images/cancel.png" bindtap="delTap"></image>
      </view>
      <!-- <text bindtap="searchCity">搜索</text> -->
    </view>

  </view>

  <!-- 城市列表 -->
  <view class='list-city' wx:if="{{showCity}}">
    <scroll-view scroll-y="true" style="height:100%;" scroll-into-view="{{scrollTopId}}" scroll-with-animation="true" enable-back-to-top="true">
      <view class='item'>
        <view class='py'>当前定位</view>
        <view class="dw-style" data-citycode="{{dwcitycode}}" bindtap='{{dwcity?"selectCity":""}}'>
          <image src="/images/location.png"></image>
          <text style="color:{{dwcity?'':'#aaa'}}">{{dwcity?dwcity:'正在定位'}}</text>
        </view>
      </view>
      <!-- 热门城市 -->
      <view class='item' style="padding-bottom:25rpx;">
        <view class='py' id="hot">★ 热门城市</view>
        <view class="fullname hot-city" wx:for="{{cityData.hotCity}}" wx:key="key"  data-cityname="{{item.cityName}}" data-cityid="{{item.cityId}}" bindtap='selectCity'>{{item.cityName}}</view>
      </view>

      <!-- 全部 -->
      <view class='item' wx:for="{{cityData.citylist}}" wx:for-index="idx" wx:for-item="group" wx:key="key">
        <view class='py' id="{{group.letter}}">{{group.letter}}</view>
        <view class="fullname" wx:for="{{group.data}}" wx:key="key"  data-cityname="{{item.cityName}}" data-cityid="{{item.cityId}}" bindtap='selectCity'>{{item.cityName}}</view>
      </view>

    </scroll-view>

    <!-- 首字母 -->
    <view class='city-py' bindtouchstart="tStart" bindtouchend="tEnd" catchtouchmove="tMove">
      <view wx:for="{{cityData.letter}}" wx:key="key" bindtouchstart="getPy" bindtouchend="setPy" id="{{item}}">{{item == 'hot' ? "★" : item}}
      </view>
    </view>
  </view>

  <!-- 搜索结果 -->
  <scroll-view scroll-y="true" style="height:100%;" class="searchRes" wx:else>
    <view wx:if="{{cityRes!='' && keywords!=''}}">
      <view class="restitle">搜索结果</view>
      <view class="fullname" wx:for="{{cityRes}}" wx:key="key" data-cityname="{{item.cityName}}" data-cityid="{{item.cityId}}" bindtap='selectCity'>{{item.cityName}}</view>
    </view>
    <view class="no-city" wx:if="{{keywords && cityRes==''}}">
      <image src="/images/nocity.png"></image>
      <text>没有找到相关城市</text>
    </view>
    <!-- <view >没有找到相关城市</view> -->
  </scroll-view>

</view>

<!--选择显示-->
<view hidden="{{hidden}}" class="showPy">{{showPy == 'hot' ? "★" : showPy}}</view>

下面展示一些 citylist.wxss

/* pages/citylist/citylist.wxss */

page {
  height: 91.5%;
}

.city-body {
  /* padding-top: 92rpx; */
  box-sizing: border-box;
  height: 100%;
}

/* 定位城市 */

.dw-style {
  display: flex;
  align-items: center;
  padding: 25rpx;
}

.dw-style image {
  width: 55rpx;
  height: 55rpx;
  margin-right: 10rpx;
}

.dw-style text {
  font-size: 30rpx;
  color: #555;
}

/* 搜索城市 */

.search-bar {
  width: 100%;
  height: 110rpx;
  line-height: 100rpx;
  top: 0;
  box-sizing: border-box;
  overflow: hidden;
  padding: 20rpx;
  position: relative;

}

.search-row {
  display: flex;
  align-items: center;
}

.search-row text {
  font-size: 28rpx;
  font-family: PingFang SC;
  font-weight: 500;
  line-height: 40rpx;
  color: rgba(20, 20, 20, 1);
  opacity: 1;
  margin-left: 30rpx;
}

.input-box {
  height: 62rpx;
  /* background: #f5f5f5; */
  opacity: 1;
  border-radius: 32rpx;
  padding: 5rpx 10rpx;
  display: flex;
  align-items: center;
  font-size: 28rpx;
  flex: 1;
  border: 1rpx solid rgb(73, 157, 235);
}

.input-box image {
  width: 55rpx;
  height: 55rpx;
  margin: 0 10rpx;
}

.input-box input {
  flex: 1;
  height: 62rpx;
}

.list-detail,
.list-city {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  background: #fff;
}

.list-detail .item-nav {
  border-bottom: 1rpx solid #eee;
}

.list-detail .title,
.history .title {
  font-size: 32rpx;
  color: #000;
  line-height: 45rpx;
}

.list-detail .address,
.history .address {
  font-size: 28rpx;
  color: #aaa;
  white-space: normal;
}

/* 搜索结果 */

.searchRes .restitle {
  background: #eee;
  font-size: 25rpx;
  color: #aaa;
  padding: 12rpx 25rpx;
}

.citytext {
  box-sizing: border-box;
  font-size: 30rpx;
  color: #555;
  padding: 25rpx;
  border-bottom: 1rpx solid #eee;
}

.no-city {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-top: 255rpx;
}

.no-city image {
  width: 298rpx;
  height: 226rpx;
}

.no-city text {
  font-size: 28rpx;
  font-family: PingFang SC;
  font-weight: 500;
  line-height: 40rpx;
  color: rgba(167, 166, 166, 1);
  opacity: 1;
  margin-top: 25rpx;
}

/* 城市列表 */

.list-city {
  position: relative;
}

.py {
  box-sizing: border-box;
  background: #f5f5f5;
  font-size: 23rpx;
  color: #aaa;
  padding: 10rpx 25rpx;
}

.fullname {
  box-sizing: border-box;
  font-size: 30rpx;
  color: #555;
  padding: 25rpx;
  border-bottom: 1rpx solid #eee;
}

.city-py {
  position: fixed;
  top: 21%;
  right: 0;
  /* margin-top: -360rpx; */
}

.city-py view {
  font-size: 25rpx;
  width: 60rpx;
  height: 37rpx;
  line-height: 37rpx;
  text-align: center;
  /* color: #555; */
  color: rgb(73, 157, 235);
}

.showPy {
  width: 150rpx;
  height: 150rpx;
  background: #fff;
  border-radius: 15rpx;
  line-height: 150rpx;
  text-align: center;
  font-size: 80rpx;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: 3;
  /* color: #333; */
  color: rgb(73, 157, 235);
  box-shadow: 0 0 150rpx rgba(0, 0, 0, 0.35);
}

.hot-city {
  border: 1rpx solid #eee;
  display: inline-block;
  margin: 25rpx 0 0 22rpx;
  padding: 10rpx 0rpx;
  font-size: 25rpx;
  border-radius: 6rpx;
  width: 118rpx;
  text-align: center;
}

然后在你需要的页面直接引入

// 在json文件里
{
  "usingComponents": {
    "city-list":"/components/citylist/citylist"
  },
  "navigationBarBackgroundColor":"#82b8db",
  "navigationBarTextStyle":"white",
  "navigationBarTitleText":"城市列表"
}

// 在wxml里
<city-list></city-list>

如果有任何不明白的地方可以评论告诉我哦~ 我觉得大家一般也不想听分析吧((/ω\)捂脸)如果有大佬觉得哪里有可以改进的地方,也请大佬多多指教哦~

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值