inocan-group / vue3-google-map

A set of composable components for easy use of Google Maps in your Vue 3 projects.
https://vue3-google-map.com
MIT License
293 stars 59 forks source link

Pass options as one prop? #171

Closed cadilhac closed 1 year ago

cadilhac commented 1 year ago

Would it be possible to pass options like this:

<GoogleMap api-key="..." ref="mapRef" :options="getMapOptions">
</GoogleMap>

function getMapOptions() {
  return {
        zoom: 14,
        center: new google.maps.LatLng(45.481662, -73.628735),
        draggable: true,
        backgroundColor: '#fbf0de',
        scrollwheel: true,
        disableDefaultUI: true,
        panControl: false,
        zoomControl: true,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        maxZoom: 18,
        minZoom: 5,
        panControlOptions: {
            position: google.maps.ControlPosition.TOP_RIGHT
        },
        zoomControlOptions: {
            position: google.maps.ControlPosition.TOP_RIGHT
        },
        styles: getMapStyles()
  }
}

instead of having to pass each one individually. This makes the template more readable.

As a workaround, I can do this instead:

watch(() => mapRef.value?.ready, (ready) => {
    if (!ready) return

    mapRef.value.map.setOptions(getMapOptions())
})
HusamElbashir commented 1 year ago

You could always just use v-bind with an object instead https://vuejs.org/guide/components/props.html#binding-multiple-properties-using-an-object

cadilhac commented 1 year ago

Well, if I use v-bind="getMapOptions()" which returns an object that relies on the google instance, then it complains that google is not defined (i.e. the script not loaded yet).

HusamElbashir commented 1 year ago

See here: https://github.com/inocan-group/vue3-google-map#advanced-usage You can make your options object a computed property that uses the map api once it's ready or falls back to some default value

cadilhac commented 1 year ago

Yes I can do like that. However I notice that I have to change the name of some properties. If I use the ones defined by google, it doesn't work (ex: zoomControlOptions in the google api becomes zoomControlPosition in your api, or disableDefaultUI which has its last letter that changes case).

Because of those differences, I will continue using my workaround because using the google types and names makes more sense to me.

HusamElbashir commented 1 year ago

Correct we opted for simplifying the api when an interface only has one possible property (e.g. position for ZoomControlOptions). There are other issues that had to be factored in such as prop name casing: https://vuejs.org/guide/components/props.html#prop-name-casing This is to avoid disableDefaultUI translating into disable-default-u-i when using kebab-case in templates.

So if you have to use your options as is I'm afraid you'll have to use a watcher like you suggested in your initial post.

cadilhac commented 1 year ago

Thanks for all this information.