当前位置:   article > 正文

微信小程序实现按首字母检索城市列表_微信小程序 根据拼音排序,自动锚定节点定位当前城市

微信小程序 根据拼音排序,自动锚定节点定位当前城市

不说废话,上效果图

 

因为我有多处要用到,所以我这里是写成自定义组件的,你也可以直接改成在page页面编写:

布局左边一个scroll-view,显示城市列表,右边一个view显示字母列表,城市列表这边有首字母显示,给这个添加这个字母的ID,然后给右边的26个字母添加点击事件,点击的时候获取到点击的是哪个字母,给scroll-view的scroll-into-view赋值相应的字母,它左边就可以跳到相应的地方,再给scroll-view 加一个scroll-with-animation,让它跳转的时候有动画效果;

 

首先,我们来看看wxml

  1. <view class='city_box' style='{{styles}}'>
  2. <view class='city_left'>
  3. <scroll-view scroll-y style='width:100%;height:100%;' scroll-with-animation scroll-into-view='{{cityListId}}'>
  4. <view class='city_locate' data-types='locate' catchtap='cityTap'>
  5. <text class='city_locate_title'>自动定位</text>
  6. <text class='city_locate_text' style='{{!locateCity&&"color:#33b9ff;"}}'>{{locateCity||'点击定位'}}</text>
  7. </view>
  8. <view class='national' data-types='national' catchtap='cityTap'>全国</view>
  9. <view class='new_city'>
  10. <view class='new_city_title'>热门城市</view>
  11. <view class='new_city_box'>
  12. <text class='new_city_text' wx:for='{{newcity}}' wx:key='this' data-types='new' catchtap='cityTap' data-val='{{item}}'>{{item}}</text>
  13. </view>
  14. </view>
  15. <view class='city_list_box'>
  16. <block wx:for='{{citylist}}' wx:key='this' wx:for-item='letterItem' wx:for-index='letterIndex'>
  17. <view class='city_first_letter' id='{{letterItem.letter}}'>{{letterItem.letter}}</view>
  18. <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>
  19. </block>
  20. </view>
  21. </scroll-view>
  22. </view>
  23. <view class='city_right'>
  24. <text class='letter_item' wx:for='{{letter}}' wx:key='this' catchtap='letterTap' data-item='{{item}}'>{{item}}</text>
  25. </view>
  26. </view>

然后wxss

  1. .city_box{
  2. height:100%;
  3. background: #fff;
  4. display: flex;
  5. }
  6. .city_left{
  7. flex: 1;
  8. }
  9. .city_right{
  10. width: 60rpx;
  11. display: flex;
  12. flex-direction: column;
  13. justify-content: space-around;
  14. }
  15. .letter_item{
  16. flex: 1;
  17. display: block;
  18. font-size: 24rpx;
  19. color: #33B9FF;
  20. text-align: center;
  21. }
  22. .city_locate,.national{
  23. height: 80rpx;
  24. line-height: 80rpx;
  25. border-bottom: 1px solid #efefef;
  26. font-size: 28rpx;
  27. color: #333;
  28. padding-left: 25rpx;
  29. }
  30. .city_locate_title{
  31. color: #999;
  32. margin-right: 20rpx;
  33. }
  34. .new_city{
  35. background: #efefef;
  36. font-size: 28rpx;
  37. }
  38. .new_city_title{
  39. line-height: 50rpx;
  40. color: #999;
  41. padding-left: 25rpx;
  42. margin-bottom: 20rpx;
  43. }
  44. .new_city_box{
  45. display: flex;
  46. flex-wrap: wrap;
  47. }
  48. .new_city_text{
  49. width: 200rpx;
  50. text-align: center;
  51. line-height: 70rpx;
  52. background: #fff;
  53. border-radius: 35rpx;
  54. margin:0 0 22rpx 22rpx;
  55. }
  56. .city_first_letter{
  57. line-height: 40rpx;
  58. height: 40rpx;
  59. padding-left: 25rpx;
  60. font-size: 28rpx;
  61. background: #eee;
  62. color: #999;
  63. }
  64. .city_name{
  65. display: block;
  66. line-height: 80rpx;
  67. height: 80rpx;
  68. border-bottom: 1px solid #efefef;
  69. font-size: 28rpx;
  70. color: #333;
  71. padding-left: 25rpx;
  72. }

然后是json文件,因为我这里是组件,所以是下面这样,如果你不是的组件,那么不要这句

  1. {
  2. "component": true
  3. }

 

