259 lines
6.5 KiB
Vue
259 lines
6.5 KiB
Vue
<template>
|
|
<view class="city-select-page">
|
|
<view class="white_container padding_bottom40">
|
|
<!-- 搜索框 -->
|
|
<u-search placeholder="输入城市进行搜索" :value="searchValue" @search="handleSearch" @change="handleSearch"
|
|
:showAction=false height="70" searchIconSize="40" shape="round"></u-search>
|
|
<view v-if="searchValue" class="search_popup">
|
|
<view
|
|
v-for="(item, index) in searchRes"
|
|
:key="index"
|
|
:class="['list-item', index === searchRes.length -1 && 'no_border' ]"
|
|
@click="headerSelectMapClick(item)"
|
|
>
|
|
{{item.name}}
|
|
</view>
|
|
</view>
|
|
<view v-if="!searchValue">
|
|
<!-- 当前定位城市 -->
|
|
<view class="current-city">
|
|
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Index_add.png" mode="widthFix" />
|
|
<text>当前定位城市 {{ location.cityName }}</text>
|
|
</view>
|
|
|
|
<!-- 国内热门城市 -->
|
|
<view class="hot-cities">
|
|
<text class="title">国内热门城市</text>
|
|
<view class="city-list">
|
|
<view v-for="(item, index) in hotCities" class="city_name" :key="index" @click="headerSelectMapClick(item)">{{item}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view v-if="!searchValue" class="container">
|
|
<!-- 左侧列表 -->
|
|
<scroll-view class="list-scroll" scroll-y :scroll-into-view="activeId" @scroll="handleScroll">
|
|
<view v-for="(group, index) in groupedData" :key="index" class="white_container" :id="'group-' + group.letter">
|
|
<!-- 字母标题 -->
|
|
<view class="letter-title">{{ group.letter }}</view>
|
|
<!-- 列表项 -->
|
|
<view v-for="(item, ind) in group.list" :key="item.id" :class="['list-item', ind === group.list.length -1 && 'no_border' ]" @click="headerSelectMapClick(item)">
|
|
{{ item.name }}
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 右侧索引栏 -->
|
|
<view class="index-bar">
|
|
<view v-for="(letter, index) in letters" :key="index" class="index-item" @tap="scrollToLetter(letter)">
|
|
{{ letter }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
</view>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
import {
|
|
apiArr
|
|
} from '../../api/community.js';
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
location: {},
|
|
searchValue: '',
|
|
currentCity: '衡水',
|
|
hotCities: ['上海', '北京', '广州', '杭州', '成都', '深圳', '苏州', '南京', '重庆', '西安', '长沙', '天津', '三亚', '厦门', '武汉', '无锡'],
|
|
rawData: [{
|
|
id: 1,
|
|
name: '阿巴嘎旗',
|
|
letters: 'A',
|
|
lat: '39.908823',
|
|
long: '116.39747',
|
|
},
|
|
{
|
|
id: 2,
|
|
name: '阿坝',
|
|
letters: 'A',
|
|
lat: '31.196322',
|
|
long: '121.339841'
|
|
},
|
|
{
|
|
id: 3,
|
|
name: '阿坝县',
|
|
letters: 'A',
|
|
},
|
|
{
|
|
id: 4,
|
|
name: '阿城区',
|
|
letters: 'A',
|
|
},
|
|
{
|
|
id: 5,
|
|
name: '阿尔山市',
|
|
letters: 'B',
|
|
},
|
|
{
|
|
id: 6,
|
|
name: '阿合奇县',
|
|
letters: 'B',
|
|
},
|
|
{
|
|
id: 7,
|
|
name: '阿克塞哈萨克族自治县',
|
|
letters: 'B',
|
|
},
|
|
{
|
|
id: 8,
|
|
name: '阿克苏地区',
|
|
letters: 'C',
|
|
},
|
|
{
|
|
id: 9,
|
|
name: '阿克苏市',
|
|
letters: 'D',
|
|
},
|
|
{
|
|
id: 10,
|
|
name: '阿拉尔',
|
|
letters: 'E',
|
|
},
|
|
],
|
|
letters: ['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'
|
|
],
|
|
groupedData: [], // 分组后的数据
|
|
activeId: '', // 当前高亮的字母区域 ID
|
|
activeLetter: '' ,// 当前高亮的字母
|
|
searchRes: [
|
|
{
|
|
name: '河北,石家庄'
|
|
},
|
|
{
|
|
name: '河北,廊坊'
|
|
},
|
|
{
|
|
name: '河北,保定'
|
|
},
|
|
{
|
|
name: '河北,衡水'
|
|
},
|
|
{
|
|
name: '河北,沧州'
|
|
},
|
|
{
|
|
name: '河北,唐山'
|
|
},
|
|
]
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
this.location = uni.getStorageSync('location');
|
|
this.groupData();
|
|
},
|
|
methods: {
|
|
|
|
headerSelectMapClick(item) {
|
|
console.log('地图选点', item);
|
|
const lat = Number(item.lat);
|
|
const long = Number(item.long);
|
|
uni.chooseLocation({
|
|
latitude: lat,
|
|
longitude: long,
|
|
success: (res) => {
|
|
console.log('打开地图选择商铺名称', res);
|
|
if (!res.name) {
|
|
uni.showToast({
|
|
title: '请选择具体城市信息',
|
|
icon: 'none'
|
|
});
|
|
return;
|
|
}
|
|
// 更新页面数据,如标记点等
|
|
const selectLocation = {
|
|
cityName: res.address.match(/(.*?(?:省|自治区)|^)(.*?)(?:市|地区|盟|州|县|区)?$/)[2].match(/(.*市)/)[1],
|
|
district: res.address.match(/市(.*)/)[1],
|
|
lat: res.latitude,
|
|
long: res.longitude
|
|
};
|
|
uni.setStorageSync('location', selectLocation); // 缓存数据信息
|
|
uni.setStorageSync('city', selectLocation.cityName); // 缓存数据信息
|
|
console.log('location', selectLocation);
|
|
uni.navigateBack({
|
|
delta: 1
|
|
});
|
|
},
|
|
fail: (err) => {
|
|
console.log('选择位置失败', err);
|
|
}
|
|
});
|
|
},
|
|
|
|
handleSearch(e) {
|
|
// 搜索逻辑,可以在这里根据 searchValue 过滤城市数据
|
|
this.searchValue = e;
|
|
console.log('搜ee索:', e);
|
|
},
|
|
|
|
groupData() {
|
|
const map = {};
|
|
this.letters.forEach(letter => {
|
|
map[letter] = {
|
|
letter,
|
|
list: []
|
|
};
|
|
});
|
|
|
|
this.rawData.forEach(item => {
|
|
if (map[item.letters]) {
|
|
map[item.letters].list.push(item);
|
|
}
|
|
});
|
|
console.log('112312313', Object.values(map).filter(group => group.list.length > 0))
|
|
// 过滤掉没有数据的字母
|
|
this.groupedData = Object.values(map).filter(group => group.list.length > 0);
|
|
},
|
|
|
|
// 点击字母滚动到对应区域
|
|
scrollToLetter(letter) {
|
|
this.$nextTick(() => {
|
|
this.activeId = 'group-' + letter;
|
|
this.activeLetter = letter;
|
|
});
|
|
},
|
|
// 滚动时监听当前位置
|
|
handleScroll(e) {
|
|
const query = uni.createSelectorQuery().in(this);
|
|
let activeLetter = '';
|
|
|
|
// 遍历每个字母区域,检查是否在可视范围内
|
|
this.letters.some(letter => {
|
|
query.select(`#group-${letter}`).boundingClientRect(rect => {
|
|
if (rect && rect.top <= 100 && rect.bottom >= 0) {
|
|
activeLetter = letter;
|
|
}
|
|
}).exec();
|
|
return activeLetter; // 找到第一个符合条件的字母后退出循环
|
|
});
|
|
if (activeLetter && activeLetter !== this.activeLetter) {
|
|
this.activeLetter = activeLetter;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
@import url("./index.css");
|
|
</style> |