GithubHelp home page GithubHelp logo

vue-leaflet / vue-leaflet Goto Github PK

View Code? Open in Web Editor NEW
701.0 16.0 107.0 1.45 MB

vue-leaflet compatible with vue3

License: MIT License

JavaScript 2.09% Vue 58.76% HTML 0.24% TypeScript 38.90%
vue3 leaflet vue-leaflet hacktoberfest

vue-leaflet's Introduction

vue-leaflet

Vue-leaflet, written and compatible with Vue 3!

This is a Beta version! And may yet be unstable! If you want to help, please reach out in an issue or on discord, or join the discussions.

What works

  • LCircle
  • LCircleMarker
  • LControl
  • LControlAttribution
  • LControlLayers
  • LControlScale
  • LControlZoom
  • LFeatureGroup
  • LGeoJson
  • LIcon
  • LImageOverlay
  • LMap
  • LMarker
  • LPolygon
  • LPolyline
  • LPopup
  • LRectangle
  • LTileLayer
  • LTooltip
  • LWmsTileLayer

Note that unlike the Vue 2 version, this library is fully compatible with SSR.

Installation

yarn add @vue-leaflet/vue-leaflet leaflet

or

npm i -D @vue-leaflet/vue-leaflet leaflet

Usage

Until the complete documentation is ready, please check the component playground examples or the demo project for usage with Vue 3. Most component props mimic the vanilla Leaflet options as closely as possible, and generally remain the same as in their Vue2Leaflet counterparts.

Quickstart

<template>
  <div style="height:600px; width:800px">
    <l-map ref="map" v-model:zoom="zoom" :center="[47.41322, -1.219482]">
      <l-tile-layer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        layer-type="base"
        name="OpenStreetMap"
      ></l-tile-layer>
    </l-map>
  </div>
</template>

<script>
import "leaflet/dist/leaflet.css";
import { LMap, LTileLayer } from "@vue-leaflet/vue-leaflet";

export default {
  components: {
    LMap,
    LTileLayer,
  },
  data() {
    return {
      zoom: 2,
    };
  },
};
</script>

<style></style>

Component playground

To see the component playground in action, clone this repo and run the local devserver, then visit http://127.0.0.1:5173,

git clone https://github.com/vue-leaflet/vue-leaflet.git
cd vue-leaflet
yarn
yarn dev

Server-side rendering (SSR)

Note that while the vue-leaflet library has the option of enabling SSR, Leaflet itself does not.

N.B. Using import L from "leaflet" or import { ... } from "leaflet" can lead to unexpected errors.

To provide server-side rendering and tree-shaking capabilities, vue-leaflet can be configured to use async imports from the Leaflet ESM, by disabling the useGlobalLeaflet option on the map component, <l-map :useGlobalLeaflet="false">.

This can lead to issues when importing additional methods from Leaflet, because the two instances of the Leaflet classes are technically no longer the same. See Issue 48 for more.

To avoid these issues, import any Leaflet methods asynchronously in response to the LMap component's @ready event:

<template>
  <div style="height:600px; width:800px">
    <p>vue-leaflet SSR Demo</p>
    <l-map :useGlobalLeaflet="false">
      <l-geo-json :geojson="geojson" :options="geojsonOptions" />
    </l-map>
  </div>
</template>

<script>
// DON'T load Leaflet components here!
// Its CSS is needed though, if not imported elsewhere in your application.
import "leaflet/dist/leaflet.css"
import { LMap, LGeoJson } from "@vue-leaflet/vue-leaflet";

export default {
  components: {
    LMap,
    LGeoJson,
  },
  data() {
    return {
      geojson: {
        type: "FeatureCollection",
        features: [
          // ...
        ],
      },
      geojsonOptions: {
        // Options that don't rely on Leaflet methods.
      },
    };
  },
  async beforeMount() {
    // HERE is where to load Leaflet components!
    const { circleMarker } = await import("leaflet/dist/leaflet-src.esm");

    // And now the Leaflet circleMarker function can be used by the options:
    this.geojsonOptions.pointToLayer = (feature, latLng) =>
      circleMarker(latLng, { radius: 8 });
    this.mapIsReady = true;
  },
};
</script>

