{"id":13937992,"url":"https://github.com/phegman/vue-mapbox-gl","last_synced_at":"2026-04-01T18:22:07.645Z","repository":{"id":19737209,"uuid":"87761375","full_name":"phegman/vue-mapbox-gl","owner":"phegman","description":"A Vue.js component for Mapbox GL JS","archived":false,"fork":false,"pushed_at":"2022-12-11T04:17:01.000Z","size":1022,"stargazers_count":269,"open_issues_count":32,"forks_count":33,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-08-15T12:59:48.339Z","etag":null,"topics":["javascript","mapbox-gl-js","vue","vue2","vuejs2"],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phegman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-10T03:13:07.000Z","updated_at":"2025-04-06T19:47:20.000Z","dependencies_parsed_at":"2023-01-13T22:15:15.480Z","dependency_job_id":null,"html_url":"https://github.com/phegman/vue-mapbox-gl","commit_stats":null,"previous_names":["phegman/mapbox-gl-vue.js"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/phegman/vue-mapbox-gl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phegman%2Fvue-mapbox-gl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phegman%2Fvue-mapbox-gl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phegman%2Fvue-mapbox-gl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phegman%2Fvue-mapbox-gl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phegman","download_url":"https://codeload.github.com/phegman/vue-mapbox-gl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phegman%2Fvue-mapbox-gl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","mapbox-gl-js","vue","vue2","vuejs2"],"created_at":"2024-08-07T23:04:09.400Z","updated_at":"2026-04-01T18:22:07.626Z","avatar_url":"https://github.com/phegman.png","language":"Vue","funding_links":[],"categories":["UI Components [🔝](#readme)","Vue","UI组件","Components \u0026 Libraries","UI Components"],"sub_categories":["地图","UI Components","Map"],"readme":"# Mapbox GL JS Vue.js\n\nA simple lightweight (9kb/3kb gzipped) Mapbox GL JS Vue component.\n\n## [Demo](https://vue-mapbox-gl.peterhegman.com)\n\n- [Installation](#installation)\n- [Setup](#setup)\n- [Props](#props)\n- [Events](#map-events)\n- [Plugins](#plugins)\n- [Popups](#popups)\n- [Development](#development)\n\n## Installation\n\n### Yarn\n\n```bash\nyarn add mapbox-gl-vue\n```\n\n### NPM\n\n```bash\nnpm install mapbox-gl-vue --save\n```\n\n### [Vue CDN](https://vuejs.org/v2/guide/#Getting-Started)\n\nDownload latest `vue-mapbox-gl.min.js` from [https://github.com/phegman/vue-mapbox-gl/releases](https://github.com/phegman/vue-mapbox-gl/releases)\n\nInclude using a `\u003cscript\u003e` tag\n\n```html\n\u003cscript src=\"vue-mapbox-gl.min.js\"\u003e\u003c/script\u003e\n```\n\n### Including Mapbox GL JS\n\nThis package does not include the Mapbox GL JS and CSS files. See Mapbox GL JS installation guide here: [https://www.mapbox.com/install/js/](https://www.mapbox.com/install/js/)\n\n#### Importing Mapbox GL JS with Webpack\n\nIf you decide to include Mapbox GL JS by installing it with Yarn/NPM you should use [Shimming](https://webpack.js.org/guides/shimming/) for it to work correctly.\n\n`webpack.config.js`\n\n```js\nconst webpack = require('webpack')\n\nplugins: [\n  new webpack.ProvidePlugin({\n    mapboxgl: 'mapbox-gl',\n  }),\n]\n```\n\nProjects setup with [Vue CLI 3](https://cli.vuejs.org/):\n\n`vue.config.js`\n\n```js\nconst webpack = require('webpack')\n\nmodule.exports = {\n  configureWebpack: {\n    plugins: [\n      new webpack.ProvidePlugin({\n        mapboxgl: 'mapbox-gl',\n      }),\n    ],\n  },\n}\n```\n\n## Setup\n\nIn the file you will be including the component:\n\n```vue\n\u003cscript\u003e\nimport Mapbox from 'mapbox-gl-vue'\n\nexport default {\n  components: { Mapbox },\n}\n\u003c/script\u003e\n```\n\nIn your template block:\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv id=\"app\"\u003e\n    \u003cmapbox\n      access-token=\"your access token\"\n      :map-options=\"{\n        style: 'mapbox://styles/mapbox/light-v9',\n        center: [-96, 37.8],\n        zoom: 3,\n      }\"\n    /\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\n#### CSS\n\nCSS needs to be added for the map to show up. The `#map` container needs a height and a width. Example:\n\n```vue\n\u003cstyle\u003e\n#map {\n  width: 100%;\n  height: 500px;\n}\n\u003c/style\u003e\n```\n\n## Props\n\nVue.js Documentation [https://vuejs.org/v2/guide/components.html#Props](https://vuejs.org/v2/guide/components.html#Props)\n\n`access-token`  \n Type: `string`  \n Required: `true`\n\nYour access token is required for Mapbox to work. It can be obtained in the Mapbox Studio dashboard\n\n---\n\n`map-options`  \n Type: [MapboxOptions](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/ecb7a34d7a93504d556f3e281baa7e4d4080317e/types/mapbox-gl/index.d.ts#L252)  \n Required: `true`\n\nOverview of available Mapbox options can be found here: [https://www.mapbox.com/mapbox-gl-js/api/#map](https://www.mapbox.com/mapbox-gl-js/api/#map)\n\n`container` will default to `map` (giving the container an id of `map`). If you want to change this or use multiple map components on the same page simply set the `container` property.\n\n---\n\n`nav-control`  \n Type: [NavigationControlOptions](https://github.com/phegman/vue-mapbox-gl/blob/master/src/interfaces/navigation-control-options.interface.ts)  \n Required: `false`  \n Default: `{ show: true, position: 'top-right' }`\n\nMore information about navigation control here: [https://docs.mapbox.com/mapbox-gl-js/api/#navigationcontrol](https://docs.mapbox.com/mapbox-gl-js/api/#navigationcontrol)\n\n---\n\n`geolocate-control`  \n Type: [GeolocateControlOptions](https://github.com/phegman/vue-mapbox-gl/blob/master/src/interfaces/geolocate-control-options.interface.ts)  \n Required: `false`  \n Default: `{ show: false, position: 'top-left', options: {} }`\n\nMore information about geolocate control here: [https://docs.mapbox.com/mapbox-gl-js/api/#geolocatecontrol](https://docs.mapbox.com/mapbox-gl-js/api/#geolocatecontrol)\n\n---\n\n`scale-control`  \n Type: [ScaleControlOptions](https://github.com/phegman/vue-mapbox-gl/blob/master/src/interfaces/scale-control-options.interface.ts)  \n Required: `false`  \n Default: `{ show: false, position: 'top-left', options: {} }`\n\nMore information about scale control here: [https://docs.mapbox.com/mapbox-gl-js/api/#scalecontrol](https://docs.mapbox.com/mapbox-gl-js/api/#scalecontrol)\n\n---\n\n`fullscreen-control`  \n Type: [FullscreenControlOptions](https://github.com/phegman/vue-mapbox-gl/blob/master/src/interfaces/fullscreen-control-options.interface.ts)  \n Required: `false`  \n Default: `{ show: false, position: 'top-right' }`\n\nMore information about full screen control here: [https://docs.mapbox.com/mapbox-gl-js/api/#fullscreencontrol](https://docs.mapbox.com/mapbox-gl-js/api/#fullscreencontrol)\n\n---\n\n`attribution-control`  \n Type: [AttributionControlOptions](https://github.com/phegman/vue-mapbox-gl/blob/master/src/interfaces/attribution-control-options.interface.ts)  \n Required: `false`  \n Default: `{ show: false, position: 'top-right' }`\n\nMore information about full screen control here: [https://docs.mapbox.com/mapbox-gl-js/api/#attributioncontrol](https://docs.mapbox.com/mapbox-gl-js/api/#attributioncontrol)\n\n#### Example\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv id=\"app\"\u003e\n    \u003cmapbox\n      access-token=\"your access token\"\n      :map-options=\"{\n        style: 'mapbox://styles/mapbox/light-v9',\n        center: [-96, 37.8],\n        zoom: 3,\n      }\"\n      :geolocate-control=\"{\n        show: true,\n        position: 'top-left',\n      }\"\n      :scale-control=\"{\n        show: true,\n        position: 'top-left',\n      }\"\n      :fullscreen-control=\"{\n        show: true,\n        position: 'top-left',\n      }\"\n    /\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\n## Map Events\n\n`@map-init` : This event is fired when the map is initialized. It can be used to integrate [plugins](https://docs.mapbox.com/mapbox-gl-js/plugins/).\n\nAll Mapbox GL JS events are available for use. List of events here: [https://docs.mapbox.com/mapbox-gl-js/api/#map.event:resize](https://docs.mapbox.com/mapbox-gl-js/api/#map.event:resize)\n\nMap events can be used by adding the `@map-` prefix to the beginning of the Mapbox event name. For example for the `click` event `@map-click` can be used. All events are passed the mapboxgl [Map](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/ecb7a34d7a93504d556f3e281baa7e4d4080317e/types/mapbox-gl/index.d.ts#L60) instance as the first parameter and, if the event has one, the [MapboxEvent](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/ecb7a34d7a93504d556f3e281baa7e4d4080317e/types/mapbox-gl/index.d.ts#L1117) as the second parameter.\n\nFor events that support specifying a `layerId` as documented here [https://docs.mapbox.com/mapbox-gl-js/api/#map#on](https://docs.mapbox.com/mapbox-gl-js/api/#map#on) the `layerId` can be specified by using a colon to separate the event from the `layerId`. For example if you have a layer with an id of `points` the `click` event can be registered like so: `@map-click:points`\n\n## Geolocation Events\n\nGeolocation events are available for use by adding the `@geolocate-` prefix to the beginning of the Mapbox event name. A list of Geolocation events can be found here: [https://docs.mapbox.com/mapbox-gl-js/api/#geolocatecontrol.event:geolocate](https://docs.mapbox.com/mapbox-gl-js/api/#geolocatecontrol.event:geolocate)\n\n#### Example\n\n`App.vue`\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv id=\"app\"\u003e\n    \u003cmapbox\n      access-token=\"your access token\"\n      :map-options=\"{\n        style: 'mapbox://styles/mapbox/light-v9',\n        center: [-96, 37.8],\n        zoom: 3,\n      }\"\n      :geolocate-control=\"{\n        show: true,\n        position: 'top-left',\n      }\"\n      @map-load=\"loaded\"\n      @map-zoomend=\"zoomend\"\n      @map-click:points=\"clicked\"\n      @geolocate-error=\"geolocateError\"\n      @geolocate-geolocate=\"geolocate\"\n    /\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport Mapbox from 'mapbox-gl-vue'\n\nexport default {\n  components: { Mapbox },\n  methods: {\n    loaded(map) {\n      map.addLayer({\n        id: 'points',\n        type: 'symbol',\n        source: {\n          type: 'geojson',\n          data: {\n            type: 'FeatureCollection',\n            features: [\n              {\n                type: 'Feature',\n                geometry: {\n                  type: 'Point',\n                  coordinates: [-77.03238901390978, 38.913188059745586],\n                },\n                properties: {\n                  title: 'Mapbox DC',\n                  icon: 'monument',\n                },\n              },\n              {\n                type: 'Feature',\n                geometry: {\n                  type: 'Point',\n                  coordinates: [-122.414, 37.776],\n                },\n                properties: {\n                  title: 'Mapbox SF',\n                  icon: 'harbor',\n                },\n              },\n            ],\n          },\n        },\n        layout: {\n          'icon-image': '{icon}-15',\n          'text-field': '{title}',\n          'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],\n          'text-offset': [0, 0.6],\n          'text-anchor': 'top',\n        },\n      })\n    },\n    zoomend(map, e) {\n      console.log('Map zoomed')\n    },\n    clicked(map, e) {\n      const title = e.features[0].properties.title\n      console.log(title)\n    },\n    geolocateError(control, positionError) {\n      console.log(positionError)\n    },\n    geolocate(control, position) {\n      console.log(\n        `User position: ${position.coords.latitude}, ${position.coords.longitude}`\n      )\n    },\n  },\n}\n\u003c/script\u003e\n\n\u003cstyle\u003e\n#map {\n  width: 100%;\n  height: 500px;\n}\n\u003c/style\u003e\n```\n\n## Plugins\n\nPlugins ([https://www.mapbox.com/mapbox-gl-js/plugins/](https://www.mapbox.com/mapbox-gl-js/plugins/)) can be integrated using the `map-init` event that is fired when Mapbox is initialized. Below is an example:\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv id=\"app\"\u003e\n    \u003cmapbox\n      access-token=\"your access token\"\n      :map-options=\"{\n        style: 'mapbox://styles/mapbox/light-v9',\n        center: [-96, 37.8],\n        zoom: 3,\n      }\"\n      :geolocate-control=\"{\n        show: true,\n        position: 'top-left',\n      }\"\n      :scale-control=\"{\n        show: true,\n        position: 'top-left',\n      }\"\n      :fullscreen-control=\"{\n        show: true,\n        position: 'top-left',\n      }\"\n      @map-init=\"mapInitialized\"\n    /\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport Mapbox from 'mapbox-gl-vue'\n\nexport default {\n  components: { Mapbox },\n  methods: {\n    initialized(map) {\n      const Draw = new MapboxDraw()\n      map.addControl(Draw)\n    },\n  },\n}\n\u003c/script\u003e\n\n\u003cstyle\u003e\n#map {\n  width: 100%;\n  height: 500px;\n}\n\u003c/style\u003e\n```\n\n## Popups\n\nPopups can be a bit tricky if you are trying to use Vue directives inside the popup content. This is because the popups are added to the DOM by Mapbox and not compiled by Vue. See below for one approach to solving this problem.\n\n`App.vue`\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv id=\"app\"\u003e\n    \u003cmapbox\n      access-token=\"your access token\"\n      :map-options=\"{\n        style: 'mapbox://styles/mapbox/light-v9',\n        center: [-96, 37.8],\n        zoom: 3,\n      }\"\n      @map-load=\"loaded\"\n      @map-click:points=\"clicked\"\n      @map-mouseenter:points=\"mouseEntered\"\n      @map-mouseleave:points=\"mouseLeft\"\n    /\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport Mapbox from 'mapbox-gl-vue'\nimport PopupContent from './PopupContent.vue'\n\nexport default {\n  components: { Mapbox },\n  methods: {\n    loaded(map) {\n      map.addLayer({\n        id: 'points',\n        type: 'symbol',\n        source: {\n          type: 'geojson',\n          data: {\n            type: 'FeatureCollection',\n            features: [\n              {\n                type: 'Feature',\n                geometry: {\n                  type: 'Point',\n                  coordinates: [-77.03238901390978, 38.913188059745586],\n                },\n                properties: {\n                  title: 'Mapbox DC',\n                  icon: 'monument',\n                },\n              },\n              {\n                type: 'Feature',\n                geometry: {\n                  type: 'Point',\n                  coordinates: [-122.414, 37.776],\n                },\n                properties: {\n                  title: 'Mapbox SF',\n                  icon: 'harbor',\n                },\n              },\n            ],\n          },\n        },\n        layout: {\n          'icon-image': '{icon}-15',\n          'text-field': '{title}',\n          'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],\n          'text-offset': [0, 0.6],\n          'text-anchor': 'top',\n        },\n      })\n    },\n    clicked(map, e) {\n      if (e.features) {\n        const coordinates = e.features[0].geometry.coordinates.slice()\n\n        // Ensure that if the map is zoomed out such that multiple\n        // copies of the feature are visible, the popup appears\n        // over the copy being pointed to.\n        while (Math.abs(e.lngLat.lng - coordinates[0]) \u003e 180) {\n          coordinates[0] += e.lngLat.lng \u003e coordinates[0] ? 360 : -360\n        }\n\n        new mapboxgl.Popup()\n          .setLngLat({ lng: coordinates[0], lat: coordinates[1] })\n          .setHTML('\u003cdiv id=\"vue-popup-content\"\u003e\u003c/div\u003e')\n          .addTo(map)\n\n        new PopupContent({\n          propsData: { feature: e.features[0] },\n        }).$mount('#vue-popup-content')\n      }\n    },\n    mouseEntered(map) {\n      map.getCanvas().style.cursor = 'pointer'\n    },\n    mouseLeft(map) {\n      map.getCanvas().style.cursor = ''\n    },\n  },\n}\n\u003c/script\u003e\n\n\u003cstyle\u003e\n#map {\n  width: 100%;\n  height: 500px;\n}\n\u003c/style\u003e\n```\n\n`PopupContent.vue`\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv\u003e\n    \u003ch3\u003e{{ feature.properties.title }}\u003c/h3\u003e\n    \u003cbutton @click=\"popupClicked\"\u003eLearn more\u003c/button\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport Vue from 'vue'\nexport default Vue.extend({\n  props: {\n    feature: {\n      required: true,\n      type: Object,\n    },\n  },\n  methods: {\n    popupClicked() {\n      alert('Learn more clicked')\n    },\n  },\n})\n\u003c/script\u003e\n```\n\n## Development\n\n### Install dependencies\n\n```bash\nyarn install\n```\n\n### Start development server\n\nThis will start a dev server with [HMR](https://webpack.js.org/guides/hot-module-replacement/) at `localhost:8080`.\n\n```bash\nACCESS_TOKEN=yourAccessToken yarn dev\n```\n\n### Linting\n\nPlease make sure all your code passes linting before opening a PR.\n\n```bash\nyarn lint\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphegman%2Fvue-mapbox-gl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphegman%2Fvue-mapbox-gl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphegman%2Fvue-mapbox-gl/lists"}