在这篇博文中,我们将探讨如何使用Ionic Capacitor Google Map Plugin构建与 Google Maps 集成的 Vue.js 移动应用程序。
HomePage.vue
Script部分:
Imports:
我们首先导入必要的依赖项和组件。我们从包中导入 Ionic 框架组件@ionic/vue
,并使用 vue 包访问 ref 函数,这使我们能够创建反应式引用。此外,我们从其他文件导入两个自定义组件,MyMap
和。MarkerInfoWindow
最后,我们Capacitor
从用于构建跨平台应用程序的 Capacitor 框架中导入。
import {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonPopover,
modalController,
} from "@ionic/vue";
import { ref } from "vue";
import MyMap from "./MyMap.vue";
import MarkerInfoWindow from "../components/MarkerInfoWindow.vue";
import { Capacitor } from "@capacitor/core";
变量声明:
我们声明了两个响应式引用变量:markerInfo
和markerIsOpen
。这些变量将分别保存有关当前选定标记以及标记弹出窗口是打开还是关闭的信息。
我们定义了一个名为的数组markerData
,用于保存地图上标记的样本数据。每个标记对象由coordinates
(纬度和经度)、atitle
和 a组成snippet
。您可以根据需要添加更多标记来自定义此数据。
const markerInfo = ref<any>();
const markerIsOpen = ref<boolean>(false);
// sample data for the map
const markerData = [
{
coordinate: { lat: 37.769, lng: -122.446 },
title: "title one",
snippet: "title one snippet content will be presented here",
},
{
coordinate: { lat: 37.774, lng: -122.434 },
title: "title two",
snippet: "title two snippet content will be presented here",
},
{
coordinate: { lat: 37.783, lng: -122.408 },
title: "title three",
snippet: "title three snippet content will be presented here",
},
// Add more points as needed
];
功能介绍:
openModal
是单击标记时的事件处理程序。它使用modalController.create()
. 模态显示MarkerInfoWindow
组件,其中显示有关marker
.
mapClicked
是点击地图时的事件侦听器。它只是将一条消息记录到控制台,允许您在单击地图时执行任何所需的操作。
getMarkerInfo
将marker
对象作为输入并返回数组中的关联信息markerData
。此函数用于在单击标记时检索标记信息。
markerClicked
是单击标记时的事件处理程序。它使用Capacitor.isNativePlatform()
. 如果它不是原生的,它调用函数openModal
以模态显示标记信息。这种区别是必要的,因为网络版本不会直接在地图上显示信息窗口。
const openModal = async (marker: any) => {
const modal = await modalController.create({
component: MarkerInfoWindow,
componentProps: {
marker,
},
initialBreakpoint: 0.2,
breakpoints: [0, 0.2],
backdropBreakpoint: 0,
showBackdrop: false,
backdropDismiss: true,
});
modal.present();
const { data, role } = await modal.onWillDismiss();
};
const mapClicked = () => {
console.log("mapClicked");
};
const getMarkerInfo = (marker: { latitude: number; longitude: number }) => {
return markerData.filter(
(m) =>
m.coordinate.lat === marker.latitude &&
m.coordinate.lng === marker.longitude
)[0];
};
const markerClicked = (event: any) => {
console.log(event);
// only use dialog in web since we doesnt show info window
if (!Capacitor.isNativePlatform()) {
openModal(getMarkerInfo(event));
}
};
Script部分:
模板部分使用 Ionic Vue 组件定义我们组件的 HTML 模板的结构和布局。让我们来看看它:
<ion-page>
代表我们 Ionic 应用程序中的一个页面。它为整个内容提供了一个容器。
<ion-header>
包含页面的标题工具栏。我们用它来显示应用程序标题。
<ion-toolbar>
表示标题中的工具栏。它为按钮、标题和其他元素提供了位置。
<ion-title>
显示页面的标题。在这种情况下,它被设置为“Vue + Capacitor + Google Maps”。
<ion-content>
包含页面的主要内容。它提供了一个可滚动的区域,我们将在其中显示我们的地图和标记。
<my-map>
是代表地图的自定义组件。我们传入markerData
prop 以提供标记信息。该组件还发出两个事件:onMapClicked
和onMarkerClicked
,这使我们能够分别处理地图和标记点击。
<ion-popover>
代表一个弹出窗口,它是一个小的覆盖窗口。它需要isOpen
prop 来控制 popover 的可见状态
<ion-page>
<ion-header :translucent="true">
<ion-toolbar>
<ion-title>Vue + Capacitor + Google Maps</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<my-map
:markerData="markerData"
@onMapClicked="mapClicked"
@onMarkerClicked="markerClicked"
></my-map>
<ion-popover
:is-open="markerIsOpen"
size="cover"
@did-dismiss="markerIsOpen = false"
>
<ion-content class="ion-padding">
<div>{{ markerInfo?.title }}</div>
</ion-content>
</ion-popover>
</ion-content>
</ion-page>
MyMap.vue
在本节中,我们将讨论一个新组件,该组件负责使用 Capacitor Google 地图插件渲染地图和标记。我们将解释包含逻辑的脚本部分和定义组件结构的模板部分。
脚本部分:
脚本部分包含自定义地图组件的逻辑和功能。让我们分解一下:
Imports
我们从 vue 包中导入必要的功能,例如 onMounted、nextTick、ref 和 onUnmounted。这些函数用于处理组件生命周期事件。我们还从 @capacitor/google-maps 包中导入 GoogleMap 对象,它提供了与 Google 地图插件交互的功能。
import { onMounted, nextTick, ref, onUnmounted } from "vue";
import { GoogleMap } from "@capacitor/google-maps";
Props 和 Emits 声明
组件定义了两个部分:props 和 emits。Props 允许我们将数据传递到组件中,而 emits 使我们能够触发自定义事件。
在这种情况下,该组件需要一个名为的道具markerData
,其中包含一个标记对象数组。
emits 部分声明了两个事件:onMarkerClicked
和onMapClicked
。单击标记或地图时,这些事件将发回父组件。
// PROPS
const props = defineProps<{
markerData: { coordinate: any; title: string; snippet: string }[];
}>();
// EVENTS
const emits = defineEmits<{
(event: "onMarkerClicked", info: any): void;
(event: "onMapClicked"): void;
}>();
变量声明
mapRef
是一个响应式引用变量,它保存对 DOM 中地图元素的引用。markerIds
是一个反应性参考变量,它包含一个标记 ID 数组。newMap
是一个变量,它将保存 GoogleMap 对象的一个实例。
const mapRef = ref<HTMLElement>();
const markerIds = ref<string[] | undefined>();
let newMap: GoogleMap;
生命周期钩子
onMounted
是一个生命周期钩子,当组件被挂载到 DOM 时运行。在这个钩子里面,我们用来nextTick
等待组件完全渲染。然后,我们调用该createMap
函数来初始化和渲染地图。
onUnmounted
是一个生命周期挂钩,在组件即将卸载时运行。在这个钩子中,我们调用对象removeMarkers
的方法newMap
来从地图中删除标记。
onMounted(async () => {
console.log("mounted ", mapRef.value);
await nextTick();
await createMap();
});
// remove markers on unmount
onUnmounted(() => {
console.log("onunmounted");
newMap.removeMarkers(markerIds?.value as string[]);
});
函数声明
addSomeMarkers
是一个异步函数,它将 GoogleMap 对象的实例作为参数。它从地图中删除任何现有标记,并根据传递给组件的 markerData 属性添加新标记。
createMap
是负责创建和渲染地图的异步函数。它首先检查该mapRef
值是否存在。然后,它使用 Capacitor Google Maps 插件创建一个新的地图实例。它设置地图的 ID、关联的 DOM 元素、API 密钥和初始配置(中心和缩放级别)。
创建地图后,它调用函数addSomeMarkers
将标记添加到地图。最后,它设置事件侦听器来处理标记点击和地图点击,向父组件发出适当的事件。
const addSomeMarkers = async (newMap: GoogleMap) => {
markerIds?.value && newMap.removeMarkers(markerIds?.value as string[]);
// Plot each point on the map
let markers = props.markerData.map(({ coordinate, title, snippet }) => {
return {
coordinate,
title,
snippet,
};
});
markerIds.value = await newMap.addMarkers(markers);
};
/**
*
*/
async function createMap() {
if (!mapRef.value) return;
// render map using capacitor plugin
newMap = await GoogleMap.create({
id: "my-cool-map",
element: mapRef.value,
apiKey: import.meta.env.VITE_APP_YOUR_API_KEY_HERE as string,
config: {
center: {
lat: 37.783,
lng: -122.408,
},
zoom: 12,
},
});
// add markers to map
addSomeMarkers(newMap);
// Set Event Listeners...
// Handle marker click, send event back to parent
newMap.setOnMarkerClickListener((event) => {
emits("onMarkerClicked", event);
});
// Handle map click, send event back to parent
newMap.setOnMapClickListener(() => {
emits("onMapClicked");
});
}
模板部分
模板部分定义组件的 HTML 模板的结构。这是一个细分:
<div>
:充当地图组件的容器。
<capacitor-google-map>
:表示Capacitor Google Maps插件提供的自定义地图组件。它接受一个 ref 属性 (mapRef) 来引用地图元素,并应用内联样式来设置地图的显示、宽度和高度。
<template>
<div>
<capacitor-google-map
ref="mapRef"
style="display: inline-block; width: 100vw; height: 86vh"
>
</capacitor-google-map>
</div>
</template>
在本节中,我们探讨了与 Capacitor 和 Google 地图集成的自定义地图组件的代码。脚本部分处理逻辑,包括创建地图、添加标记和处理事件。模板部分定义组件的 HTML 模板的结构,其中包括一个<div>
容器和<capacitor-google-map>
由 Capacitor Google Maps 插件提供的元素。
MarkerInfoWindow.vue
在本节中,我们将讨论显示标记信息的 Vue 组件。InfoWindow
由于不支持预期的 GoogleMaps,我们在此示例中仅将此组件用于应用程序的 Web 版本。
我们将解释呈现标记数据的模板部分和定义组件逻辑的脚本部分。
模板部分:
模板部分负责呈现组件的 HTML 结构。让我们分解一下:
<ion-content>
:
此 Ionic 框架组件代表组件的主要内容区域。它充当组件内容的容器。
<p>
:
此 HTML 段落元素显示标记信息。段落的内容是使用 Vue 表达式动态生成的JSON.stringify(marker,null,2)
。它使用该JSON.stringify()
函数将 marker prop 转换为带缩进 2 个空格的格式化 JSON 字符串。
这只是您希望形成和显示的信息的占位符,以供用户查看刚刚单击的标记
<template>
<ion-content >
<p>{{JSON.stringify(marker,null,2)}}</p>
</ion-content>
</template>
脚本部分:
脚本部分包含组件的逻辑和功能。让我们来看看它:
导入:
我们从 @ionic/vue 包中导入该组件所需的所有 Ionic 组件。该组件在模板部分中用于表示内容区域。
Props 和 Emits 声明:
该组件定义了两个部分:props
和emits
。Props 允许我们将数据传递到组件中,而 emits 使我们能够触发自定义事件。
在这种情况下,组件需要一个名为 prop 的 prop ,它包含一个具有和属性的marker
对象。coordinate``title
emits 部分声明了一个名为 的事件onDismiss
。
<script setup lang="ts">
import {
IonContent,
} from "@ionic/vue";
// PROPS
const props = defineProps<{
marker: { coordinate: any; title: string };
}>();
const emits = defineEmits<{
(event: "onDismiss"): void;
}>();
简介:
在本节中,我们检查了显示标记信息的 Vue 组件的代码。模板部分使用JSON.stringify()
表达式呈现标记数据。脚本部分定义道具并发出声明。
您可以使用此组件在您的 Vue 应用程序中显示标记信息。根据需要自定义模板部分以实现所需的布局和样式。
结论:
在这篇博文中,我们检查了使用 Vue、Ionic Capacitor 和 Google Maps 构建的自定义地图组件的代码。
通过理解这段代码,您现在为构建与 Ionic Capacitor 和 Google Maps 集成的 Vue 移动应用程序奠定了基础。您可以通过添加其他功能或样式来进一步自定义组件以满足您的特定需求。
请记住在函数中正确配置您的 API 密钥,createMap
以确保 Google 地图插件正常运行。此外,您可以随意浏览 Ionic Capacitor 和 Google Maps 文档,了解更多高级特性和功能。
原文链接:https://juejin.cn/post/7248249730479620153 作者:happyEnding