vue-leaflet's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-leaflet's Issues

Map vue is blurred and unable to zoom in past level 18

Hi All

I am not sure if this has been picked up before, cant see any reference here specifically but it does look like an issue that has occurred before (Leaflet/Leaflet#6069) in the vanilla leaflet library, but using vue-leaflet seems to result in a blurry may that can zoom in higher then level 18. Please see the two comparison maps attached.

If anyone know where to start to resolve this, I can attempt a PR and try to resolve, other then that I am more then happy to volunteer as a tester.

The images below were from a 1080p screen, not a retina display.

vue-leaflet
pure-leaflet

Thanks in advance
parkb

[Component] LFeatureGroup

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Error when changing zoom levels on a map that has layers with tooltips

I have a Map containing some geojson data. It looks a little like this:

<l-map>
        <l-tile-layer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        ></l-tile-layer>

        <l-geo-json :geojson="geojson" :options="geojsonOptions"></l-geo-json>
</l-map>

With as script code something like this (omitting the loading of the geojson):

<script setup>
const onEachFeature = (feature, layer) => {
  layer.on({
    click: (e) => onAreaClick(e, layer),
  });
  layer.bindTooltip("Hello", {});
};

let geojsonOptions = {
  onEachFeature: onEachFeature,
};

const onAreaClick = async (e, layer) => {
  map.fitBounds(layer.getBounds(), { animate: true });
};
</script>

Clicking on an area gives the following error:

Uncaught (in promise) TypeError: this._map is null
    _updatePosition Tooltip.js:181
    fire Events.js:190
    _move Map.js:1241
    _resetView Map.js:1197
    setView Map.js:206
    fitBounds Map.js:295
    onAreaClick LeafletMap.vue:151
   ...

When I remove bindTooltip, the error goes away. But of course, then I have no tooltip. If I remove the fitBounds, I can click on an area all I want and the function is nicely executed without errors. But if course, it then doesn't fit to bounds.

timing issue - geojson data sometimes not loading correctly

Hello, I am a quite newbie on github and vue3, so I say sorry in advance if this is not the rightr way to ask for help.
Maybe I have a similar issue as discussed in #48 that sometimes the leaflet code from leaflet/src... and sometimes from @vue-leaflet/vue-leaflet is loaded.
My error is a different one in the GEOJson module responding with a strange ("not a valid geojson") - but I simply refresh the page and then it works - then again not, so the geojson file is not the culprit (and I validated the file with geojson linters).

I also know where my problem lies, I think.
I am using
import { LMap, LTileLayer, LGeoJson } from "@vue-leaflet/vue-leaflet"; (as explained in the demo-project, I think this is outdated)
whereas I should use (as explained in the readme) :
import { LMap, LTileLayer, LGeoJson } from "./../../components";
But this gives:
Failed to resolve import "./../../components"

I am using vite and vue3 (with the composition API) for the first time and this seems to be a relative path import issue.
Sadly vite does not have a "root" path "@/..." .

So how can I adapt my code to make it work ? This is my code:

<template>
  <div v-if="loaded" class="container-fluid vh-100">
    <div class="row vh-100">
      <div class="col-9">
        <l-map :zoom="7" :center="[51.4, 9.0]">
          <l-geo-json
            v-if="loaded"
            :geojson="geojson"
            :options="geojsonOptions"
          />
          <l-tile-layer
            url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
          ></l-tile-layer>
        </l-map>
      </div>

      <div class="col-3">
        <h3>Info</h3>
        Landkreis:
        <span> {{ lkName }}</span>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, onMounted, watch } from "vue";
