задний план
Второй проект новой компании — построить торговый центр H5 с друзьями, в основном в WeChat, но также рассмотрим и другие браузеры. Среди них главная страница должна найти и отобразить ближайший магазин в соответствии с широтой и долготой текущего пользователя. Работа, которую должен выполнить внешний интерфейс, состоит в том, чтобы получить широту и долготу пользователя, а затем запросить внутренний интерфейс и отобразить страницу.
Цели и анализ
Наша цель — получить возвращенную информацию о местоположении, вызвав только один метод после инкапсуляции.
Что нам нужно сделать, так это инкапсулировать разные классы для разных терминалов (WeChat H5 и других сред браузера), а затем использовать метод, чтобы различать их через UA, и вызывать классы, соответствующие разным средам, для получения местоположения.
В WeChat, после многократной практики, будь то с помощью собственного позиционирования HTML5 или стороннего (например, Baidu или Tencent Maps) jsapi для получения местоположения, не только время позиционирования велико, но даже часто происходит сбой позиционирования, который серьезно влияет на взаимодействие с пользователем. , особенно для домашней страницы торгового центра, где большая часть потока информации зависит от используемого для нее местоположения, совершенно неприемлемо. Итак, в WeChat у нас есть только вариант WeChat sdk;
Со стороны браузера через стороннюю карту jsapi или компонент позиционирования информация о местоположении может быть получена стабильно и быстро.Чтобы максимально соответствовать WeChat, мы выбираем карту Tencent jsapi.
решение
Разговоры дешевы, покажите мне код Не говорите чушь, просто перейдите к коду:
1. В браузере получить местоположение через Tencent Maps jsapi
1.1 Добавьте jsapi Tencent Maps в файл шаблона html проекта
<!-- index.html -->
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=腾讯地图key&referer=应用名称"></script>
проиллюстрировать:
Чтобы использовать jsapi Tencent Maps, вам нужно перейти на открытую платформу Tencent Maps, чтобы подать заявку на собственную учетную запись, затем создать собственное приложение и заменить вышеуказанные значения ключом Tencent Maps и именем созданного приложения.
1.2 Вызовите интерфейс получения местоположения, чтобы получить информацию о местоположении
Чтобы облегчить повторное использование, мы инкапсулируем отдельный класс jsapi Tencent Map с именем tMap.js.
// tMap.js
const qq = window.qq
var geolocation = null
if (qq && qq.maps) {
// 初始化定位组件
geolocation = new qq.maps.Geolocation(
'QVLBZ-YUULR-OUMW7-WKXFD-4SUWS-UDBIA',
'mymap'
)
}
class TMap {
// 获取定位计数器 用于定位失败时累计次数 超过3次后不再继续,抛出定位失败错误
getPositionCount = 0
// 对外暴露的获取位置接口
getLocation () {
return new Promise((resolve, reject) => {
// 定位成功回调
this.getTMapLocation(resolve, reject)
})
}
// 调用腾讯地图获取位置
getTMapLocation (success, fail) {
const _self = this
// 定位成功回调
const showPosition = position => {
uni.setStorage({
key: 'positionData',
data: position
})
success(position)
}
// 定位失败回调
const showErr = (err) =>
// 如果获取定位失败超过3次 抛出错误 否则继续获取定位信息
if (this.getPositionCount > 3) {
fail('超过3次 获取定位失败')
} else {
// 定位失败递归
_self.getPositionCount = _self.getPositionCount + 1
_self.getTMapLocation(success, fail)
}
}
// 调用腾讯web定位组件获取位置信息
if (geolocation) {
geolocation.getIpLocation(showPosition, showErr, {
timeout: 6000, // 定位超时时长 单位ms
failTipFlag: true
})
}
}
}
export default new TMap()
2. В веб-просмотре WeChat получите информацию о местоположении через WeChat SDK.
2.1 Подготовка, связанная с WeChat js-sdk
2.1.1 Знакомство с js-файлами
/**
* 微信sdk异步加载
* @param {*} src
* @param {*} callback api接口
*/
export const handlerLoadScript = callback => {
const src = `https://res.wx.qq.com/open/js/jweixin-1.4.0.js`
if (!(typeof callback === 'function')) {
callback = function() {}
}
var check = document.querySelectorAll(`script[src="${src}"]`)
if (check.length > 0) {
check[0].addEventListener('load', function() {
callback()
})
callback()
return
}
var script = document.createElement('script')
var head = document.getElementsByTagName('head')[0]
script.type = 'text/javascript'
script.charset = 'UTF-8'
script.src = src
if (script.addEventListener) {
script.addEventListener(
'load',
function() {
callback()
},
false
)
} else if (script.attachEvent) {
script.attachEvent('onreadystatechange', function() {
var target = window.event.srcElement
if (target.readyState === 'loaded') {
callback()
}
})
}
head.appendChild(script)
}
2.1.2 Внедрение конфигурации проверки разрешений
Все страницы, которые должны использовать JS-SDK, должны сначала ввести информацию о конфигурации, иначе они не будут вызываться. Информация о конфигурации обычно получается через фоновый интерфейс.
/**
* 注入权限验证配置
* @param {object} 微信 js-sdk 权限验证配置
*/
export const wxconfigInfo = config => {
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: config.appId,
timestamp: parseInt(config.timestamp),
nonceStr: config.nonceStr,
signature: config.signature,
jsApiList: [ // 需要使用的 jsapi 列表
...,
'getLocation' // 获取地理位置
]
})
}
2.2 Вызов API для получения информации о местоположении
/**
* 微信获取位置
*/
export const handleGetLocation = (config) => {
return new Promise((resolve, reject)=>{
wxconfigInfo(config)
wx.ready(function () {
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
console.warn('微信sdk定位成功', res)
resolve({
lat: res.latitude, // 纬度
lng: res.longitude, // 经度
speed: res.speed, // 速度,以米/每秒计
accuracy: res.accuracy // 位置精度
})
},
fail: function (err) {
console.error('微信sdk定位失败', err)
reject(err)
}
})
})
wx.error(function(err) {
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
console.log('wxjsapi-error=', err)
reject(`wxjsapi-error: ${err}`)
})
})
2.3 Вызов различных методов позиционирования в зависимости от операционной среды
// public.js
/**
* UA枚举
*/
const UA = {
/**
* 微信h5
*/
WECHAT: 'WECHAT',
/**
* 支付宝h5
*/
ALIPAY: 'ALIPAY',
/**
* 其他
*/
OTHERS: 'OTHERS'
}
/**
* 判断客户端运行环境 这里只判断微信和浏览器h5
*/
export const getUserAgent = () => {
var userAgent = navigator.userAgent.toLowerCase()
if (userAgent.match(/Alipay/i) == 'alipay') {
return UA.ALIPAY
} else if (userAgent.match(/MicroMessenger/i) == 'micromessenger') {
return UA.WECHAT
} else {
return UA.OTHERS
}
}
// js-sdk.js
/**
* 唤起微信api
* @param {*} _href 当前页面url
* @param {*} options 分享信息
* @param {*} apiType 调用api类型
*/
export const handleWXSDKCall = (_href, apiType, options) => {
return new Promise((resolve, reject)=>{
// 通过后台接口获取配置信息
WeChatServivce.sign(_href)
.then(res => {
if (res) {
if ( apiType === 'location' ) {
handleGetLocation(res).then((res)=>{
resolve(res)
}).catch(err=>{
reject(err)
})
}
}
})
.catch(err => {
reject(`err-sign: ${err}`)
uni.showToast({
title: err.data.code + err.data.msg,
mask: true,
icon: 'none'
})
})
})
}
// getLocation.js
import { getUserAgent, handlerLoadScript } from '@/module/utils'
import { handleWXSDKCall } from '@/module/utils/wechat/wxJsApiSdk'
import UA from '@/module/enums/userAgent'
import TMap from '@/module/utils/tMap'
/**
* 对外暴露的获取位置方法
* @return Promise resolve一个 positionData 对象 lat-纬度 lng-经度
*/
const getLocation = () => {
return new Promise((resolve, reject) => {
console.log('进入全局获取用户位置方法')
const storageData = uni.getStorageSync('positionData')
const userAgent = getUserAgent()
if (storageData) {
resolve(storageData)
} else {
// 根据环境判断 如果在微信内使用微信sdk 其他使用腾讯地图定位组件
if (userAgent === UA.WECHAT) {
handlerLoadScript(() => {
handleWXSDKCall(window.location.href, 'location').then((res) => {
uni.setStorageSync('positionData', res)
resolve(res)
}).catch(err => {
reject(err)
})
})
} else {
TMap.getLocation().then(res => {
uni.setStorageSync('positionData', res)
resolve(res)
}).catch((err) => {
reject(err)
})
}
}
})
}
export default getLocation
3. Вызов страницы
3.1 Метод привязки к прототипу VUE
import getLocation from '@/module/utils/getLocation'
Vue.prototype.$getLocation = getLocation
3.2 Вызов компонента страницы
onShow() {
// 获取位置信息后请求后台接口
this.$getLocation()
.then(res => {
console.warn('首页获取位置成功', res)
this.latitude = res.lat
this.longitude = res.lng
// 这里根据获取到的经纬度请求后台接口...
})
.catch(err => {
console.error('首页获取位置失败', err)
// 错误处理
})
}
Суммировать
Обнаруженные ямы и моменты, на которые следует обратить внимание:
- Чтобы получить информацию о местоположении с помощью WeChat SDK, вам необходимо выполнить следующие шаги по порядку:
- Загружать WeChat SDK асинхронно
- Получите информацию о конфигурации через интерфейс и настройте WeChat SDK
- метод вызова в обратном вызове wx.ready
Вышеуказанные три шага необходимо выполнить в строгом порядке, иначе функции WeChat SDK не могут быть вызваны.
Короче говоря, с помощью этой статьи можно решить более 99% сценариев применения позиционирования H5.