Включить роутер-ссылку в Google Maps Infowindows - vuejs - PullRequest
0 голосов
/ 08 декабря 2018

Я создаю приложение в Laravel 5.7 с VueJS.У меня есть карта Google (созданная с использованием vue2-google-maps) с 200+ маркерами, каждый из которых имеет информационное окно.Я хотел бы включить ссылку на маршрутизатор в информационное окно, но кажется, что, поскольку ссылка передается в виде строки, она не анализируется Vue.

В данный момент это мой компонент - все работает, кромеrouter-link

Кто-нибудь может предложить способ получения vue для анализа роутер-ссылки?

Спасибо

<template>
<div id="map">

    <gmap-map
            :center="center"
            :zoom="11"
            style="width:100%;  height: 750px;"
            map-type-id="satellite"
    >

        <GmapMarker v-for="location in locations"
                    :key="location.id"
                    @click="toggleInfoWindow(location, location.id)"
                    :position="({
                        lat : location.latitude,
                        lng : location.longitude,
                        }
                    )"
        ></GmapMarker>
        <gmap-info-window
                :options="infoOptions"
                :position="infoWindowPos"
                :opened="infoWinOpen"
                @closeclick="infoWinOpen=false"
        >
            <div v-html="infoContent"></div>
        </gmap-info-window>

    </gmap-map>


</div>
</template>

<script>

    export default {

        data() {
            return {
                center: {lat: 51.553726, lng: -0.110035},
                locations: [],
                visits:[],
                infoContent: '',
                infoWindowPos: {
                    lat: 0,
                    lng: 0
                },
                infoWinOpen: false,
                currentMidx: null,
                //optional: offset infowindow so it visually sits nicely on top of our marker
                infoOptions: {
                    pixelOffset: {
                        width: 0,
                        height: -35
                    }
                }
            }

        },

        methods: {
            getLocations(){

                window.axios.get('/api/locations').then(({data})=>{
                    data.forEach(location => {
                        this.locations.push(location)
                    });
                });
            },


            toggleInfoWindow: function (marker, idx) {

                this.infoWindowPos = ({
                        lat : marker.latitude,
                        lng : marker.longitude,
                    }
                );
                this.infoContent = this.getInfoWindowContent(marker);

                //check if its the same marker that was selected if yes toggle
                if (this.currentMidx == idx) {
                    this.infoWinOpen = !this.infoWinOpen;
                }
                //if different marker set infowindow to open and reset current marker index
                else {
                    this.infoWinOpen = true;
                    this.currentMidx = idx;
                }
            },

            getInfoWindowContent: function (marker) {
                return(`<div class="info_window container">
                          <h3>${marker.name}</h3>
                          <a href="/location/${marker.slug}"><div class="mx-auto btn btn-success">More Info</div></a>
                          <router-link :to="/location/${marker.slug}" class="mx-auto btn btn-success">RL More Info</router-link>
                         </div>`);
            },


        },

        created(){
            this.getLocations()

        },


    };
</script>

<style>

</style>

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

Директива v-html, использованная в следующем фрагменте кода, не может использоваться для составления частичных шаблонов [1] .

<div v-html="infoContent"></div>

В этом случае для infoContent может быть полезно реализовать его в виде отдельного компонента, который можно зарегистрировать следующим образом [2]

<template>
<!--...-->
  <gmap-info-window
    :options="infoOptions"
    :position="infoWindowPos"
    :opened="infoWinOpen"
    @closeclick="infoWinOpen=false"
  >
    <info-content 
      v-bind:slug="marker.slug"
      v-bind:name="marker.name"
    >
    </info-content>
  </gmap-info-window>
<!--...-->
</template>

<script>
import InfoContent from './components/InfoContent.vue'

export default {
   components: {
     InfoContent
   },
   data() { /*...*/ },
   methods: { 
     //...
     toggleInfoWindow (marker, idx) {
       //...
       this.marker = marker;
       //...
     }
   }
}
</script>

компоненты / InfoContent.vue

<template>
   <div class="info_window container">
    <h3>{{ name }}</h3>
    <a href="/location/{{ slug }}">
      <div class="mx-auto btn btn-success">More Info</div>
    </a>
    <router-link
      :to="/location/{{ slug }}"
      class="mx-auto btn btn-success">
      RL More Info
    </router-link>
  </div>
</template>

<script>
export default {
  name: 'info-content',
  props: {
    slug: String,
    name: String
  }
}
</script>
0 голосов
/ 08 декабря 2018

Директива v-html просто передает данные, которые вы передаете ей, непосредственно в DOM как innerHtml этого элемента.Это замечательно, если вы хотите передать что-то, что уже является HTML, но не так здорово, если Vue нужно что-то с этим сделать.

Вместо этого вам нужно использовать сам шаблон.Если это находится в самом компоненте, как здесь, это просто.Вместо того, чтобы генерировать какую-либо строку HTML, вместо этого поместите все это в шаблон и используйте обозначения усов, v-if и т. П. Для управления тем, что и где показано.Если вместо этого у вас есть отдельный компонент, вы можете использовать слоты для управления тем, что передается в ваше информационное окно.Затем вы передаете контент в этот слот через шаблон родителя.


Чтобы устранить проблему, вам нужно сделать что-то подобное.Сначала присвойте свой маркер некоторой переменной, которую мы можем использовать в шаблоне.Мы можем просто повторно использовать infoContent в этом случае.

    toggleInfoWindow: function (marker, idx) {
        this.infoWindowPos = ({
                lat : marker.latitude,
                lng : marker.longitude,
            }
        );
        this.infoContent = marker;

        //check if its the same marker that was selected if yes toggle
        if (this.currentMidx == idx) {
            this.infoWinOpen = !this.infoWinOpen;
        }
        //if different marker set infowindow to open and reset current marker index
        else {
            this.infoWinOpen = true;
            this.currentMidx = idx;
        }
    },

Теперь мы изменим шаблон, чтобы ваш html и компоненты были внутри gmap-info-window.Поскольку мы присвоили нашему активному маркеру infoContent, мы ссылаемся на него здесь.

    <gmap-info-window
            :options="infoOptions"
            :position="infoWindowPos"
            :opened="infoWinOpen"
            @closeclick="infoWinOpen=false"
    >
        <div class="info_window container">
            <h3>{{ infoContent.name }}</h3>
            <a :href="`/location/${infoContent.slug}`"><div class="mx-auto btn btn-success">More Info</div></a>
            <router-link :to="`/location/${infoContent.slug}`" class="mx-auto btn btn-success">RL More Info</router-link>
        </div>
    </gmap-info-window>

Теперь, когда вы вызываете toggleInfoWindow, информационное окно теперь будет обновляться с новой информацией маркера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...