最后JS,因为我这里是写的一个组件,所以是Component而不是Page

  1. import qqmap from '../../utils/map.js';
  2. Component({
  3. properties: {
  4. styles:{//这个是可以自定义最外层的view的样式
  5. type:String,
  6. value:'',
  7. observer: function (newval, oldval) {
  8. // 监听改变
  9. console.log(newval, oldval);
  10. }
  11. }
  12. },
  13. data: {
  14. //下面是字母排序
  15. 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"],
  16. cityListId: '',
  17. //下面是城市列表信息,这里只是模拟数据
  18. 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": "张家口" }] }],
  19. //下面是热门城市数据,模拟数据
  20. newcity: ['北京', '上海', '广州', '深圳', '成都', '杭州'],
  21. // citySel: '全国',
  22. locateCity: ''
  23. },
  24. methods: {
  25. //点击城市
  26. cityTap(e) {
  27. const val = e.currentTarget.dataset.val || '',
  28. types = e.currentTarget.dataset.types || '',
  29. Index = e.currentTarget.dataset.index || '',
  30. that=this;
  31. let city = this.data.citySel;
  32. switch (types) {
  33. case 'locate':
  34. //定位内容
  35. city = this.data.locateCity;
  36. break;
  37. case 'national':
  38. //全国
  39. city = '全国';
  40. break;
  41. case 'new':
  42. //热门城市
  43. city = val;
  44. break;
  45. case 'list':
  46. //城市列表
  47. city = val.cityName;
  48. break;
  49. }
  50. if(city){
  51. wx.setStorage({
  52. key: 'city',
  53. data: city
  54. })
  55.     //点击后给父组件可以通过bindcitytap事件,获取到cityname的值,这是子组件给父组件传值和触发事件的方法
  56. this.triggerEvent('citytap', { cityname: city });
  57. }else{
  58. console.log('还没有');
  59. this.getLocate();
  60. }
  61. },
  62. //点击城市字母
  63. letterTap(e) {
  64. const Item = e.currentTarget.dataset.item;
  65. this.setData({
  66. cityListId: Item
  67. });
  68. console.log(this.data.cityListId);
  69. },
  70. //调用定位
  71. getLocate(){
  72. let that=this;
  73. new qqmap().getLocateInfo().then(function (val) {//这个方法在另一个文件里,下面有贴出代码
  74. console.log(val);
  75. if (val.indexOf('市') !== -1) {//这里是去掉“市”这个字
  76. console.log(val.indexOf('市') - 1);
  77. val = val.slice(0, val.indexOf('市'));
  78. console.log(val);
  79. }
  80. that.setData({
  81. locateCity: val
  82. });
  83. //把获取的定位和获取的时间放到本地存储
  84. wx.setStorageSync('locatecity', { city: val, time: new Date().getTime() });
  85. });
  86. }
  87. },
  88. ready(){
  89. console.log(getApp());
  90. let that = this,
  91. cityOrTime = wx.getStorageSync('locatecity')||{},
  92. time = new Date().getTime(),
  93. city='';
  94. if (!cityOrTime.time||(time - cityOrTime.time > 1800000)){//每隔30分钟请求一次定位
  95. this.getLocate();
  96. }else{//如果未满30分钟,那么直接从本地缓存里取值
  97. that.setData({
  98. locateCity: cityOrTime.city
  99. })
  100. }
  101. }
  102. })

 

然后是引用的map.js,这里需要用到腾讯地图的微信小程序sdk获取当前经纬度的详情信息,然后取到当前城市,这是腾讯地图微信小程序JavaScript SDK,可以去查看教程,这里用到的是地址解析功能;

  1. const wxqqmap = require('../libs/qqmap-wx-jssdk.min.js'),
  2. qqwxmap = new wxqqmap({
  3. key: 'GTDBZ-WFSRX-JOT4W-7WYBD-Z2CTO-7QBEM' // 必填,这里最好填自己申请的的
  4. });
  5. import util from './util.js';
  6. const qq='sdfsdf';
  7. export default class qqmap{//获取定位信息
  8. getLocateInfo(){
  9. let that=this;
  10. return new Promise(function (resolve, reject) {
  11. that.location().then(function(val){
  12. //如果通过授权,那么直接使用腾讯的微信小程序sdk获取当前定位城市
  13. qqwxmap.reverseGeocoder({
  14. location: {
  15. latitude: val.latitude,
  16. longitude: val.longitude
  17. },
  18. success: function (res) {
  19. console.log(res.result.address_component.city);
  20. resolve(res.result.address_component.city);//返回城市
  21. },
  22. fail: function (res) {
  23. reject(res);
  24. },
  25. complete: function (res) {
  26. console.log(res);
  27. }
  28. });
  29. },function(error) {
  30. //如果用户拒绝了授权,那么这里会提醒他,去授权后再定位
  31. console.log('shibai');
  32. wx.showModal({
  33. title: '',
  34. content: '自动定位需要授权地理定位选项',
  35. confirmText: '去授权',
  36. success(res) {
  37. if (res.confirm) {
  38. wx.openSetting({
  39. success(res) {
  40. console.log(res);
  41. that.getLocateInfo();
  42. }
  43. })
  44. }
  45. }
  46. })
  47. })
  48. })
  49. }
  50. //定位,获取当前经纬度
  51. location(){
  52. return new Promise(function (resolve, reject) {
  53. wx.getLocation({
  54. altitude: true,
  55. success: function (res) {
  56. resolve(res);
  57. },fail(res){
  58. reject(res);
  59. }
  60. })
  61. });
  62. }
  63. }