//import { LMap, LTileLayer, LGeoJson } from "@vue-leaflet/vue-leaflet";
import { LMap, LTileLayer, LGeoJson } from "./../../components";
import "leaflet/dist/leaflet.css";
export default {
  components: {
    LMap,
    LTileLayer,
    LGeoJson,
  },

  data() {
    return {
      zoom: 6,
      geojsonOptions: {
        onEachFeature: this.onEachFeature,
        style: this.setGeoJsonStyle,
      },
      loaded: false,
      lkName: "",
    };
  },

  mounted() {
    this.loaded = true;
  },
  watch: {
    selectedLayer(o, n) {
      console.log(o, n, this.selectedLayer);
    },
    hoveredLayer(o, n) {
      console.log(o, n, this.hoveredLayer);
      this.lkName = this.hoveredLayer.feature.properties.name;
    },
    geoJsonloaded(o, n) {
      console.log("loaded!");
      this.loaded = this.geoJsonloaded;
    },
  },

  setup() {
    const defaultStyle = {
      weight: 1,
      color: "#808080",
    };

    const hoverStyle = {
      color: "#333",
      weight: 2,
    };

    const selectedStyle = {
      color: "#cc0000",
      weight: 2,
    };

    const selectedLayer = ref(null);
    const hoveredLayer = ref(null);
    const geoJsonloaded = ref(false);
    const geojson = ref({});
    const getGeojson = async () => {
      var myHeaders = new Headers();
      myHeaders.append("pragma", "no-cache");
      myHeaders.append("cache-control", "no-cache");
      myHeaders.append("Content-Type", "application/json");
      myHeaders.append("Accept", "application/json");
      var myInit = {
        method: "GET",
        headers: myHeaders,
      };
      var myRequest = new Request("landkreise_rki.geojson");
      fetch(myRequest, myInit)
        .then((response) => response.json())
        .then(function (geojson_data) {
          console.log(geojson_data);
          geojson.value = geojson_data;
          geoJsonloaded.value = true;
          console.log(mylog.value);
          return geojson_data;
        });
    };

    const whenClicked = (e) => {
      //console.log("whenClicked", e);
      var layer = e.target;
      if (selectedLayer.value != null) {
        selectedLayer.value.setStyle(defaultStyle);
        if (
          selectedLayer.value.feature.properties.id ==
          layer.feature.properties.id
        ) {
          selectedLayer.value = null;
          return;
        }
      }
      selectedLayer.value = layer;
      console.log(selectedLayer.value);
      layer.setStyle(selectedStyle);
    };

    const whenMouseover = (e) => {
      //console.log("whenMouseover", e);
      var layer = e.target;
      hoveredLayer.value = layer;
      if (selectedLayer.value != null) {
        if (
          selectedLayer.value.feature.properties.id ==
          layer.feature.properties.id
        ) {
          return;
        }
      }
      layer.setStyle(hoverStyle);
    };

    const whenMouseout = (e) => {
      console.log("whenMouseout", e);
      var layer = e.target;
      if (selectedLayer.value != null) {
        console.log(selectedLayer);
        if (
          selectedLayer.value.feature.properties.id ==
          layer.feature.properties.id
        ) {
          return;
        }
      }
      layer.setStyle(defaultStyle);
    };

    const onEachFeature = (feature, layer) => {
      //console.log(feature, layer);
      //bind click
      layer.on({
        click: whenClicked,
        mouseover: whenMouseover,
        mouseout: whenMouseout,
      });
    };

    const setGeoJsonStyle = (e) => {
      return { color: "#808080", weight: 1 };
    };

    onMounted(getGeojson); // on `mounted` call `getUserRepositories`

    return {
      geojson,
      getGeojson,
      onEachFeature,
      setGeoJsonStyle,
      whenClicked,
      selectedLayer,
      hoveredLayer,
      geoJsonloaded,
      mylog,
    };
  },
};
</script>
<style>
#map {
  position: relative;
  width: 100%;
  height: 100%;
  left: 0%;
  top: 0%;
}
</style>

[Component] LControlScale

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Integration with Leaflet Geoman plugin

Hello, thanks for all your hard work.

I have been doing some prototypes using the Vue 3 repo recently and everything was working perfect until I wanted to install https://github.com/geoman-io/leaflet-geoman .

This plugin auto install itself on the L constant when it it's imported. The current Vue 3 components for what I can see are dynamically importing leafleat so I haven't found a way to make the plugin be able to reference the same leaflet map object that the component is using.

I try doing things similar to geoman-io/leaflet-geoman#580 but given the new way that the Vue 3 library works with leaflet it's not working for me. Any help is very much appreciated! thanks

Tile layer minZoom and maxZoom

