This tutorial will guide you through the process of recreating an existing project that integrates OpenLayers Map with VueJS, using Vite, Pinia, and TypeScript. The original project used Vuex, which has since been deprecated, so we will be updating it with the newer and more efficient state management library, Pinia.
We will start by setting up a new project using Vite, a modern build tool that provides fast development and builds speeds. We will then install the necessary dependencies, including OpenLayers, VueJS, and Pinia. We will also enable TypeScript in our project to ensure type safety.
OpenLayers VueJS integration series:
1. Integrating OpenLayers Map with VueJS: Create Map – Part 1
2. Integrating OpenLayers Map with VueJS: Create Layers Panel – Part 2
3. Integrating OpenLayers Map with VueJS: Create Implement Style and legend for vector layer – Part_3
4. Integrating OpenLayers Map With VueJS: Open Feature Information Popup On Click – Part 4
5. Integrating OpenLayers Map with VueJS: Recreating the project with Vite, Pinia and TypeScript-Part 5
To get full source code for this tutorial, click here.
To check the live demo for this tutorial, click here.
1.Create latest VueJS application with npm init vue@latest
We will use npm init vue@latest command to create a latest VueJS application. This command will internally use Vite to create project. The created project will be using a build setup based on Vite.
When you run the command, it will ask you to select the options while creating the project. Give project name and make sure you select yes for all options. It will create the project. Then go to vue-layers directory, install dependencies using npm install and run the the project using using npm run dev.
We have created the the simple basic project using Vite as build tool enabling TypeScript and Pinia
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
(base) geoknight@pop-os:~/Desktop/Learning/ol_vuejs/vue-layers$ npm init vue@latest Vue.js - The Progressive JavaScript Framework ✔ Project name: … vue-layers ✔ Add TypeScript? … No / Yes ✔ Add JSX Support? … No / Yes ✔ Add Vue Router for Single Page Application development? … No / Yes ✔ Add Pinia for state management? … No / Yes ✔ Add Vitest for Unit Testing? … No / Yes ✔ Add an End-to-End Testing Solution? › Cypress ✔ Add ESLint for code quality? … No / Yes ✔ Add Prettier for code formatting? … No / Yes Scaffolding project in /home/geoknight/Desktop/Learning/ol_vuejs/vue-layers/vue-layers... Done. Now run: cd vue-layers npm install npm run format npm run dev (base) geoknight@pop-os:~/Desktop/Learning/ol_vuejs/vue-layers$ cd vue-layers/ (base) geoknight@pop-os:~/Desktop/Learning/ol_vuejs/vue-layers/vue-layers$ npm install npm WARN deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead added 642 packages, and audited 643 packages in 2m 141 packages are looking for funding run `npm fund` for details found 0 vulnerabilities (base) geoknight@pop-os:~/Desktop/Learning/ol_vuejs/vue-layers/vue-layers$ npm run dev VITE v4.2.1 ready in 376 ms ➜ Local: http://127.0.0.1:5174/ ➜ Network: use --host to expose ➜ press h to show help |
After running the project using npm run dev command, you will see below web page running on the local server.
2.Configuring Pinia store for state management
Since, we have already selected Pinia store as state management during project creation, it has been already configured in our app.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import router from './router' import './assets/main.css' const app = createApp(App) app.use(createPinia()) app.use(router) app.mount('#app') |
To configure a Pinia store, you will first need to import the defineStore
function from the Pinia library. This function is used to define a new store.
Next, you can use the defineStore
function to create a new store by passing it a name for the store, along with an object that defines the store’s state, getters, and actions. In the example code provided, the store is named ‘map’, and it has a state object with a single property named ‘map’, which is an empty object.
The getters
object contains a single getter function named getMap
, which returns the value of the ‘map’ property in the state object.
The actions
object contains a single action function named setMap
, which takes an argument named map
and sets the value of the ‘map’ property in the state object to the value of the map
argument.
Once the store has been defined, it can be used in Vue.js components by importing it and calling its getter and action functions as needed.
Overall, configuring a Pinia store involves defining the store’s state, getters, and actions using the defineStore
function and then using the store in your Vue.js components to manage the application state.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import { defineStore } from 'pinia' export const useMapStore = defineStore('map', { state: () => ({ map: {} }), getters: { getMap: (state) => state.map, }, actions: { setMap(map: {}) { this.map = map }, }, }) |
3.Changing existing Vuejs components.
In the previous tutorials, we developed Vue components, and now we need to update the code to use Pinia for state management. To achieve this, we will need to make some changes to the code.
First, we will need to import the useMapStore
function from the Pinia store we created in 2nd step in our Vue components. This function enables us to access the Pinia store from within the component.
Next, we will need to update our component’s computed properties and methods to use the Pinia store’s getters and actions to access and update the application state. We can do this by calling the useMapStore
function in our component and accessing the getters and actions through the returned store object.
We will also need to update the mounted
hook in our component to use the Pinia store’s action to fetch data, instead of using the Vuex store’s action.
Additionally, we need to include the lang="ts"
attribute in the script
tag of our component to enable TypeScript in the component.
Finally, we will need to apply these same changes to all of our Vue components to ensure that they are fully integrated with Pinia for state management.
Overall, these changes will allow us to use Pinia for state management in our Vue application, providing a more efficient and modern solution than the previously used Vuex library.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<template> <q-page class="flex flex-center"> <div id="map"> </div> <MapPopup/> </q-page> </template> <script lang="ts"> import { defineComponent } from 'vue' import { Map, View } from 'ol'; import { Tile as TileLayer } from 'ol/layer'; import { OSM } from 'ol/source'; import MapPopup from './MapPopup.vue' import { useMapStore } from '@/stores/mapStore'; export default defineComponent({ name: 'MapApp', components: { MapPopup }, mounted() { const store = useMapStore(); let map = new Map({ target: 'map', layers: [ new TileLayer({ source: new OSM(), name: 'OpenStreetMap', isBaseMap: true }) ], view: new View({ center: [-9869708.964428628, 4908948.052576464], zoom: 4 }) }); store.setMap(map); window.map = map; } }) </script> <style scoped> #map { height: 100vh; width: 100%; margin: 0; padding: 0; } </style> |
I hope this tutorial will create a good foundation for you. If you want tutorials on another GIS topic or you have any queries, please send an email at contact@spatial-dev.guru.