<template>
|
<div class="position-page">
|
<!--不使用定位,由于解决ios的侧滑问题,定位使得页面切换出现错乱-->
|
<x-header
|
:left-options="{showBack: true, backText: ''}"
|
id="searchCityHeader">
|
<div slot="overwrite-title">
|
<x-input v-model.trim="inputInfor"
|
@keyup.native="userInput" @on-change="userInput"
|
title="输入城市名称" placeholder="输入城市名称">
|
<i slot="label" class="iconfont icon-search"></i>
|
</x-input>
|
</div>
|
</x-header>
|
<!--滚动区域-->
|
<div class="position-content" :style="{height: contentHeight}" ref="posContent">
|
<!--用户搜索结果集-->
|
<ul id="search_ul"
|
v-show="isSearch"
|
ref="searchUl"
|
class="page" :style="{height: contentHeight}">
|
<li class="city-name vux-1px-b"
|
v-for="item in searchResults"
|
v-text="item.name"
|
@click="setCityCode(item)"></li>
|
</ul>
|
<!--初始化数据展示结果集-->
|
<div v-show="!isSearch">
|
<div class="userCityInfo">
|
<!--当前定位城市-->
|
<h4>当前定位城市</h4>
|
<span id="letter_当"></span>
|
<div class="current-city-box">
|
<i class="iconfont icon-location"></i>
|
<span class="current-city" @click="handleCurrentCity" v-text="cityName"></span>
|
<span class="position-box" @click="handleAgainPosition">
|
<i class="iconfont icon-position"></i>重新定位
|
</span>
|
</div>
|
<!--热门城市-->
|
<h4 id="letter_热">热门城市</h4>
|
<div class="hot-city-list">
|
<span v-for="item in hotCity" v-text="item.name" @click="setCityCode(item)"></span>
|
</div>
|
</div>
|
<!--城市列表-->
|
<ul id="cityWrap">
|
<li class="city_letter" v-for="(value, key) in cityList" :key="key">
|
<h4 class="city_letter_name" v-bind:id="'letter_' + key" v-text="key"></h4>
|
<ul>
|
<li class="city-name vux-1px-b"
|
v-for="item in value"
|
:key="item.code"
|
v-text="item.name" @click="setCityCode(item)"></li>
|
</ul>
|
</li>
|
</ul>
|
<!--首字母列表-->
|
<ul class="letter_ul">
|
<li v-for="item in letterList" :key="item" v-html="item" @click="clickLetter($event)"></li>
|
</ul>
|
</div>
|
<div id="positionGeolocation" style="display: none;"></div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
/**
|
* Created by c.y on 2018/3/16.
|
* 我是定位页面
|
* 开发 by c.k
|
*/
|
import {XInput, XHeader, Search} from 'vux';
|
import sysApi from '../../api/api';
|
import statusCodeManage from '../../api/statusCodeManage';
|
|
export default {
|
name: 'f-position',
|
data () {
|
return {
|
cityName: '', // 当前城市名
|
adcode: '', // 当前城市code
|
isSearch: false, // 控制搜索列表
|
hotCity: null, // 热门城市
|
cityList: null, // 城市列表
|
letterList: null, // 字母列表
|
inputInfor: '', // 用户输入内容
|
searchResults: [],
|
contentHeight: 0 // 定位的内容
|
};
|
},
|
components: {
|
XInput, XHeader, Search
|
},
|
methods: {
|
// 更新城市code cityCode为发送请求的code
|
updateCityCode (cityCode) {
|
// 全局发送城市code
|
let newClientInfo = JSON.parse(window.localStorage.getItem('newClientInfo'));
|
newClientInfo.areaCode = cityCode;
|
window.localStorage.setItem('newClientInfo', JSON.stringify(newClientInfo));
|
},
|
// 调取高德地图api, 获取cityCode与cityName
|
fetchCityCodeByGao: function () {
|
let _this = this;
|
// 创建地图对象 需要一个div 对象 id 为geolocation
|
let mapObj = new AMap.Map('positionGeolocation');
|
// 使用城市搜索组件
|
mapObj.plugin('AMap.Geolocation', function () { // AMap.Geolocation AMap.CitySearch
|
let geolocation = new AMap.Geolocation({ // Geolocation
|
enableHighAccuracy: false, //是否使用高精度定位,默认:true
|
GeoLocationFirst: false, // 默认为false,设置为true的时候可以调整PC端为优先使用浏览器定位,失败后使用IP定位
|
timeout: 10000, //超过10秒后停止定位,默认:无穷大
|
maximumAge: 0, //定位结果缓存0毫秒,默认:0
|
showButton: false, // 是否显示定位按钮
|
useNative: false // 是否使用安卓定位sdk用来进行定位
|
// enableHighAccuracy: true, //是否使用高精度定位,默认:true
|
// timeout: 10000, //超过10秒后停止定位,默认:无穷大
|
// maximumAge: 0, //定位结果缓存0毫秒,默认:0
|
// showButton: false, //显示定位按钮,默认:true
|
});
|
// getCurrentPosition getLocalCity
|
// 定位失败的次数,我们约定为3次,3次失败的话,就展示获取城市失败
|
let posiTimes = 3;
|
_this.getGeolocation(geolocation, posiTimes);
|
});
|
},
|
// 高德地图调取api
|
getGeolocation (geolocation, posiTimes) {
|
let _this = this;
|
geolocation.getCurrentPosition(function (status, result) {
|
posiTimes--;
|
// 定位成功
|
if (status == 'complete') {
|
_this.cityName = result.addressComponent.city;
|
_this.adcode = result.addressComponent.adcode;
|
_this.adcode = _this.adcode.substring(0, _this.adcode.length - 2) + '00';
|
let cityCodeObj = {
|
name: _this.cityName,
|
code: _this.adcode
|
};
|
window.localStorage.setItem('cityCode', JSON.stringify(cityCodeObj));
|
_this.updateCityCode(_this.adcode);
|
_this.$router.push({path: '/f-main'});
|
return false;
|
} else {
|
// 定位失败,一直重复定位,如果3次之后,那么就不在定位,直接展示定位失败
|
// 定位失败后,还是使用上一次的code
|
if (!posiTimes) {
|
_this.cityName = '定位失败';
|
let cityCodeObj = {
|
name: _this.cityName,
|
code: JSON.parse(window.localStorage.getItem('newClientInfo')).areaCode
|
};
|
window.localStorage.setItem('cityCode', JSON.stringify(cityCodeObj));
|
return false;
|
} else {
|
// 如果用户拒绝定位,我们可以给出提示,传递成都code
|
if (result.message === 'Geolocation permission denied.') {
|
_this.$vux.toast.text('请开启定位权限,以获取正常的使用', 'middle');
|
_this.cityName = '定位失败';
|
let cityCodeObj = {
|
name: _this.cityName,
|
code: JSON.parse(window.localStorage.getItem('newClientInfo')).areaCode
|
};
|
window.localStorage.setItem('cityCode', JSON.stringify(cityCodeObj));
|
return false;
|
} else {
|
// 如果是其他原因造成的定位失败的话,我们尝试三次定位,如何失败的话
|
// 默认传递成都code,显示定位失败
|
_this.getGeolocation(geolocation, posiTimes);
|
}
|
}
|
}
|
});
|
},
|
userInput: function () {
|
if (this.inputInfor.length > 0) {
|
let _py = this.inputInfor;
|
let result = [];
|
let letterKey = Object.keys(this.cityList);
|
let len = letterKey.length;
|
for (let i = 0; i < len; i++) {
|
let letterVal = this.cityList[letterKey[i]];
|
for (let j = 0, mLen = letterVal.length; j < mLen; j++) {
|
let m = letterVal[j];
|
if (m.name.indexOf(_py) == 0) {
|
result.push(m);
|
}
|
}
|
}
|
this.$refs.searchUl.scrollTop = 46;
|
this.isSearch = true;
|
this.searchResults = result;
|
} else {
|
this.isSearch = false;
|
}
|
},
|
// 处理选择当前城市
|
handleCurrentCity () {
|
// 如果当前正在定位的话,那么点击当前城市,那么就不做什么反应
|
if (this.cityName === '城市定位中...') {
|
return false;
|
// 定位失败的话
|
} else if (this.cityName === '定位失败') {
|
return false;
|
} else {
|
// 只有定位成功后,才跳转到首页
|
this.$router.push({path: '/f-main'});
|
}
|
},
|
// 处理选择重新定位按钮
|
handleAgainPosition () {
|
this.cityName = '城市定位中...';
|
this.fetchCityCodeByGao();
|
},
|
// 处理选择城市
|
setCityCode: function (item) {
|
// 返回城市信息
|
let _item = item;
|
this.isSearch = false;
|
this.searchResults = [];
|
this.inputInfor = '';
|
|
window.localStorage.setItem('cityCode', JSON.stringify(_item));
|
// 修改 localS 的 areaCode
|
this.updateCityCode(_item.code);
|
this.$router.push({path: '/f-main'});
|
},
|
// click 字母, 修改是为了修复ios返回时,dom不加载,需要点击空白才会加载
|
clickLetter: function (e) {
|
let target = e.target || e.srcElement || event.srcElement || event.target;
|
let _htmlNode = document.getElementById('letter_' + target.innerHTML);
|
if (_htmlNode) {
|
// let newY = _htmlNode.offsetTop;
|
// newY -= document.getElementById('searchCityHeader').offsetHeight;
|
// window.scroll(0, newY);
|
this.$refs.posContent.scrollTop = _htmlNode.offsetTop - 46;
|
} else {
|
// window.scroll(0, 0);
|
this.$refs.posContent.scrollTop = 0;
|
}
|
}
|
},
|
deactivated(){
|
this.cityName = '';
|
this.adcode = '';
|
this.isSearch = false;
|
this.hotCity = null;
|
this.cityList = null;
|
this.letterList = null;
|
this.inputInfor = '';
|
this.searchResults = [];
|
this.contentHeight = 0;
|
this.$store.commit('UPDATE_DIRECTION', {direction: 'none'});
|
},
|
activated: function () {
|
// 如果本地没有城市的code的话
|
this.contentHeight = (document.documentElement.clientHeight - 46) + 'px';
|
let cityCode = window.localStorage.getItem('cityCode');
|
if (!cityCode) {
|
this.cityName = '城市定位中...';
|
// 请求高德地图api
|
this.fetchCityCodeByGao();
|
} else {
|
this.cityName = JSON.parse(cityCode).name;
|
this.adcode = JSON.parse(cityCode).code;
|
}
|
// 获取城市列表
|
sysApi.getAreaInfo().then(response => {
|
this.hotCity = response.hotCity;
|
this.cityList = response.cityList;
|
response.group.unshift('热');
|
response.group.unshift('<i class="iconfont icon-location goto-location-icon"></i>');
|
this.letterList = response.group;
|
},
|
error => {
|
statusCodeManage.showTipOfStatusCode(error, this);
|
});
|
}
|
};
|
</script>
|
|
|
<style lang="less">
|
@import "../../style/mixin";
|
|
.position-page {
|
.vux-header {
|
.color-linear-gradient(@color-primary-light, @color-primary, 90deg);
|
.vux-header-title {
|
font-size: 18px;
|
|
}
|
.vux-header-left {
|
.left-arrow:before {
|
border: solid 1px @color-white;
|
border-width: 2px 0 0 2px;
|
}
|
}
|
}
|
.position-content {
|
overflow-y: auto;
|
}
|
.iconfont {
|
display: inline-block;
|
color: @color-white;
|
margin-top: 2px;
|
}
|
.userCityInfo {
|
background-color: @color-background-default;
|
}
|
.userCityInfo h4 {
|
height: 32px;
|
line-height: 32px;
|
padding: 0 12px;
|
font-size: @font-size-medium;
|
font-weight: normal;
|
color: @color-text-third;
|
}
|
.vux-header-title-area {
|
.weui-search-bar {
|
padding: 0;
|
}
|
}
|
.vux-header-title-area, .vux-header .vux-header-title {
|
position: relative;
|
right: -14px;
|
top: 3px;
|
margin: 0 36px;
|
}
|
|
.vux-header .weui-cell {
|
padding: 0 4PX;
|
border-bottom: 1PX solid @color-white; /*no*/
|
}
|
|
.vux-header-title-area .weui-input {
|
height: 30px;
|
}
|
.vux-header-title-area .icon-search {
|
position: relative;
|
font-size: 20Px;
|
}
|
.vux-header-title-area input {
|
position: relative;
|
padding-left: 10px;
|
line-height: 1;
|
color: @color-white;
|
font-size: @font-size-medium;
|
}
|
.vux-header-title-area input::-webkit-input-placeholder {
|
color: @color-white;
|
}
|
.vux-header-title-area .weui-icon-clear:before {
|
color: @color-white;
|
}
|
.hot-city-list {
|
padding: 0 12px;
|
.flexLayout();
|
flex-wrap: wrap;
|
span {
|
width: 30%;
|
height: 44px;
|
line-height: 44px;
|
display: inline-block;
|
margin-right: 10px;
|
margin-bottom: 10px;
|
font-size: @font-size-medium;
|
text-align: center;
|
box-sizing: border-box;
|
background-color: @color-white;
|
color: @color-text-primary;
|
border-radius: @border-radius-normal-size;
|
&:nth-child(3n) {
|
margin-right: 0;
|
}
|
}
|
}
|
.current-city-box {
|
width: 100%;
|
height: 44px;
|
padding: 0 12px;
|
font-size: @font-size-medium;
|
line-height: 44px;
|
background: @color-white;
|
box-sizing: border-box;
|
.current-city {
|
font-size: @font-size-base;
|
color: @color-text-primary;
|
}
|
.position-box {
|
color: @color-primary;
|
float: right;
|
.icon-position {
|
color: @color-primary;
|
}
|
}
|
.icon-location {
|
color: @color-primary;
|
}
|
}
|
.letter_ul {
|
position: fixed;
|
top: 60%;
|
right: -10px;
|
width: 44px;
|
text-align: center;
|
box-sizing: border-box;
|
font-size: @font-size-small;
|
color: @color-primary;
|
border-radius: 6px;
|
background-color: transparent;
|
-moz-transform: translate3d(0, -50%, 0);
|
-ms-transform: translate3d(0, -50%, 0);
|
-o-transform: translate3d(0, -50%, 0);
|
-webkit-transform: translate3d(0, -50%, 0);
|
transform: translate3d(0, -50%, 0);
|
z-index: 999;
|
li {
|
line-height: 1.3;
|
}
|
.goto-location-icon {
|
color: @color-primary;
|
}
|
}
|
.city_letter {
|
background-color: @color-background-default;
|
color: @color-text-primary;
|
text-indent: 6px;
|
}
|
.city_letter_name {
|
padding: 0 12px;
|
font-weight: normal;
|
font-size: @font-size-base;
|
}
|
.city-name {
|
padding-left: 12px;
|
font-size: @font-size-medium;
|
color: @color-text-primary;
|
line-height: 44px;
|
background-color: @color-white;
|
}
|
li {
|
list-style: none;
|
}
|
}
|
|
|
</style>
|