Just started using vue-leaflet and it works great! (:
I couldn't set the minZoom and maxZoom of a l-tile-layer, although it works nicely with the l-map.
I went through the code and this seems to be the desired behaviour. I used however to set these options to be able to load more images as I zoom in... what do?

Playground the l-marker is draggable only once

Hi!

In the Playground, inside the Tooltips and Popups components, I noticed that after dragging the draggable l-marker for the first time it's not possible to drag it again and so the map.

If I zoom-in or zoom-out the draggable l-marker return to the starting position and it's not draggable (neither the map) unless the page is refreshed.

Do you know if the issue could be related to the instance of the component in the playground?

Thank you.

[Component] LPopup

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

[Component] LCircleMarker

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

[Component] LGridLayer

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

[Component] LIcon

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Could not find a declaration file for module '@vue-leaflet/vue-leaflet'

I'm trying to import the module by I got

Could not find a declaration file for module '@vue-leaflet/vue-leaflet'. '/media/khaledomara/Data/Work/00 - EgyProTech/00 - GitLab/03- Android Apps/ePowerDMS Drivers/ePowerDMS-Driver/node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.cjs.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/vue-leaflet__vue-leaflet` if it exists or add a new declaration (.d.ts) file containing `declare module '@vue-leaflet/vue-leaflet';`Vetur(7016)

I'm using typescript

[Component] LRectangle

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Error loading Polylines

Hi All

It looks the issue with polylines in vue2leaflet is also in vue-leaflet, which occurs with the example in the src/playground for polylines and geoJson which include a polyline.

vue-leaflet/Vue2Leaflet#144

Was there an easy fix for this after? Also the log from the console is below.

Thanks in advance
Parkb83

leaflet-src.esm.js?6bb3:1042 Uncaught (in promise) TypeError: Cannot read property 'x' of undefined
    at Proxy.intersects (leaflet-src.esm.js?6bb3:1042)
    at Proxy._clipPoints (leaflet-src.esm.js?6bb3:8317)
    at Proxy._update (leaflet-src.esm.js?6bb3:8362)
    at Proxy._reset (leaflet-src.esm.js?6bb3:7861)
    at Proxy.onAdd (leaflet-src.esm.js?6bb3:7806)
    at Proxy._layerAdd (leaflet-src.esm.js?6bb3:6561)
    at Proxy.whenReady (leaflet-src.js?e11e:4428)
    at Proxy.addLayer (leaflet-src.js?e11e:6629)
    at RefImpl.addLayer (LMap.vue?680d:257)
    at wrapper (utils.js?9f0a:88)

bounds are not of type LatLngBounds.

fitBounds() does not work because bounds are not of type LatLngBounds.

Reproduce:

...
<l-map ref="map"></l-map>
....
...
this.map = this.$refs.map.leafletObject
this.map.fitBounds(map.getBounds());
...

This issue happens when accessing toLatLngBounds() through fitBounds() accessed from map ref

fitBounds(bounds) {
          blueprint.mapRef.fitBounds(bounds, {  
            animate: this.noBlockingAnimations ? false : null,
          });
        },

|
\/

fitBounds: function (bounds, options) {
	bounds = toLatLngBounds(bounds);
	if (!bounds.isValid()) {
		throw new Error('Bounds are not valid.');
	}
	var target = this._getBoundsCenterZoom(bounds, options);
	return this.setView(target.center, target.zoom, options);
}

|
\/

function toLatLngBounds(a, b) {
	console.log('b = ', b) //undefined
	console.log('a = ', a) //LatLngBounds
	console.log('a.constructor.name = ', a.constructor.name) //Object
	console.log('typeof a =', typeof a) // Object
	console.log('toLatLng instance = ', LatLngBounds) //function of LatLngBounds
	if (a instanceof LatLngBounds) {  // here bounds are of instance of Object but it should be LatLngBounds !!!!!!!!!!!!!!!!!!!!!!!!!!
		return a;
	}
	return new LatLngBounds(a, b);
}

But this issue is not happening when accessing toLatLngBounds() through imported 'leaflet' package

import L from 'leaflet'
...
app.use(L);
...
L.toLatLngBounds(bounds)  // here bounds are of instance LatLngBounds therefore it will return actual latlng

P.S.

Mainly tested on 0.1.2 because 0.2.0/0.3.0 has this issue #47 but also tried 0.3.0 (same)

[Component] LControlAttribution

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

0.2.0 Issue with mapObject/leafletObject, Lpopup not working

reproduction repo here: https://github.com/Saltibarsciai/vue3-leaflet-demo/blob/main/src/App.vue
PS. it's the same repo I used to show issue of icon not changing via $ref on marker

video here: https://screenrec.com/share/2OKdZ0HazN

Quick summary:

When having $ref on it no longer has mapObject so such things as scrollWheelZoom.disable(); and zoomControl.remove() on map ref can't be done, therefore adding custom stuff to map, for example new zoom L.control.zoom({position: 'topright'}).addTo(this.map); won't work.

I saw new attribute on 0.2.0 leafletObject but it can't be reached on mounted no matter how much next ticks I do. (tried 5)

[Component] LLayerGroup

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Use Rollup to build ESM package

Currently for simplicity vue-leaflet is built with webpack, but this is not efficient in term of three shaking and bundle size.
We need to re-introduce rollup and build with it

Marker Cluster for vue3 leaflet?

Is there any package like vue2-leaflet-markercluster that works with this version of vue-leaflet?
I have searched but no luck.

[Component] LGeoJson

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Restore docs

Vue2Leaflet has extensive docs, that are the backbone of the success of the plugin, they are generated with VueDocGen, we need to restore the doc generation mechanism and re publish them

[Component] LTooltip

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

can't change markers/icons with refs

Message from discord:

vue2-leaflet and it was like so: this.$refs.mapRef.$refs[markerRef][0].mapObject._icon.attributes.src.value = '/assets/img/icons/map_icon_orange.png' in vue-leaflet/vue-leaflet it seems that on map ref mapObject is replaced by leafletObject and marker ref or icon ref doesn't have neither mapObject nor leafletObject

Also in vue2-leaflet map ref would have more nested refs and I could get my icons from there, for example this.$refs.map.$refs.marker1, on vue-leaflet/vue-leaflet only nested ref in map is root, so only item: this.$refs.map.$refs.root which is not needed, better to have actual refs that are in  l-map slots

I found a way to change icons  with vue-leaflet/vue-leaflet by accessing map ref, then to leafletObject, then to _targets. Problem is that I have dynamic markers and target numbers are random, it's good when there's only one target on marker ref, but on map ref there will be tons of them.

So I'd see few issues

  1. Ref on map doesn't expose object of refs used inside map as it did in vue2 (it does expose $refs{} but it only has root, no other refs)
  2. MapObject is no longer exposed except for map, So it's now not possible to access _icon attribute or any other.

Plan from discord:

  1. To expose leafletObject (renamed after 0.2.0 version from mapObject) on LMarker/LIcon

Using LWmsTileLayer

Hi, great library and thanks for all of you hard work!

Is there an example for LWmsTileLayer available, I think I must be doing something wrong when passing through the layer name as an option.

Thanks
Brett

[Component] LImageOverlay

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

leaflet-editable and leaflet.markercluster

  1. Do you plan to add functionality of leaflet-editable and leaflet.markercluster plugins?
  2. Did you intentionally make this package incompatible with vue2-leaflet so that existing plugins for it would fall off?

[Component] LPolyline

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Smooth zoom

Thanks for your work!
I noticed zooming the map is different than vue2-leaflet. There is no smooth transition between each zoom level.
Each tiles flash with a gray overlay. In vue2-leaflet, the tiles scale up or down and fade with the next zoom level.
I think it's not a normal behavior...

TypeError: latLng is not a function

Hi, I'm getting this issue when trying to update the position of a marker:

vue-leaflet.esm.js?5afd:729 Uncaught (in promise) TypeError: latLng is not a function
    at Object.setLatLng (vue-leaflet.esm.js?5afd:729)
    at eval (vue-leaflet.esm.js?5afd:95)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:154)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:163)
    at Array.job (runtime-core.esm-bundler.js?5c40:2012)
    at flushPreFlushCbs (runtime-core.esm-bundler.js?5c40:306)
    at updateComponentPreRender (runtime-core.esm-bundler.js?5c40:4160)
    at componentEffect (runtime-core.esm-bundler.js?5c40:4091)
    at Object.reactiveEffect [as update] (reactivity.esm-bundler.js?a1e9:42)
    at updateComponent (runtime-core.esm-bundler.js?5c40:4006) 

