489 lines
14 KiB
Vue
489 lines
14 KiB
Vue
<template>
|
|
<view class="nyn-city-list-container">
|
|
<!-- 搜索框 -->
|
|
<!-- <view class="search">
|
|
<input
|
|
type="text"
|
|
placeholder="请输入城市名称"
|
|
placeholder-style="font-size:20rpx"
|
|
@input="bindinputCitys"
|
|
/>
|
|
</view> -->
|
|
<uni-nav-bar
|
|
title=""
|
|
:fixed="true"
|
|
:border="false"
|
|
:left-width="'60rpx'"
|
|
:right-width="'160rpx'"
|
|
:statusBar="true"
|
|
:height="'34px'"
|
|
>
|
|
<block slot="left">
|
|
<view class="left-block" @click="handerSkip">
|
|
<image
|
|
style="
|
|
width: 11px;
|
|
height: 18px;
|
|
vertical-align: middle;
|
|
margin-left: 6px;
|
|
"
|
|
lazy-load
|
|
src="data:image/png;base64,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"
|
|
/>
|
|
</view>
|
|
</block>
|
|
<view class="input-view">
|
|
<uni-icons
|
|
type="search"
|
|
size="22"
|
|
color="#666666"
|
|
style="line-height: 60rpx"
|
|
/>
|
|
<input
|
|
confirm-type="search"
|
|
class="input"
|
|
type="text"
|
|
placeholder="输入城市名进行搜索"
|
|
@input="bindinputCitys"
|
|
/>
|
|
</view>
|
|
</uni-nav-bar>
|
|
<!-- 热门城市 -->
|
|
<view class="ynq-AutoAddress">
|
|
<text class="iconfontAili icon-dingwei1"></text>
|
|
<text style="margin: 0 12rpx">当前定位城市</text>
|
|
<text>{{ loactionCity }}</text>
|
|
</view>
|
|
<text>热门城市</text>
|
|
<view class="hot">
|
|
<view
|
|
class="hot-item"
|
|
v-for="item in hotList"
|
|
:key="item.id"
|
|
@tap="bindCity(item)"
|
|
:data-city="item.name"
|
|
>{{ item.name }}</view
|
|
>
|
|
</view>
|
|
<!-- 首字母检索 -->
|
|
<view class="searchLetter touchClass">
|
|
<!-- 右边字母数据数据 触摸事件-->
|
|
<view
|
|
v-for="item in searchLetter"
|
|
:key="item.name"
|
|
:data-letter="item.name"
|
|
:style="{ height: `${itemH}px` }"
|
|
@touchstart.stop="searchStart"
|
|
@touchmove.stop="searchMove"
|
|
@touchend.stop="searchEnd"
|
|
>{{ item.name }}</view
|
|
>
|
|
</view>
|
|
<!-- 左边字母跟右边字母true时 屏幕中心显示选中的首字母-->
|
|
<!-- 居中首字母样式 -->
|
|
<view class="cont_Letter" v-if="isShowLetter">
|
|
{{ showLetter }}
|
|
</view>
|
|
<scroll-view
|
|
scroll-y="true"
|
|
:style="{ height: `${winHeight}px` }"
|
|
:scroll-top="scrollTop"
|
|
enhanced
|
|
:show-scrollbar="false"
|
|
v-if="!search"
|
|
>
|
|
<!-- 循环城市数据 -->
|
|
<view v-for="(value, key) in cityList" :key="key">
|
|
<!-- 循环首字母检索信息 -->
|
|
<view class="list_letter">{{ key }}</view>
|
|
<!-- 城市ID城市名称 -->
|
|
<view
|
|
class="item_city"
|
|
v-for="item in value"
|
|
:key="item.id"
|
|
:data-city="item.name"
|
|
@tap="bindCity(item)"
|
|
>{{ item.name }}</view
|
|
>
|
|
</view>
|
|
</scroll-view>
|
|
<!-- 搜索列表 -->
|
|
<view class="list" v-if="search">
|
|
<view
|
|
class="text"
|
|
v-for="item in searchList"
|
|
:key="item.id"
|
|
@tap="bindCity(item)"
|
|
:data-city="item.name"
|
|
>{{ item.name }}</view
|
|
>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import address from "./citys.js";
|
|
export default {
|
|
name: "NynCityList",
|
|
props: {
|
|
hot: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
isShowLetter: false, //拖动时,是否显示中间字母
|
|
showLetter: "A", //中间字母
|
|
searchLetter: [], //字母检索列表
|
|
itemH: 0, //字母列表的高度
|
|
startPageY: 0, //开始拖动字母时Y坐标
|
|
bHeight: 0,
|
|
tHeight: 0,
|
|
CityName: "",
|
|
scrollTop: 0, //城市列表容器滚动条的位置
|
|
winHeight: 0, //城市列表窗口高度
|
|
cityList: [], //城市列表
|
|
hotList: [], //热门列表
|
|
search: false, //是否搜索
|
|
searchList: [],
|
|
time: 0,
|
|
loactionCity: "无法定位",
|
|
isAdd: false,
|
|
};
|
|
},
|
|
onShow() {
|
|
let currentAddress = uni.getStorageSync("currentAddress");
|
|
let loactionCity = uni.getStorageSync("loactionCity");
|
|
if (currentAddress) {
|
|
if (currentAddress.area) {
|
|
this.loactionCity = currentAddress.area;
|
|
}
|
|
|
|
if (!currentAddress.area && currentAddress.city) {
|
|
this.loactionCity = currentAddress.city;
|
|
}
|
|
|
|
if (!currentAddress.area && !currentAddress.city && currentAddress.addr) {
|
|
let regex = /(\S+市)/g;
|
|
let matches = currentAddress.addr.match(regex);
|
|
if (matches && matches.length > 0) {
|
|
let firstMatch = matches[0]; // 第一个匹配的“xx市”
|
|
this.loactionCity = firstMatch;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.loactionCity = loactionCity;
|
|
},
|
|
onLoad(options) {
|
|
if (options.isAdd) {
|
|
this.isAdd = options.isAdd;
|
|
}
|
|
this.initList();
|
|
},
|
|
methods: {
|
|
handerSkip() {
|
|
uni.navigateBack();
|
|
},
|
|
/* 列表初始化 */
|
|
initList() {
|
|
let searchLetter = [];
|
|
for (let key in address.cities) {
|
|
searchLetter.push(key);
|
|
}
|
|
let hotList = address.hotCities;
|
|
let cityList = address.cities;
|
|
let sysInfo = uni.getSystemInfoSync();
|
|
let winHeight = sysInfo.windowHeight;
|
|
//添加要匹配的字母范围值
|
|
//更加屏幕高度设置子元素的高度
|
|
let itemH = winHeight / searchLetter.length;
|
|
let tempObj = [];
|
|
for (let i = 0; i < searchLetter.length; i++) {
|
|
let temp = {};
|
|
temp.name = searchLetter[i];
|
|
temp.tHeight = i * itemH;
|
|
temp.bHeight = (i + 1) * itemH;
|
|
tempObj.push(temp);
|
|
}
|
|
this.winHeight = winHeight;
|
|
this.itemH = itemH - "20";
|
|
this.searchLetter = tempObj;
|
|
this.cityList = cityList;
|
|
this.hotList = hotList;
|
|
},
|
|
/* 搜索城市时触发 */
|
|
bindinputCitys(e) {
|
|
if (this.time !== null) {
|
|
clearTimeout(this.time);
|
|
}
|
|
|
|
this.time = setTimeout(() => {
|
|
if (e.detail.value != "") {
|
|
this.search = true;
|
|
} else {
|
|
this.search = false;
|
|
}
|
|
let cities = this.cityList;
|
|
let cyits = [];
|
|
for (let key in cities) {
|
|
for (let i = 0; i < cities[key].length; i++) {
|
|
if (
|
|
cities[key][i].name.search(e.detail.value) != -1 ||
|
|
cities[key][i].spell.search(e.detail.value) != -1
|
|
) {
|
|
cyits.push(cities[key][i]);
|
|
}
|
|
}
|
|
}
|
|
this.searchList = cyits;
|
|
}, 300);
|
|
},
|
|
/* 检索字母拖动开始 */
|
|
searchStart(e) {
|
|
let showLetter = e.currentTarget.dataset.letter;
|
|
let pageY = e.touches[0].pageY;
|
|
this.setScrollTop(showLetter);
|
|
this.nowLetter(pageY);
|
|
this.showLetter = showLetter;
|
|
this.startPageY = pageY;
|
|
this.isShowLetter = true;
|
|
// let pageY = e.touches[0].pageY;
|
|
// this.nowLetter(pageY);
|
|
// this.startPageY = pageY;
|
|
// this.isShowLetter = true
|
|
},
|
|
/* 检索字母拖动中 */
|
|
searchMove(e) {
|
|
let pageY = e.touches[0].pageY;
|
|
let startPageY = this.startPageY;
|
|
let tHeight = this.tHeight;
|
|
let bHeight = this.bHeight;
|
|
// let showLetter = 0;
|
|
if (startPageY - pageY > 0) {
|
|
//向上移动
|
|
if (pageY < tHeight) {
|
|
this.nowLetter(pageY);
|
|
}
|
|
} else {
|
|
//向下移动
|
|
if (pageY > bHeight) {
|
|
this.nowLetter(pageY);
|
|
}
|
|
}
|
|
},
|
|
/* 检索字母拖动结束 */
|
|
searchEnd() {
|
|
setTimeout(() => {
|
|
this.isShowLetter = false;
|
|
}, 1000);
|
|
},
|
|
/* 点击城市 */
|
|
bindCity(item) {
|
|
// 向外传递这个城市
|
|
// this.$emit("bindCity", item);
|
|
uni.setStorageSync("city", item.name);
|
|
uni.navigateBack();
|
|
},
|
|
/* 设置scroll-view滚动距离 */
|
|
setScrollTop(showLetter) {
|
|
let scrollTop = 0;
|
|
let cityList = this.cityList;
|
|
let cityCount = 0;
|
|
let initialCount = 0;
|
|
for (let key in cityList) {
|
|
if (showLetter == key) {
|
|
scrollTop = initialCount * 30 + cityCount * 41;
|
|
break;
|
|
} else {
|
|
initialCount++;
|
|
cityCount += cityList[key].length;
|
|
}
|
|
}
|
|
this.scrollTop = scrollTop;
|
|
},
|
|
/* */
|
|
nowLetter(pageY) {
|
|
let letterData = this.searchLetter;
|
|
let bHeight = 0;
|
|
let tHeight = 0;
|
|
let showLetter = "";
|
|
for (let i = 0; i < letterData.length; i++) {
|
|
if (letterData[i].tHeight <= pageY && pageY <= letterData[i].bHeight) {
|
|
bHeight = letterData[i].bHeight;
|
|
tHeight = letterData[i].tHeight;
|
|
showLetter = letterData[i].name;
|
|
break;
|
|
}
|
|
}
|
|
// this.setScrollTop(showLetter);
|
|
this.bHeight = bHeight;
|
|
this.tHeight = tHeight;
|
|
this.showLetter = showLetter;
|
|
this.startPageY = pageY;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.nyn-city-list-container {
|
|
padding: 0 48rpx;
|
|
background: #fff;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
|
|
.ynq-AutoAddress {
|
|
margin: 48rpx 0;
|
|
}
|
|
|
|
/* 隐藏滚动条 */
|
|
.scroll-view {
|
|
scrollbar-width: none; /* Firefox */
|
|
}
|
|
|
|
.scroll-view::-webkit-scrollbar {
|
|
display: none; /* Chrome, Safari */
|
|
}
|
|
|
|
.input-view {
|
|
width: 92%;
|
|
display: flex;
|
|
background-color: #f5f5f5;
|
|
height: 60rpx;
|
|
border-radius: 30rpx;
|
|
padding: 0 4%;
|
|
flex-wrap: nowrap;
|
|
margin: 10rpx 0;
|
|
line-height: 60rpx;
|
|
margin-left: 10rpx;
|
|
color: #b9b9b9;
|
|
}
|
|
|
|
.input-view .uni-icon {
|
|
line-height: 60rpx !important;
|
|
font-size: 24rpx;
|
|
}
|
|
|
|
.input-view .uni-icons {
|
|
font-size: 32rpx !important;
|
|
}
|
|
|
|
.input-view .input {
|
|
height: 60rpx;
|
|
line-height: 60rpx;
|
|
width: 94%;
|
|
padding: 0 2%;
|
|
font-size: 24rpx;
|
|
}
|
|
}
|
|
.search {
|
|
background-color: #ffffff;
|
|
border: 1px solid #cccccc;
|
|
width: 686rpx;
|
|
border-radius: 100rpx;
|
|
margin: 20rpx auto;
|
|
padding: 4rpx;
|
|
input {
|
|
line-height: 60rpx;
|
|
text-align: left;
|
|
padding-left: 20rpx;
|
|
}
|
|
}
|
|
/* 首字母样式 */
|
|
.searchLetter {
|
|
position: fixed;
|
|
right: 0;
|
|
top: 20%;
|
|
width: 30px;
|
|
height: 80%;
|
|
text-align: center;
|
|
justify-content: center;
|
|
display: flex;
|
|
flex-direction: column;
|
|
color: #666;
|
|
background-color: #fff;
|
|
z-index: 1;
|
|
view {
|
|
height: 50rpx;
|
|
}
|
|
}
|
|
/* 右边首字母样式 */
|
|
.touchClass {
|
|
color: #666;
|
|
font-size: 28rpx;
|
|
}
|
|
/* 居中显示的选中首字母 */
|
|
.cont_Letter {
|
|
background-color: #666;
|
|
color: #fff;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
margin: -50px;
|
|
width: 100px;
|
|
height: 100px;
|
|
border-radius: 10px;
|
|
font-size: 26px;
|
|
z-index: 1;
|
|
}
|
|
/* 循环数据首字母检索 */
|
|
.list_letter {
|
|
display: flex;
|
|
background-color: #fff;
|
|
height: 30px;
|
|
color: #2a2a2a;
|
|
font-size: 26rpx;
|
|
align-items: center;
|
|
position: sticky;
|
|
top: 0;
|
|
}
|
|
/* 城市样式 */
|
|
.item_city {
|
|
display: flex;
|
|
background-color: #fff;
|
|
height: 40px;
|
|
line-height: 40px;
|
|
color: #2a2a2a;
|
|
font-size: 28rpx;
|
|
align-items: center;
|
|
border-bottom: 1px solid #f8f8f8;
|
|
}
|
|
.hot {
|
|
background: #ffffff;
|
|
display: flex;
|
|
flex-flow: wrap;
|
|
margin: 10px 0px;
|
|
justify-content: space-between;
|
|
|
|
.hot-item {
|
|
font-size: 28rpx;
|
|
padding: 4px 11px;
|
|
border-radius: 6px;
|
|
margin-bottom: 8px;
|
|
background: #f5f5f6;
|
|
width: 17%;
|
|
text-align: center;
|
|
}
|
|
}
|
|
.list {
|
|
.eng {
|
|
background: #ffffff;
|
|
padding: 30rpx;
|
|
color: #212121;
|
|
}
|
|
.text {
|
|
color: #212121;
|
|
font-size: 28rpx;
|
|
height: 40px;
|
|
line-height: 40px;
|
|
border-bottom: 1px solid #e6e6e6;
|
|
}
|
|
}
|
|
</style>
|