腾讯位置服务示例小程序(二)

本文详述了腾讯位置服务小程序中Map组件的使用,包括地图显示、地图控件、标注点等功能。通过初始化tab导航组件、控制地图显示、使用地图控件以及交互事件,展示了如何在小程序中实现地图功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本篇博文主要对Map组件下的二级菜单进行学习。

Map组件

地图显示

在地图显示页面中,主要由tab导航,地图显示窗口和切换按钮组成。虽然该页面内容较为丰富,但我们只对较为实用对几个功能进行学习。

tab导航组件的初始化

tab导航组件的初始化在这个小程序中非常的简单,只需要在wxml中进行如下声明

<tab tabList="{{tabList}}" bind:clickTab="clickTab"/>

其中,tab为一个组件,在json文件中引入;tabList为需要在js文件中进行定义的数据列表;clickTab为需要在js文件中进行定义的响应函数。至于tab这个组件的详细学习,我们会在稍后进行学习。根据tab组件的要求,tabList中的每一段数据需要包含name属性,故js中的表示如下

tabList: [{
			id: 0,
			show: true,
			name: '基础地图'
		},{
			id: 1,
			show: false,
			name: '室内图'
		},{
			id: 2,
			show: false,
			name: '海外地图'
		},{
			id: 3,
			show: false,
			name: '卫星图'
		}],

其中,id可以用来进行唯一标示,show可以用来表示该子tab对应的页面是否应当被显示。当点击tab中的子标签时,会触发tab导航的响应函数,即

	// 点击标题栏处的tab的响应函数
	clickTab (event) {
		// 与之前类似,即使用id来判断当前哪个tab被点击
		const id = event.detail.current,list = this.data.tabList;
		for (let i = 0, len = list.length; i < len; ++i) {
			if (list[i].id === id) {
				list[i].show = !list[i].show;
			} else {
				list[i].show = false;
			}
		}
		// 更新数据
		this.setData({
			tabList: list
		});
	},

自此,tab导航组件初始化完毕。

使用tab导航来控制哪一个页面需要被显示

由于tab导航使用show字段来表示当前哪个tab子控件处于激活状态,故在wxml中,使用如下代码来对页面进行显示和不显示的操作

<view class="map-content pl20 {{tabList[0].show ? 'map-content-show' : '' }}">
<view class="map-content pl20 {{tabList[1].show ? 'map-content-show' : '' }}">
<view class="map-content pl20 {{tabList[2].show ? 'map-content-show' : '' }}">
<view class="map-content pl20 {{tabList[3].show ? 'map-content-show' : '' }}">

由上述代码可以看出,当tabList[n].show的值为true时,即表示当前第n个子控件处于激活状态,故将该页面进行展示。

地图控件的显示

微信小程序API提供了一个直接用来显示地图的组件,能够使开发者轻而易举的将地图展现到页面中。在这里,主要列举了两个较为典型的地图组件使用方式

<!-- 这里的latitube和logitude为经纬度
        即打开地图是的视野位置 -->
<!-- enable-3D是否显示3D楼块,参数为bool -->
<!-- enable-traffic是否开启实时路况,参数为bool -->
<map class="map" latitude="40.040415" longitude="116.273511" scale="17" enable-3D="{{is3D}}" enable-traffic="{{isRealTraffic}}"></map>
<!-- enable-satellite表示是否开启卫星图,默认为true -->
<map class="map" latitude="40.040415" longitude="116.273511" scale="15" enable-satellite></map>

在上述代码中,经纬度是人为硬编码到代码中。而在我们实际开发中,可以使用数据绑定等方法,在js脚本中对经纬度进行改变,进而渲染到wxml文件中。

切换按钮组件

在这个样例中,出现了一个新的组件,即切换按钮组件。该组件只有两个状态,即开启和关闭状态。它在wxml中的声明如下

<switch color="#3875FF" checked="{{is3D}}" bindchange="onChange3D"></switch>

其中,color为switch组件开启后显示的背景色;checked为一个动态改变值,当switch组件关闭时,checked对应的变量为false,反之为true;bindchange为switch组件状态发生变化时的响应函数。响应函数的例子如下

	// 使用切换按钮来确定是否显示3D
	onChange3D (event) {
		this.setData({
			// 这里的is3D即为之前wxml中的is3D
			is3D: event.detail.value
		});
	},