at this line: https://github.com/vue-leaflet/vue-leaflet/blob/master/src/functions/marker.js#L63

I also get this warning when loading the page:
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: injection "latLng" not found.

Am I doing something wrong?

Component emitted event "ready" but it is neither declared in the emits option nor as an "onReady" prop.

Hello,

I have this warning :

Component emitted event "ready" but it is neither declared in the emits option nor as an "onReady" prop.

My code :

<l-map
  v-model="zoom"
  v-model:zoom="zoom"
  :center="[latitude, longitude]"
>
    <l-tile-layer
      url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    ></l-tile-layer>
</l-map>

I really have the minimum code and I have this warning. It seems to miss the declaration of the event in one of the components of the library. Can you fix it please?

Valentin

l-control-layers

Just an observation, when using l-control-layers, is it normal for all of the base layers to be 'active' when the map is first loaded? Looking at the network tab, when panning/zooming all base layers load. It isn't until a layer is selected, that just that layer is loaded when panning/zooming.

Thanks
parkb83

[Component] LControlZoom

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

[Component] LControl

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Typescript support

@DonNicoJs Maybe too early to start a conversation about it since you have just started the implementation, but would it make sense to write the whole codebase in Typescript?
Since Vue 3 will basically have better support for type checking especially in the templates.

