Skip to content

Commit 5efbb1f

Browse files
committed
Added Vue tutorial source code
1 parent 15757c8 commit 5efbb1f

File tree

12 files changed

+330
-0
lines changed

12 files changed

+330
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
.DS_Store
12+
dist
13+
dist-ssr
14+
coverage
15+
*.local
16+
17+
/cypress/videos/
18+
/cypress/screenshots/
19+
20+
# Editor directories and files
21+
.vscode/*
22+
!.vscode/extensions.json
23+
.idea
24+
*.suo
25+
*.ntvs*
26+
*.njsproj
27+
*.sln
28+
*.sw?
29+
30+
*.tsbuildinfo
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# use-mapbox-gl-js-with-vue
2+
3+
This is supporting code for the Mapbox tutorial [Use Mapbox GL JS in an Vue app](https://docs.mapbox.com/help/tutorials/use-mapbox-gl-js-with-vue/).
4+
5+
## Overview
6+
7+
This tutorial walks through how to setup [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/) in an [Vue](https://vuejs.org) project.
8+
9+
10+
You'll learn how to:
11+
- Setup a Vite JS app to use Svelte
12+
- How to install Mapbox GL JS and its dependencies.
13+
- Use Mapbox GL JS to render a full screen map.
14+
- How to add a toolbar which displays map state like `longitude`, `latitude`, and `zoom` level and is updated as the map is interacted with (showing the map to app data flow).
15+
- How to create a UI button to reset the map to its original view (showing the app to map data flow).
16+
17+
18+
## Prerequisites
19+
20+
- Node v18.20 or higher
21+
- npm
22+
23+
## How to run
24+
25+
- Clone this repository and navigate to this directory
26+
- Install dependencies with `npm install`
27+
- Replace `YOUR_MAPBOX_ACCESS_TOKEN` in `src/components/Map.vue` with an access token from your [Mapbox account](https://console.mapbox.com/).
28+
- Run the development server with `npm run dev` and open the app in your browser at [http://localhost:5173](http://localhost:5173).
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="">
3+
<head>
4+
<meta charset="UTF-8">
5+
<link rel="icon" href="/favicon.ico">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>Vite App</title>
8+
</head>
9+
<body>
10+
<div id="app"></div>
11+
<script type="module" src="/src/main.js"></script>
12+
</body>
13+
</html>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "vue-and-mapbox-gl-js",
3+
"version": "0.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "vite build",
9+
"preview": "vite preview"
10+
},
11+
"dependencies": {
12+
"mapbox-gl": "^3.12.0",
13+
"vue": "^3.5.13"
14+
},
15+
"devDependencies": {
16+
"@vitejs/plugin-vue": "^5.2.3",
17+
"vite": "^6.2.4",
18+
"vite-plugin-vue-devtools": "^7.7.2"
19+
}
20+
}
4.19 KB
Binary file not shown.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<div id="sidebar">
3+
Longitude: {{ location.center.lng.toFixed(4) }} | Latitude:
4+
{{ location.center.lat.toFixed(4) }} | Zoom:
5+
{{ location.zoom.toFixed(2) }} |
6+
<button
7+
@click="
8+
location = {
9+
center: { lng: -71.05987, lat: 42.35982 },
10+
zoom: 14,
11+
}
12+
"
13+
>Reset
14+
</button>
15+
</div>
16+
<Map v-model="location" />
17+
</template>
18+
19+
<script>
20+
import Map from "./components/Map.vue";
21+
22+
export default {
23+
components: { Map },
24+
data() {
25+
return {
26+
location: {
27+
center: { lng: -71.05987, lat: 42.35982 },
28+
zoom: 14,
29+
},
30+
};
31+
},
32+
};
33+
</script>
34+
35+
<style>
36+
#sidebar {
37+
background-color: rgb(35 55 75 / 90%);
38+
color: #fff;
39+
padding: 6px 12px;
40+
font-family: monospace;
41+
z-index: 1;
42+
position: absolute;
43+
top: 0;
44+
left: 0;
45+
margin: 12px;
46+
border-radius: 4px;
47+
}
48+
</style>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/* color palette from <https://github.com/vuejs/theme> */
2+
:root {
3+
--vt-c-white: #ffffff;
4+
--vt-c-white-soft: #f8f8f8;
5+
--vt-c-white-mute: #f2f2f2;
6+
7+
--vt-c-black: #181818;
8+
--vt-c-black-soft: #222222;
9+
--vt-c-black-mute: #282828;
10+
11+
--vt-c-indigo: #2c3e50;
12+
13+
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
14+
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
15+
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
16+
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
17+
18+
--vt-c-text-light-1: var(--vt-c-indigo);
19+
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
20+
--vt-c-text-dark-1: var(--vt-c-white);
21+
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
22+
}
23+
24+
/* semantic color variables for this project */
25+
:root {
26+
--color-background: var(--vt-c-white);
27+
--color-background-soft: var(--vt-c-white-soft);
28+
--color-background-mute: var(--vt-c-white-mute);
29+
30+
--color-border: var(--vt-c-divider-light-2);
31+
--color-border-hover: var(--vt-c-divider-light-1);
32+
33+
--color-heading: var(--vt-c-text-light-1);
34+
--color-text: var(--vt-c-text-light-1);
35+
36+
--section-gap: 160px;
37+
}
38+
39+
@media (prefers-color-scheme: dark) {
40+
:root {
41+
--color-background: var(--vt-c-black);
42+
--color-background-soft: var(--vt-c-black-soft);
43+
--color-background-mute: var(--vt-c-black-mute);
44+
45+
--color-border: var(--vt-c-divider-dark-2);
46+
--color-border-hover: var(--vt-c-divider-dark-1);
47+
48+
--color-heading: var(--vt-c-text-dark-1);
49+
--color-text: var(--vt-c-text-dark-2);
50+
}
51+
}
52+
53+
*,
54+
*::before,
55+
*::after {
56+
box-sizing: border-box;
57+
margin: 0;
58+
font-weight: normal;
59+
}
60+
61+
body {
62+
min-height: 100vh;
63+
color: var(--color-text);
64+
background: var(--color-background);
65+
transition:
66+
color 0.5s,
67+
background-color 0.5s;
68+
line-height: 1.6;
69+
font-family:
70+
Inter,
71+
-apple-system,
72+
BlinkMacSystemFont,
73+
'Segoe UI',
74+
Roboto,
75+
Oxygen,
76+
Ubuntu,
77+
Cantarell,
78+
'Fira Sans',
79+
'Droid Sans',
80+
'Helvetica Neue',
81+
sans-serif;
82+
font-size: 15px;
83+
text-rendering: optimizeLegibility;
84+
-webkit-font-smoothing: antialiased;
85+
-moz-osx-font-smoothing: grayscale;
86+
}
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@import url('./base.css');
2+
3+
#app {
4+
width: 100vw;
5+
height: 100vh;
6+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<template>
2+
<div ref="mapContainer" class="map-container"></div>
3+
</template>
4+
5+
<script>
6+
import mapboxgl from "mapbox-gl";
7+
import "mapbox-gl/dist/mapbox-gl.css";
8+
9+
mapboxgl.accessToken = "YOUR_MAPBOX_ACCESS_TOKEN";
10+
11+
export default {
12+
props: ["modelValue"],
13+
mounted() {
14+
const { center, zoom } = this.modelValue
15+
16+
const map = new mapboxgl.Map({
17+
container: this.$refs.mapContainer,
18+
style: "mapbox://styles/mapbox/standard",
19+
center,
20+
zoom,
21+
});
22+
23+
// function to update the modelValue prop with the map's current location
24+
const updateLocation = () => this.$emit("update:modelValue", this.getLocation());
25+
26+
// add event listeners to update the location on map move and zoom
27+
map.on("move", updateLocation);
28+
map.on("zoom", updateLocation);
29+
30+
// assign the map instance to this component's map property
31+
this.map = map;
32+
},
33+
34+
// clean up the map instance when the component is unmounted
35+
unmounted() {
36+
this.map.remove();
37+
this.map = null;
38+
},
39+
// watch for external changes to the modelValue prop and update the map accordingly
40+
watch: {
41+
modelValue(next) {
42+
const curr = this.getLocation();
43+
44+
// Only flyTo if any of the values have changed
45+
if (
46+
curr.center.lng !== next.center.lng ||
47+
curr.center.lat !== next.center.lat ||
48+
curr.zoom !== next.zoom
49+
) {
50+
this.map.flyTo({
51+
center: next.center,
52+
zoom: next.zoom,
53+
});
54+
}
55+
},
56+
},
57+
methods: {
58+
getLocation() {
59+
return {
60+
center: this.map.getCenter(),
61+
zoom: this.map.getZoom(),
62+
};
63+
},
64+
}
65+
};
66+
</script>
67+
68+
<style>
69+
/* make the map container fill its parent */
70+
.map-container {
71+
width: 100%;
72+
height: 100%;
73+
}
74+
</style>

0 commit comments

Comments
 (0)