地图视野控制

感觉这个二级菜单没啥好说的。

地图控件

正如小程序里边的提示文字所说,“此页面展示地图提供的控件产品,包含比例尺,指南针,定位控件”。从页面可以看出,比例尺,指南针和定位控件均由switch组件来决定他们是否显示,故主要还是看map组件是如何定义的

<map
	class="map"
	id="map"
	latitude="{{location.latitude}}"
	longitude="{{location.longitude}}"
	show-location="{{showPosition}}"
	show-compass="{{isShowCompass}}"
	show-scale="{{isShowScale}}"
	scale="16"
>
</map>

这个map组件比之前我们使用的map组件多了很多参数,但新增的参数也很容易理解,即是否开启比例尺,指南针和定位控件有后边的变量来决定。而这些变量的改变权由三个switch组件来决定。

<switch color="#3875FF" checked="{{isShowScale}}" bindchange="onChangeShowScale"></switch>
<switch color="#3875FF" checked="{{isShowCompass}}" bindchange="onChangeShowCompass"></switch>
<switch class="feature-switch" color="#3875FF" checked="{{isShowPosition}}" bindchange="onChangeShowPosition"></switch>

其中,比例尺和指南针对应的switch按钮的响应函数很简单,就是改变对应绑定数据的值而已。定位控件的响应函数还包含了对设备定位的获取

	// 激活定位控件
	onChangeShowPosition (event) {
		// const {value} = event.detail与
		// value = event.detail.value等价
		const {value} = event.detail;
		if (value) {
			// 取得设备当前位置
			wx.getLocation({
				type: 'gcj02',
				success: (res) => {
					// 将位置的经纬度更新到全局数据中
					const {latitude, longitude} = res;
					this.setData({
						location: {
							latitude,
							longitude
						}
					});
				}
			});
		}
		this.setData({
			showPosition: value
		});
	},

定位控件显示,也就是在地图上显示设备的位置,并将视野切换到该位置上。

标注点

该页面主要对地图当中对标注点和标注点上方的气泡进行学习。

初始化有marker的地图

<map class="map" markers="{{calloutMarkers}}" latitude="40.040415" longitude="116.273511" scale="15"></map>

该声明与之前的map不同点在于,多了一个marker参数。marker参数的样例如下

const INIT_MARKER = {
	// marker上的气泡显示
	callout: {
		content: '腾讯总部大楼',
		// 边缘留白大小
		padding: 10,
		// 圆角大小
		borderRadius: 2,
		// 'BYCLICK':点击显示; 'ALWAYS':常显
		display: 'ALWAYS'
	},
	// 坐标位置
	latitude: 40.040415,
	longitude: 116.273511,
	// maker的标志
	iconPath: './imgs/Marker1_Activated@3x.png',
	// 宽高旋转透明度
	width: '34px',
	height: '34px',
	rotate: 0,
	alpha: 1
};

可以看到,在map组件中有经纬度的设置,在makrer中也有经纬度的设置,他们二者不通点在于,map组件中的经纬度控制了镜头的位置,marker中的经纬度控制了marker出现的位置。

选择marker的图标

通过在页面中对不同图标对选择,进而对marker数据进行更新,并刷新到显示页面

<!-- 选择图标,使用for来遍历图标列表 -->
<!-- 响应函数为onSelectMarkerImg -->
<view class="feature-txt-item" bindtap="onSelectMarkerImg" data-index="{{index}}" wx:for="{{markerImgs}}">
	<!-- 使用index来判断当前选中那一个图标,并改变图标 -->
	<image hidden="{{index === markerImgIndex}}" class="marker-img" src="{{item.normal}}"></image>
	<image hidden="{{index !== markerImgIndex}}" class="marker-img" src="{{item.active}}"></image>
</view>
// 选择marker的图标
onSelectMarkerImg (event) {
	const markerImgIndex = event.currentTarget.dataset.index;
	// 如果未改变
	if (markerImgIndex === this.data.markerImgIndex) {
		return;
	}
	// 更新markers的数据
	this.setData({
		'markers[0].iconPath': this.data.markerImgs[markerImgIndex].active,
		markerImgIndex
	});
},

上述js脚本有一个注意的点,就是当我们需要对markers[0].iconPath进行值对修改时,不是直接使用markers[0].iconPath: xxxx,而是先将markers[0].iconPath包成字符串,然后再赋值修改。那是因为markers是一个类数组对变量,所有需要进行这样对操作。