vue-leaflet doesn't work when built with Vite

Bug description

When building a Vue app with Vite, the following error is displayed in the browser's console as soon as the LMap component is created:

Uncaught (in promise) ReferenceError: require is not defined
    at resetWebpackIcon (vue-leaflet.js:68)
    at vue-leaflet.js:1085

How to reproduce

Run:

npm init vite-app temp --template vue
cd temp
npm i
npm i leaflet @vue-leaflet/vue-leaflet

Put the following code into src/App.vue:

<template>
  <l-map/>
</template>
<script>
import {LMap} from "@vue-leaflet/vue-leaflet"
export default {components: {LMap}}
</script>

Then run npm run dev and open the app in the browser.

Alternative approach to Leaflet props and events

@DonNicoJs last night I pushed some changes to my fork's dev branch that use context.attrs (composition api's combination of this.$attrs and this.$listeners) to allow the majority of the props and events to be set on the underlying Leaflet objects without having to define props on the Vue components, wrap them into an object, and pass that through.

I haven't pushed it very far yet so there might be a good reason not to use this sort of approach that I haven't thought of or encountered yet, but you can see initially at least how little code and effort is required to get LMap, LTileLayer, and LMarker up and running. I'm interested in your thoughts on the approach.

Outline

The basic idea is to get the non-prop attributes passed to the component in setup(props, { attrs }), and split them into two sets: one whose names start with "on" and whose values are functions, and another with all the rest. The names of the first set are then changed slightly by removing "on" from the beginning and converting the first letter to lowercase. For example, if

attrs == {
  onZoomend: fn,
  maxZoom: 16,
  center: [0, 0]
}

then we end up with

listenersSet = { zoomend: fn }; // Set 1
optionsSet = { maxZoom: 16, center: [0, 0] }; // Set 2

(If the component is used with <l-map @zoomend="fn" ...>, then the composition api automatically converts that to onZoomend: fn in the attrs object. So to use the same event names that Leaflet users expect, we just have to undo that change.)

Now it's just a matter of instantiating a new Leaflet object, using standard Vue props for any non-options constructor arguments, and passing the second set of options down. For example,

layerMarker = L.marker(props.latLng, optionsSet);

and using Leaflet's DomEvent to bind its event map,

DomEvent.on(layerMarker, listenersSet);

Advantages

  • Significantly less code, both to write and maintain.
  • Handles any new Leaflet options and events seamlessly, should future versions include them, and doesn't add code that expects or requires any particular Leaflet version in either direction.
  • ...?

Disadvantages

  • Doesn't provide the user with autocomplete options for prop or event names in their IDE (although Vue 3's emits property would allow getting around that somewhat, though without the future-proofing advantage above).
  • Doesn't allow validation functionality for most Leaflet options.
  • ...?

