DEV Community

时空路由器
时空路由器

Posted on

How to use MapboxGL in Vue more elegantly

Vue provides a declarative and component-based programming model that helps you efficiently develop user interfaces, be it simple or complex.

To more elegantly in using mapbox-gl, there is a package named MapVue.

MapVue is a comprehensive MapboxGL component library. You can easily and happily apply MapVue to your Vue projects. Import various data sources and layers in the form of components, and update props of layers and sources in map by MVVM.

How it works?

MapVue essentially wraps some classes in MapboxGL and implements componentization through some variable properties of the watch class.

For example, the v-fill-layer component actually wraps the FillLayer class.

There are 25 components im MapVue, almost contains all of the mapbox-gl APIS.

The core component is VMap component. It is the top-level component, all other components must be wrapped in VMap, it instantiates a mapboxgl.Map and provides the map instance to child components.

Components lists

  • Core Components
    • VMap
  • Common Components
    • VMarker: wrap mapboxgl.Marker
    • VPopup: wrap mapboxgl.Popup
    • VSprit: add an image to the style
    • VFog: wrap map.setFog
    • VFeatureState: set the state of a feature
  • Control Components
    • VAttributionControl: wrap AttributionControl control
    • VNavigationControl: wrap NavigationControl control
    • VScaleControl: wrap ScaleControl control
  • Layer Components
    • VBackgroundLayer: wrap background layer
    • VCircleLayer: wrap circle layer
    • VFillExtrusionLayer: wrap fillextrusion layer
    • VFillLayer: wrap fill layer
    • VHeatmapLayer: wrap heatmap layer
    • VHillshadeLayer: wrap hillshade layer
    • VLineLayer: wrap line layer
    • VRasterLayer: wrap raster layer
    • VSymbolLayer: wrap symbol layer
    • VCanvasLayer: wrap canvas layer
  • Source Components
    • VGeoSource: wrap geojson source
    • VVectorSource: wrap vector source
    • VImageSource: wrap image source
    • VVideoSource: wrap video source
    • VRasterSource: wrap raster source
    • VRasterDemSource: wrap rasterdem source

Install

# use yarn
yarn add mapvue
Enter fullscreen mode Exit fullscreen mode
# use pnpm
pnpm add mapvue
Enter fullscreen mode Exit fullscreen mode

Import

Vite

import { createApp } from "vue";
import MapVue from "mapvue";
import "mapvue/dist/mapvue.css";
import App from "./App.vue";

createApp(App).use(MapVue).mount("#app");
Enter fullscreen mode Exit fullscreen mode

Use case

<script>
import { defineComponent, reactive, watch } from "vue";
import { accessToken } from "../store";

export default defineComponent({
  setup() {
    const state = reactive({
      "heatmap-color": [
        "interpolate",
        ["linear"],
        ["heatmap-density"],
        0,
        "rgba(33,102,172,0)",
        0.2,
        "rgb(103,169,207)",
        0.4,
        "rgb(209,229,240)",
        0.6,
        "rgb(253,219,199)",
        0.8,
        "rgb(239,138,98)",
        1,
        "rgb(178,24,43)",
      ],
      "heatmap-opacity": ["interpolate", ["linear"], ["zoom"], 7, 1, 9, 0],
      "heatmap-radius": ["interpolate", ["linear"], ["zoom"], 0, 2, 9, 20],
      "heatmap-intensity": ["interpolate", ["linear"], ["zoom"], 0, 1, 9, 3],
      radius: 20,
      intensity: 3,
      layout: {
        visibility: "visible",
      },
    });

    return {
      state,
      accessToken,
    };
  },
});
</script>

<template>
  <div class="container">
    <v-map
      :accessToken="accessToken"
      :options="{
        center: [-124.137343, 45.137451],
        zoom: 3,
      }"
    >
      <v-geo-source
        id="geo"
        data="https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"
      />
      <v-heatmap-layer
        id="heatmap"
        source="geo"
        :paint="{
          'heatmap-color': state['heatmap-color'],
          'heatmap-opacity': state['heatmap-opacity'],
          'heatmap-radius': state['heatmap-radius'],
          'heatmap-intensity': state['heatmap-intensity'],
        }"
        :layout="state.layout"
      />
    </v-map>
  </div>
</template>

<style scoped>
.container {
  height: 100vh;
  width: 100%;
}
</style>

Enter fullscreen mode Exit fullscreen mode

render heatmap

more examples please visiting examples

github: MapVue
docs: MapVue doc

Top comments (0)