类似功能的小程序也有挺多,其实都是大同小异,有部分样式是参考其他小程序,该小程序还在开发中,还有很多没有完善…
首先要在index,json中引入组件,代码如下
{
"usingComponents": {
"address": "../../components/address/address"
}
}
然后在index.wxml中使用组件
<view class='wrapper'>
<address my-city="北京" data="{{city}}" binddetail="bindtap"></address>
</view>
<!--参数说明:
data [Object] : 列表所需要的数据(所有城市的json格式)
my-city [String]: 我的城市,
-->
city中的数据如图所示,如需这些数据可以私信我。
let city = require(’…/…/data/allcity.js’);
该组件的wxml,wxss部分,这里就不多讲话了,下面直接给代码吧,这里讲一下js跟config部分。
js这里就两个核心点,1、处理index页面携带进来的数据(即组件初始化数据),2、将选中的城市抛出去,记录历史选中城市。
一、config.wxs
module.exports = {
horizontal: true, // 第二个选项是否横排显示(一般第一个数据选项为 热门城市,常用城市之类 ,开启看需求)
animation:true ,// 过渡动画是否开启
search:true ,// 是否开启搜索
history:true ,// 是否开启历史访问城市
searchBtn:false ,// 是否存在搜索按钮
};
二、address.js
初始数据处理:这里只需将所有城市的json赋值给list便可。
let rightArr = []
for (let i in data) {
rightArr.push(data[i].title.substr(0, 1));
}
this.setData({
list: data,
rightArr
})
历史访问数据处理
let detail = e.currentTarget.dataset.detail;
this.triggerEvent('detail', detail, myEventOption);
if(wx.getStorageSync('historyAddress')){
var arr = wx.getStorageSync('historyAddress');
for(var i=0;i<arr.length;i++){
if(arr[i].name==detail.name){//这里主要将以前访问过的,又重新选中的放到最前面
var arr1 = arr[i];
var arr2 = arr[0];
var arr3 = [];
arr3 = arr1;
arr[i] = arr[0];
arr[0] = arr3;
wx.setStorageSync('historyAddress',arr)
break;
}
if(i==arr.length-1){ //如果选中的这个城市以前没访问过,这记录下来
arr = prepend(arr,detail);
wx.setStorageSync('historyAddress',arr);
function prepend(arr, item) {
//将arr数组复制给a
var a = arr.slice(0);
//使用unshift方法向a开头添加item
a.unshift(item);
return a;
}
break;
}
}
}else{
var newArr = [];
newArr.push(detail);
wx.setStorageSync('historyAddress',newArr)
}
搜索:
_search(){
console.log("搜索")
let data = this.data.data;
let newData = [];
for (let i = 0; i < data.length; i++) {
let itemArr = [];
for (let j = 0; j < data[i].item.length; j++) {
if (data[i].item[j].name.indexOf(this.value) > -1) {
let itemJson = {};
for (let k in data[i].item[j]) {
itemJson[k] = data[i].item[j][k];
}
itemArr.push(itemJson);
}
}
if (itemArr.length === 0) {
continue;
}
newData.push({
title: data[i].title,
type: data[i].type ? data[i].type : "",
item: itemArr
})
}
this.resetRight(newData);
},
完整js代码
Component({
/**
* 组件的属性列表
*/
properties: {
data: {
type: Object,
value: {},
observer: function (newVal, oldVal) {
this.resetRight(newVal);
if(wx.getStorageSync('historyAddress')){
this.setData({
historyAddress:wx.getStorageSync('historyAddress')
})
}
}
},
myCity: {
type: String,
value: "",
},
// 用于外部组件搜索使用
search:{
type:String,
value:"",
observer: function (newVal, oldVal) {
console.log(newVal)
this.value = newVal;
this.searchMt();
}
}
},
data: {
inputValue: '',
list: [],
rightArr: [],// 右侧字母展示
jumpNum: '',//跳转到那个字母
myCityName: '请选择', // 默认我的城市
screenHeight:wx.getSystemInfoSync().screenHeight,
historyAddress:null,
},
ready() {
let data = this.data.data;
this.resetRight(data);
if (this.data.myCity) {
this.getCity()
}
},
methods: {
// 数据重新渲染
resetRight(data) {
let rightArr = []
for (let i in data) {
rightArr.push(data[i].title.substr(0, 1));
}
this.setData({
list: data,
rightArr
})
},
getCity() {
var _this = this;
wx.getLocation({
type: 'wgs84',
success: function (res) {
_this.latitude = res.latitude;
_this.longitude = res.longitude;
console.log(res)
}
})
},
// 右侧字母点击事件
jumpMt(e) {
let jumpNum = e.currentTarget.dataset.id;
this.setData({jumpNum:jumpNum});
console.log(this.data.jumpNum,'jumpNum')
},
// 列表点击事件
detailMt(e) {
let detail = e.currentTarget.dataset.detail;
if(e.currentTarget.dataset.mycity){
var mycity = {
name:detail,
key:'我的城市'
}
detail = mycity
}
let myEventOption = {
bubbles: false,//事件是否冒泡
composed: false,//事件是否可以穿越组件边界
capturePhase: false //事件是否拥有捕获阶段
} // 触发事件的选项
this.triggerEvent('detail', detail, myEventOption);
console.log(detail,'detail');
if(wx.getStorageSync('historyAddress')){
var arr = wx.getStorageSync('historyAddress');
for(var i=0;i<arr.length;i++){
if(arr[i].name==detail.name){
var arr1 = arr[i];
var arr2 = arr[0];
var arr3 = [];
arr3 = arr1;
arr[i] = arr[0];
arr[0] = arr3;
wx.setStorageSync('historyAddress',arr)
break;
}
if(i==arr.length-1){
// var aa= [
// {name:detail.name,key:detail.key}
// ];
// aa.push(detail)
// arr[arr.length] = detail;
arr = prepend(arr,detail);
wx.setStorageSync('historyAddress',arr);
function prepend(arr, item) {
//将arr数组复制给a
var a = arr.slice(0);
//使用unshift方法向a开头添加item
a.unshift(item);
return a;
}
break;
}
}
}else{
var newArr = [];
newArr.push(detail);
wx.setStorageSync('historyAddress',newArr)
}
// wx.setStorageSync('historyAddress',_this.data.myConcern);
},
// 获取搜索输入内容
input(e) {
this.value = e.detail.value;
this._search();
this.setData({
inputValue:e.detail.value
})
},
clear() {
this.value = '';
this.setData({
inputValue:''
})
this._search();
},
// 基础搜索功能
searchMt() {
this._search();
},
_search(){
console.log("搜索")
let data = this.data.data;
let newData = [];
for (let i = 0; i < data.length; i++) {
let itemArr = [];
for (let j = 0; j < data[i].item.length; j++) {
if (data[i].item[j].name.indexOf(this.value) > -1) {
let itemJson = {};
for (let k in data[i].item[j]) {
itemJson[k] = data[i].item[j][k];
}
itemArr.push(itemJson);
}
}
if (itemArr.length === 0) {
continue;
}
newData.push({
title: data[i].title,
type: data[i].type ? data[i].type : "",
item: itemArr
})
}
this.resetRight(newData);
},
// 城市定位
locationMt() {
// 定位自己的城市,需要引入第三方api
}
}
})
`wxml,这部分包括,城市搜索,我的城市,历史访问城市,热门城市推荐,城市字母选择,城市列表。其中搜索,历史访问城市,热门城市以及过度动画是否开启,这些都做在config.wxs中。
<wxs src="config.wxs" module="config" />
<view class='list-warpper'>
<view wx:if="{{config.search}}" class='list-search'>
<view class='list-search-box'>
<icon type="search" size="15" color="#d1dbf6" />
<input placeholder-style="color:white;font-size:30rpx;" placeholder="输入您要搜索的城市" bindinput='input' value="{{inputValue}}"/>
<icon bindtap="clear" type="clear" size="15" color="#d1dbf6" />
</view>
<button wx:if="{{config.searchBtn}}" class='search-button' catchtap='searchMt'>搜索</button>
</view>
<block wx:if="{{list.length != 0 }}">
<scroll-view style="height: {{screenHeight*0.95}}px;" class="list-scroll {{config.search?'top':''}}" scroll-y="true" scroll-into-view="{{jumpNum}}" scroll-with-animation="{{config.animation}}">
<view class="line-h30" style=""></view>
<!-- 我的位置 -->
<view wx:if="{{myCity}}">
<view class='list-horizontal myaddress'>
<view class="wh40" style="">
<image class="wh100" mode="aspectFit" src="/image/address.png"></image>
</view>
<view class='myaddressText' data-detail="{{myCity}}" data-mycity='1' catchtap='detailMt'>
{{myCity}}
</view>
<view class="mt14">GPS定位</view>
</view>
</view>
<!-- 历史访问城市 -->
<view wx:if="{{historyAddress&&config.history}}">
<view class='list-title'>历史访问城市</view>
<view class='list-horizontal'>
<view class='list-name border' wx:for="{{historyAddress}}" wx:for-item="history" wx:for-index="idx" wx:key="history" data-detail="{{history}}" catchtap='detailMt'>
{{history.name}}
</view>
</view>
</view>
<!-- 热门搜索&所有城市 -->
<view id="{{'index'+index}}" wx:for="{{list}}" wx:key="key">
<view class='list-title'>{{item.title}}</view>
<view class='{{index===0&&config.horizontal&&item.type==="hot"?"list-horizontal":""}}'>
<view class='list-name {{idx === 0 ?"":"border"}}' wx:for="{{item.item}}" wx:for-item="city" wx:for-index="idx" wx:key="city" data-detail="{{city}}" catchtap='detailMt'>
{{city.name}}
</view>
</view>
<view wx:if="{{index===0}}" class="line-h30"></view>
</view>
</scroll-view>
<view class='list-right-wrapper'>
<view class='right-item' wx:for="{{rightArr}}" wx:key="rightArr" data-id="{{'index'+index}}" catchtap='jumpMt'>
{{rightArr[index]}}
</view>
</view>
</block>
<block wx:else>
<view class='nodata'>暂无更多数据</view>
</block>
</view>
wxss部分
page{
height:100%;
width:100%;
}
.wh100{
width:100%;
height:100%;
}
.list-warpper {
position: relative;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.list-scroll {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.list-scroll.top{
padding-top: 90rpx;
}
/* 样式控制 */
.list-title {
background: #fff;
color: #999;
font-size: 28rpx;
padding: 10rpx;
padding-left: 30rpx;
padding-top: 15rpx;
}
.list-name {
position: relative;
font-size: 28rpx;
padding: 30rpx;
padding-left: 30rpx;
color: #444;
}
.list-name.border::after {
content: "";
position: absolute;
left: 30rpx;
right: 0;
top: 0;
height: 1px;
background: #f5f5f5;
}
.list-right-wrapper {
position: fixed;
top: 12%;
right: 2rpx;
padding: 10rpx;
border-radius: 20rpx;
z-index: 2;
height: 80%;
overflow: auto;
/* background: #ddd; */
}
.right-item {
display: flex;
justify-content: center;
align-items: center;
padding: 2rpx 10rpx;
font-size: 25rpx;
color: #666;
}
.list-search {
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
width: 100%;
/* height: 90rpx; */
padding: 10rpx 30rpx;
box-sizing: border-box;
z-index: 20;
background: #3e67d9;
padding-bottom: 20rpx;
}
.search-title {
flex-shrink: 0;
font-size: 28rpx;
padding-right: 10rpx;
}
.list-search-box {
display: flex;
align-items: center;
padding: 0 30rpx;
width: 100%;
height: 70rpx;
background: #6585e1;
border-radius: 90rpx;
font-size: 28rpx;
box-sizing: border-box;
}
.list-search-box input {
width: 100%;
padding-left: 10rpx;
color: white;
}
.search-button {
/* width: 100rpx; */
flex-shrink: 0;
height: 60rpx;
line-height: 60rpx;
font-size: 28rpx;
margin-left: 10rpx;
color:white;
}
/* 热门城市横排显示样式 */
.list-horizontal {
display: flex;
flex-wrap: wrap;
padding: 10rpx 30rpx;
padding-right: 50rpx;
align-items:center;
}
.list-horizontal .list-name{
border:1rpx #ddd solid;
border-radius:5rpx;
margin-right:3%;
width:29%;
text-align:center;
padding:15rpx 0;
margin-bottom:25rpx;
font-size:30rpx;
color:#333;
position: static;
}
/* 无数据 */
.nodata {
padding-top: 200rpx;
text-align: center;
font-size: 32rpx;
color: #ddd;
}
.wh40{
width: 40rpx;
height: 40rpx;
}
.myaddress{
padding: 20rpx 0;
margin: 0 30rpx;
border-bottom: 1rpx solid #eee;
font-size: 30rpx;
color: #999;
}
.line-h30{
width: 100%;
height: 30rpx;
background: #f7f7f7;
}
.myaddressText{
font-size: 40rpx;
color: #000;
margin: 0 15rpx;
}
.mt14{
margin-top:14rpx;
}