改变marker的旋转角度

这里使用了一个新控件,即滑动控制条。当对滑动控制条进行滑动时,该组件会触发响应函数,并将数值回传给js脚本

<!-- slider组件,滑动控制条 -->
<!-- value为组件显示的数值,这里采用双向绑定 -->
<!-- color为剩余部分的颜色,activeColor为挪动的颜色 -->
<!-- min为最小值,max为最大值 -->
<slider class="slider" value="{{markers[0].rotate}}" bindchange="onChangeMarkerRotate" color="#e5e5e5" activeColor="#3875ff" block-size="20" min="0" max="360"/>

使用响应函数来接收调整的值并对js中对数据进行更新

// 改变旋转角度的响应函数
onChangeMarkerRotate (event) {
	const {value} = event.detail;
	this.setData({
		'markers[0].rotate': value
	});
},

调整透明度与调整旋转角度类似,唯一区别在于,调整透明度使用了一个新的参数,即步长

<slider class="slider" value="{{markers[0].alpha}}" step="0.01" bindchange="onChangeMarkerAlpha" color="#e5e5e5" activeColor="#3875ff" block-size="20" min="0" max="1"/>

输入设置气泡显示文字

用户通过intup组件可以将自己输入的文字更新到marker气泡上。

<input
	class="callout-input"
	value="{{calloutMarkers[0].callout.content}}"
	placeholder="不得超过 10 字"
	bindinput="onInputChange"
/>

其中,双向绑定的数值为calloutMarkers对应的内容;input组件缺省值为不得超过 10 字;每当input组件内的内容发生变化时,就会调用响应函数onInputChange。该响应函数与其他响应函数类似,都是用来更新js脚本中的数据

onInputChange (event) {
	const {value} = event.detail;
	this.setData({
		'calloutMarkers[0].callout.content': value
	});
},

弹框调整文字颜色

页面结构主要是通过数据来对文字颜色进行修改。还有一个重要对点在于,点击触发对响应函数

<!-- 绑定点击响应事件 -->
<view class="feature-content border-bottom" bindtap="ontriggerSelectColor">
	<text class="feature-label">文本颜色</text>
	<view class="feature-txt">
		<!-- 通过数据来动态修改文字的样式 -->
		<text style="{{'color:' + (calloutMarkers[0].callout.color || '#222')}}">{{calloutMarkers[0].callout.color ? '文本颜色' : '默认颜色'}}</text>
		<!-- 右箭头图片 -->
		<image class="right-arrow" src="{{imgs.rightArrow}}"></image>
	</view>
</view>

在该小程序中,点击文本颜色会从底部弹出一个可选择对列表,这是有响应函数配合组件来实现的

ontriggerSelectColor () {
	this.setData({
		showColorActionsheet: true
	});
},

上述响应函数中将showColorActionsheet这个标志位变成了true,故激活了下方的组件

<mp-actionsheet
	bindactiontap="onSelectColor"
	ext-class="color-actionsheet"
	show="{{showColorActionsheet}}"
	actions="{{calloutColors}}">
</mp-actionsheet>

这个组件是一个自定义组件,详细的代码内容我们先暂时不去考虑。可以看到,这个组件中有响应函数bindactiontap,有样式ext-class,有是否展示组件的标志show,以及需要渲染的内容actions。需要actions的值的形式为

calloutColors: [
	{text: '文本颜色', value: '#3875FF'},
	{text: '文本颜色', value: '#00C562'},
	{text: '文本颜色', value: '#F74A14'},
	{text: '默认颜色', value: ''}
],

响应函数的内容为

onSelectColor (event) {
	const {value} = event.detail;
	
	if (value) {
		console.log(value)
		// 得到颜色值后,让组件消失,并设置颜色
		this.setData({
			showColorActionsheet: false,
			'calloutMarkers[0].callout.color': value
		});
	} else {
		// 点击默认颜色后
		const callout = {...this.data.calloutMarkers[0].callout};
		// 删除之前选择的颜色信息
		delete callout.color;
		// 重置
		this.setData({
			showColorActionsheet: false,
			'calloutMarkers[0].callout': {
				...callout
			}
		});
	}
},

页面中的其他选项都大同小异,故不再进行详细讨论。

覆盖物

触发事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值