然后在引用这个组件的时候,在引用的页面的json文件里要添加这一句

  1. {
  2. "usingComponents":{
  3. "citylist":"../../component/cityListCom/cityListCom"
  4. }
  5. }

然后在引用的wxml界面添加组件,styles是设置的组件的变量,我这里是可以改变组件最外层的样式,bindcitytap是上面组件js里的点击城市方法里提到的事件

<citylist styles='max-height:100%;' bindcitytap='cityTap'></citylist>

然后在引用的界面的js里,写个cityTap事件,获取传过来的值

  1. // pages/cityList/cityList.js
  2. Page({
  3. data: {
  4. winHeight:0
  5. },
  6. //监听传值,后面自己做处理了
  7. cityTap(e){
  8. console.log('fasdfsdfsdfds');
  9. console.log(e);
  10. const cityName=e.detail.cityname;
  11. wx.navigateBack();
  12. },
  13. /**
  14. * 生命周期函数--监听页面加载
  15. */
  16. onLoad: function (options) {
  17. const win = wx.getSystemInfoSync();
  18. console.log(win);
  19. this.setData({
  20. winHeight: win.windowHeight
  21. });
  22. }
  23. })

这样就可以了。

 

如果不想写成组件的,想直接写在一个页面里面,需要改一下

 

首先wxml里面去掉圈起来的这句

 

 

WXSS里面添加page{height:100%;}

 

JS里面改成这样

  1. import qqmap from '../../utils/map.js';//这里的路径看你自己的文件路径
  2. Page({
  3. data: {
  4. //下面是字母排序
  5. 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"],
  6. cityListId: '',
  7. //下面是城市列表信息,这里只是模拟数据
  8. 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": "张家口" }] }],
  9. //下面是热门城市数据,模拟数据
  10. newcity: ['北京', '上海', '广州', '深圳', '成都', '杭州'],
  11. // citySel: '全国',
  12. locateCity: ''
  13. },
  14. //点击城市
  15. cityTap(e) {
  16. console.log(e)
  17. const val = e.currentTarget.dataset.val || '',
  18. types = e.currentTarget.dataset.types || '',
  19. Index = e.currentTarget.dataset.index || '',
  20. that = this;
  21. let city = this.data.citySel;
  22. switch (types) {
  23. case 'locate':
  24. //定位内容
  25. city = this.data.locateCity;
  26. break;
  27. case 'national':
  28. //全国
  29. city = '全国';
  30. break;
  31. case 'new':
  32. //热门城市
  33. city = val;
  34. break;
  35. case 'list':
  36. //城市列表
  37. city = val.cityName;
  38. break;
  39. }
  40. if (city) {
  41. wx.setStorage({
  42. key: 'city',
  43. data: city
  44. })
  45.     //点击后给父组件可以通过bindcitytap事件,获取到cityname的值,这是子组件给父组件传值和触发事件的方法
  46. this.triggerEvent('citytap', { cityname: city });
  47. } else {
  48. console.log('还没有');
  49. this.getLocate();
  50. }
  51. },
  52. //点击城市字母
  53. letterTap(e) {
  54. const Item = e.currentTarget.dataset.item;
  55. this.setData({
  56. cityListId: Item
  57. });
  58. console.log("..............."+this.data.cityListId);
  59. },
  60. //调用定位
  61. getLocate() {
  62. let that = this;
  63. new qqmap().getLocateInfo().then(function (val) {//这个方法在另一个文件里,下面有贴出代码
  64. console.log(val);
  65. if (val.indexOf('市') !== -1) {//这里是去掉“市”这个字
  66. console.log(val.indexOf('市') - 1);
  67. val = val.slice(0, val.indexOf('市'));
  68. console.log(val);
  69. }
  70. that.setData({
  71. locateCity: val
  72. });
  73. //把获取的定位和获取的时间放到本地存储
  74. wx.setStorageSync('locatecity', { city: val, time: new Date().getTime() });
  75. });
  76. },
  77. onShow() {
  78. console.log(getApp());
  79. let that = this,
  80. cityOrTime = wx.getStorageSync('locatecity') || {},
  81. time = new Date().getTime(),
  82. city = '';
  83. if (!cityOrTime.time || (time - cityOrTime.time > 1800000)) {//每隔30分钟请求一次定位
  84. this.getLocate();
  85. } else {//如果未满30分钟,那么直接从本地缓存里取值
  86. that.setData({
  87. locateCity: cityOrTime.city
  88. })
  89. }
  90. }
  91. })

然后运行就可以了

完结

 想了解更多的小程序的知识请添加微信小程序开发交流群:368506119

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/529490
推荐阅读
相关标签
  

闽ICP备14008679号