先给大家上效果图:
想上传视频给你们看整体效果的,看了一下好麻烦哦~
接下来进入正题:文件目录图
废话不多说直接上代码了啊~
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>
如果有任何不明白的地方可以评论告诉我哦~ 我觉得大家一般也不想听分析吧((/ω\)捂脸)如果有大佬觉得哪里有可以改进的地方,也请大佬多多指教哦~