thorui加入自己的理解以及修改。
效果图:

讯享网
代码:
<template> <view class="maps-container"> <view class="search-bar"> <view class="search-bar-form"> <!-- 第一个显示的输入框 --> <view class="search-bar-label" v-show="!inputShowed" @tap="showInput"> <icon class="icon-search" type="search" :size="16"></icon> <view class="search-bar-text">请输入您的目的地</view> </view> <!-- 点击后出现的第二个输入框 --> <view class="search-bar-box"> <icon class="icon-search-in-box" type="search" :size="16"></icon> <input confirm-type="search" class="search-bar-input" placeholder="请输入您的目的地" :value="inputVal" :focus="inputShowed" @confirm="bindInput" @input="inputTyping" /> <!-- 取消的叉叉 --> <view class="icon-clear" v-if="inputVal" @tap="clearInput"> <icon type="clear" size="14"></icon> </view> </view> </view> <view class="cancel-btn" @tap="hideInput" v-show="inputShowed">取消</view> </view> <map class="tui-map" :latitude="lat" :longitude="lng" :markers="covers" @markertap="marker" :scale="12"></map> <scroll-view scroll-y class="scrollView" :style="{height:scrollH +'px'}" @scrolltolower="pullUp"> <view class="tui-list"> <view class="tui-list-cell" :class="[index==address.length-1?'tui-cell-last':'']" v-for="(item,index) in address" :key="index"> <view class="addr-title"> <text>{
{
item.title}}</text> </view> <view class="addr-box "> <view class="addr-detail "> <text class="distance">{
{
item.distance}}m</text> {
{
item.address}} </view> <view class="addr-opera "> <view class="opera-box " hover-class="tui-opcity" :hover-stay-time="150 " @tap="call " :data-id="item.id" v-if="item.tel"> <image src="/static/map_image/call.png" class="mini-img"></image> <view class="text">打电话</view> </view> <view class="opera-box " hover-class="tui-opcity" :hover-stay-time="150" @tap="go" :data-id="item.id"> <image src="/static/map_image/go.png" class="mini-img"></image> <view class="text">到这里</view> </view> </view> </view> </view> <!-- <tui-loadmore :index="3" v-if="loading"></tui-loadmore> --> </view> </scroll-view> </view> </template> <script> const MapWX = require('@/utils/map-wx-jssdk.min.js'); export default {
data() {
return {
inputShowed: false, inputVal: "", mapsdk: null, key: 'W4WBZ-TUD65-IDAIR-QPM36-HMFQ5-CGBZP', lat: 22.63137, lng: 114.010857, // 标记点数组,设置了就能在地图上显示点 covers: [], address: [], scrollH: 256, pageIndex: 1, loading: true, pullUpOn: true, keywords: '' } }, onLoad(options) {
this.mapsdk = new MapWX({
key: this.key }); // 这里可以改成自己想要搜索的值 this.keywords = options.key || '加油站'; setTimeout(() => {
let winHeight = uni.getSystemInfoSync().windowHeight; // scrollview的高度,uni.upx2px(1000)越大,高度越小 // this.scrollH = winHeight - 44 - uni.upx2px(600); this.scrollH = winHeight - 44 - uni.upx2px(1000); this.getLocation(() => {
this.getPoiAround(this.keywords) }); }, 300) }, methods: {
// 去掉前导空格和后导空格。 trim: function(value) {
return value ? value.toString().replace(/(^\s*)|(\s*$)/g, "") : value; }, // 显示第二个输入框 showInput() {
this.inputShowed = true }, // 隐藏第二个输入框 hideInput() {
this.inputVal = ""; this.inputShowed = false; uni.hideKeyboard(); //强行隐藏键盘 }, // 取消的叉叉的事件 clearInput() {
this.inputVal = "" }, // 输入一个字符串就会进入这里 inputTyping: function(e) {
this.inputVal = e.detail.value }, getLocation(callback) {
//当前位置 const that = this; //H5:使用坐标类型为 gcj02 时,需要配置腾讯地图 sdk 信息(manifest.json -> h5) uni.getLocation({
type: 'gcj02', altitude: true, success(res) {
that.lat = res.latitude; that.lng = res.longitude; callback(); }, fail(res) {
callback(); } }); }, calculateDistance(to, callback) {
// let url=`https://apis.map..com/ws/distance/v1/?mode=walking&to=&output=jsonp&key=W4WBZ-TUD65-IDAIR-QPM36-HMFQ5-CGBZP&from=39.%2C116.`; this.mapsdk.calculateDistance({
from: '', //默认当前位置 to: to, success: res => {
callback && callback(res.result); }, fail: res => {
callback && callback(false); } }); }, getResult(data) {
let arr = []; let addr = []; let idx = this.address.length; // this.calculateDistance(data, d => {
// if (d) {
// let distanceArr = d.elements || []; // for (let i = 0, len = data.length; i < len; i++) {
// data[i].distance = distanceArr[i].distance; // } // } // }); for (let [index, item] of data.entries()) {
arr.push({
id: index + idx, latitude: item.location.lat, longitude: item.location.lng, title: item.title, iconPath: "/static/map_image/location.png", width: 32, height: 32 }); let tel = this.trim(item.tel); if (~tel.indexOf(';')) {
tel = tel.split(';')[0]; } addr.push({
id: index + idx, latitude: item.location.lat, longitude: item.location.lng, title: item.title, address: item.address, tel: tel, distance: item._distance }); } this.address = this.address.concat(addr); // 标记点数组,设置了就能在地图上显示点 this.covers = this.covers.concat(arr); this.pageIndex++; this.loading = false; if (data.length < 10) {
this.pullUpOn = false; } }, pullUp() {
if (!this.pullUpOn || this.loading) return; this.loading = true; this.getPoiAround(this.keywords) }, // 根据关键字搜索周边符合的地址 getPoiAround(keywords) {
//检索周边的POI let boundary = `nearby(${
this.lat},${
this.lng},1000)`; // #ifdef H5 //https://lbs..com/service/webService/webServiceGuide/webServiceSearch let url = `https://apis.map..com/ws/place/v1/search?keyword=${
keywords}&boundary=${
boundary}&page_size=20&page_index=${
this.pageIndex}&output=jsonp&key=${
this.key}`; this.tui.tuiJsonp( url, res => {
if (res.status === 0) {
let data = res.data || []; this.getResult(data) } }, 'map' ); // #endif // #ifndef H5 this.mapsdk.search({
keyword: keywords, page_index: this.pageIndex, page_size: 20, boundary: boundary, //无此参数 location: {
latitude: this.lat, longitude: this.lng }, success: res => {
let data = res.data || []; this.getResult(data) }, fail: res => {
this.loading = false; this.tui.toast('获取位置信息失败,请检查是否打开位置权限'); } }); // #endif }, // 点了键盘上的搜索响应事件 bindInput: function(e) {
console.log("输入11",e) this.keywords = e.detail.value; this.pageIndex = 1; this.address = []; this.covers = []; this.pullUpOn = true; // 根据关键字搜索 this.getPoiAround(this.keywords); }, // 点击标记点时触发 marker: function(e) {
const that = this const item = that.address[e.detail.markerId || 0]; const menu = item.tel ? ["打电话", "到这里"] : ["到这里"]; uni.showActionSheet({
itemList: menu, success(res) {
if (res.tapIndex == 0 && item.tel) {
uni.makePhoneCall({
phoneNumber: item.tel }) } else {
const latitude = Number(item.latitude) const longitude = Number(item.longitude) uni.openLocation({
name: item.title, address: item.address, latitude, longitude, scale: 18 }) } }, fail(res) {
console.log(res.errMsg) } }) }, call(event) {
const index = Number(event.currentTarget.dataset.id); const tel = this.address[index].tel; if (tel) {
uni.makePhoneCall({
phoneNumber: tel }) } }, go(event) {
const index = Number(event.currentTarget.dataset.id) const item = this.address[index]; const latitude = Number(item.latitude) const longitude = Number(item.longitude) uni.openLocation({
name: item.title, address: item.address, latitude, longitude, scale: 18 }) } } } </script> <style> page {
height: 100%; } .tui-list {
background-color: #fff; position: relative; width: 100%; display: flex; flex-direction: column; padding-bottom: env(safe-area-inset-bottom); } .tui-list-cell {
position: relative; display: flex; flex-direction: row; justify-content: space-between; align-items: center; } .tui-list-cell::after {
content: ''; position: absolute; border-bottom: 1rpx solid #eaeef1; -webkit-transform: scaleY(0.5); transform: scaleY(0.5); bottom: 0; right: 0; left: 30rpx; } .tui-cell-last::after {
border-bottom: 0; } .maps-container {
width: 100%; height: 100%; overflow: hidden; } .tui-map {
width: 100%; /* height: 1000rpx; */ height: 65%; display: block; } .scrollView {
width: 100%; padding-bottom: 50rpx; background-color: #fff; } .search-bar {
position: relative; padding: 8px 10px; display: -webkit-flex; display: flex; box-sizing: border-box; align-items: center; background-color: #fff; } .icon-search {
margin-right: 8px; } .icon-search-in-box {
margin-right: 8rpx; } .search-bar-form {
position: relative; -webkit-box-flex: 1; -webkit-flex: auto; flex: auto; border-radius: 5px; background-color: #f0f0f0; } .search-bar-text {
display: inline-block; font-size: 14px; vertical-align: middle; } .search-bar-box {
width: 100%; height: 30px; padding-left: 10px; padding-right: 30px; box-sizing: border-box; display: flex; align-items: center; flex-wrap: nowrap; position: relative; z-index: 1; } .search-bar-input {
font-size: 14px; flex: 1; } .icon-clear {
height: 100%; position: absolute; top: 0; right: 0; padding: 0 8px; font-size: 0; display: flex; align-items: center; } .search-bar-label {
width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2; border-radius: 3px; text-align: center; color: #9b9b9b; background: #f0f0f0; display: flex; align-items: center; justify-content: center; } .cancel-btn {
margin-left: 10px; line-height: 30px; color: #5982fd; white-space: nowrap; font-size: 15px; } .tui-list-cell {
display: initial; padding: 30rpx; } .addr-title {
font-size: 30rpx; line-height: 40rpx; color: #000; font-weight: bold; width: 100%; padding-bottom: 20rpx; } .addr-box {
display: flex; align-items: flex-end; justify-content: space-between; } .addr-detail {
width: 450rpx; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; /* autoprefixer: off */ -webkit-box-orient: vertical; /* autoprefixer: on */ font-size: 24rpx; color: #999; } .distance {
color: #5677fc; padding-right: 6rpx; } .addr-opera {
display: flex; align-items: center; justify-content: space-between; } .opera-box {
text-align: center; margin-left: 26rpx; } .mini-img {
width: 44rpx; height: 44rpx; } .text {
color: #333; font-size: 24rpx; line-height: 30rpx; } </style>
讯享网
获取位置权限:


项目下载地址:https://download.csdn.net/download/wy/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/120532.html