不说废话,上效果图

因为我有多处要用到,所以我这里是写成自定义组件的,你也可以直接改成在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='width: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{
width: 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{
width: 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

微信小程序实现按首字母检索城市列表的更多相关文章

  1. 微信小程序rich-text 文本首行缩进和图片居中

    微信小程序开发使用rich-text组件渲染html格式的代码,常常因为不能自定义css导致文本不能缩进,以及图片不能居中等问题,这里可以考虑使用js的replace方法,替换字符串,然后在渲染的同时 ...

  2. 微信小程序- 提示不在以下合法域名列表中

    第一次开发微信小程序时在访问后台数据时总是提示 提示上面问题主要有两个原因: 1.为配置安全合法域名列表: 微信小程序在开发时需要在官网配置固定的数据来源网站: 登录小程序平台中->设置: 图中 ...

  3. 微信小程序 项目实战(三)list 列表页 及 item 详情页

    1.项目结构 2.list 列表页 (1)数据(逻辑) list.js // pages/list/list.js Page({ /** * 页面的初始数据 */ data: { title: '加载 ...

  4. 微信小程序踩坑集合

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教程:https://mp.weixin.qq.com/debu ...

  5. 微信小程序开发学习资料

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  6. 微信小程序基础之开源项目库汇总

    awesome-github-wechat-weapp 是由OpenDigg整理并维护的微信小程序开源项目库集合.我们会定期同步OpenDigg上的项目到这里,也欢迎各位提交项目给我们. (链接:ht ...

  7. 微信小程序< 3 > ~ 微信小程序开源项目合集

    简介 移动开发者想学习微信小程序需要学习一点HTML ,CSS和JS才能够比较快速的上手,参考自己学习Android学习过程,阅读源码是一个很好的方式,所以才收集了一些WeApp的开源项目. awes ...

  8. 微信小程序学习指南

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  9. 微信小程序导航:官方工具+精品教程+DEMO集合(1月7更新)

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=14764346784612:简易教程:https://mp.weixin.qq.com/debug ...

随机推荐

  1. Ubuntu安装微信开发者工具

    参考教程:https://ruby-china.org/topics/30339 1.下载nw sdk $ wget -c http://dl.nwjs.io/v0.15.3/nwjs-sdk-v0. ...

  2. idea将maven项目打包成war包的方式,以及使用war包

    打包WAR过程 首先对项目进行编译.然后执行以下步骤: 单击下图红色方框处  在IDEA右侧出现maven project选项  单击maven project选项,出现Spring MVC Basi ...

  3. 常见.NET功能代码汇总 (3)

    33,彻底关闭Excel进程 .NET中使用Excel属于使用非托管资源,使用完成后一般都要用GC回收资源,但是,调用GC的位置不正确,Excel进程可能无法彻底关闭,如下面的代码: static v ...

  4. 【CSS3】动画animation-关键帧keyframes

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. HTML基础教程-简介

    关于html5笔记前言 之前有在W3school学习过html5以及javascript.为了和大家一块学习,为了回顾这些遗忘的基础,现在我把之前自己整理的笔记共享给大家.希望大家共同进步. HTML ...

  6. 聊天机器人(基于android)

    1.本人最近写了一个小项目关于语音聊天的,采用讯飞语音引擎和数据,看看效果 2.项目名称叫小秘书,它可以和你进行交互,可以通过语音聊天,蛮有意思的,聊天内容你也可以定制 3.如果想做这款应用,先看看我 ...

  7. vbs的一些入门基础。。。

    VBS(VBScript的进一步简写)是基于Visual Basic的脚本语言. Microsoft Visual Basic是微软公司出品的一套可视化编程工具, 语法基于Basic. 脚本语言, 就 ...

  8. find 命令详解

    find 作用:用于在文件树种查找文件,并作出相应的处理 (硬盘) 格式:find pathname -options [-print -exec -ok ...] 格式参数:pathname: fi ...

  9. for 在项目实战中用的比较多

    for循环编程语言中的语句之一,用于循环执行.for循环是开界的,它的一般形式为: for(; <条件表达式>; ) 语句: 初始化通常是一个赋值语句, 它用来给循环控制变量赋初值: 条件 ...

  10. Linux(CentOS6.5)修改默认yum源为国内的阿里云、网易yum源

    官方的yum源在国内访问效果不佳. 需要改为国内比较好的阿里云或者网易的yum源 修改方式: echo 备份当前的yum源 mv /etc/yum.repos.d /etc/yum.repos.d.b ...