[Component] LCircle

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

[Component] LwmsTileLayer

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Getting started w/ Nuxt

Hey all, I'm trying to get this up and run using NuxtJs, but I can't seem to get things working. I created a basic component that just uses a l-map with the following code:

<template>
  <l-map style="height: 50vh" />
</template>

<script>
import "leaflet/dist/leaflet.css";
import { LMap } from "@vue-leaflet/vue-leaflet";

export default {
  components: {
    LMap,
  },
};
</script>

However, upon running I get the following console output, and a error message displayed in my browser saying that vue.h is not a function

 ERROR  [Vue warn]: Error in render: "TypeError: vue.h is not a function"                                                                         

found in

---> <LMap> at src/components/LMap.vue
       <Map> at components/Map.vue
         <Pages/index.vue> at pages/index.vue
           <Nuxt>
             <Layouts/default.vue> at layouts/default.vue
               <Root>
 WARN  Compiled with 12 warnings                                                                                                  friendly-errors 21:43:48
 
WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48
"export 'computed' was not found in 'vue'                                                                                         friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48
 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48
"export 'h' was not found in 'vue'                                                                                                friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48
 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'inject' was not found in 'vue'                                                                                           friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'nextTick' was not found in 'vue'                                                                                         friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'onBeforeUnmount' was not found in 'vue'                                                                                  friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'onMounted' was not found in 'vue'                                                                                        friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'onUnmounted' was not found in 'vue'                                                                                      friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'provide' was not found in 'vue'                                                                                          friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'reactive' was not found in 'vue'                                                                                         friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'ref' was not found in 'vue'                                                                                              friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'render' (imported as 'render$3') was not found in 'vue'                                                                  friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

 WARN  in ./node_modules/@vue-leaflet/vue-leaflet/dist/vue-leaflet.esm.js                                                         friendly-errors 21:43:48

"export 'watch' was not found in 'vue'                                                                                            friendly-errors 21:43:48
                                                                                                                                  friendly-errors 21:43:48

Anyone have any suggestions, or is there something obvious that I'm missing?

Thanks!

[Component] LPolygon

To migrate a component from Vue2Leaflet to vue-leaflet (and so from vue2 to vue3) follow this steps:

  • create a function in functions folder called componentName.js (without the L)
  • check what mixins are used in the vue2 version and see if all the relative composition API function are present, if not they need to be created
    • Each composition API function needs to export two objects: props and setup, see marker.js for an example.
  • create a component in components folder called LComponentName.vue
  • follow the guide of LMarker.vue to understand how to deal with reactivity, dynamic import and SSR
  • add and test the component inside playground.vue

Is there a way to use the .getBounds() function?

I need to get the bounds of a polyline but cannot manage to access the .getbounds() function.

This is what I have:

import { LMap,  LTileLayer,  LPolyline } from "@vue-leaflet/vue-leaflet";

export default {
  components: {    LMap,    LTileLayer,   LPolyline,  },

methods: {
    doSomethingOnReady() {
      this.map = this.$refs.map.leafletObject;
      this.track = this.$refs.track.leafletObject;
      this.map.fitBounds(this.track.getBounds());
    },
  },

Any idea what I'm missing?

L-map calls leaflet.destroy twice - gets unmounted twice -

In my Vue SPA you can show and hide the map, conditioned by a Vue v-if clause, which removes the div when falsy if I understand correctly.

Whenever I hide the map, the remove() leaflet method is automatically called and I get a "Map container is being reused by another instance" error which, in leaflet code, means that this condition in map remove method is not satisfied:

if (this._containerId !== this._container._leaflet_id) {
throw new Error('Map container is being reused by another instance');
}

I have replicated my map component without vue-leaflet, only using leaflet and the L class, and everything worked fine, I only get the problem when using the vue-leaflet components, so my guess is the bug should be in here. I have also reduced my map to only the l-map component with no other layers, markers or any other children and the issue still appeared so it seems it is related to this l-map object and the creation and removal of it.

Also, if using the Vue v-show instead of v-if to condition the display of the map, then the problem goes away.

Any thoughts would be welcome, if you need any code please let me know.

THanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.