Vue2- Google-Maps Доступ к gmapApi с использованием beforeEnter () Route Guard - PullRequest
1 голос
/ 26 мая 2020

Контекст: Я пытаюсь получить данные места через place_id на beforeEnter() страже маршрута. По сути, я хочу, чтобы данные загружались, когда кто-то вводит URL-адрес точно www.example.com/place/{place_id}. В настоящее время все работает напрямую, когда я использую свой ввод автозаполнения, а затем вхожу в маршрут, но это не работает, когда я напрямую обращаюсь к URL-адресу с вкладки fre sh. Я считаю, что проблема в том, что google еще не создан.

Вопрос: Как я могу получить доступ к PlacesService() с помощью beforeEnter() защиты маршрута?

Ошибка: Uncaught (in promise) ReferenceError: google is not defined

Пример кода: В одном из модулей моего магазина:

const module = {
  state: {
    selectedPlace: {}
  },
  actions: {
    fetchPlace ({ commit }, params) {
      return new Promise((resolve) => {
        let request = {
          placeId: params,
          fields: ['name', 'rating', 'formatted_phone_number', 'geometry', 'place_id', 'website', 'review', 'user_ratings_total', 'photo', 'vicinity', 'price_level']
        }
        let service = new google.maps.places.PlacesService(document.createElement('div'))
        service.getDetails(request, function (place, status) {
          if (status === 'OK') {
            commit('SET_SELECTION', place)
            resolve()
          }
        })
      })
    },
  },
  mutations: {
    SET_SELECTION: (state, selection) => {
      state.selectedPlace = selection
    }
  }
}

export default module

В моем магазине. js:

import Vue from 'vue'
import Vuex from 'vuex'
import placeModule from './modules/place-module'
import * as VueGoogleMaps from 'vue2-google-maps'

Vue.use(Vuex)

// gmaps
Vue.use(VueGoogleMaps, {
  load: {
    key: process.env.VUE_APP_GMAP_KEY,
    libraries: 'geometry,drawing,places'
  }
})

export default new Vuex.Store({
  modules: {
    placeModule: placeModule
  }
})

в моем роутере:

import store from '../state/store'

export default [
  {
    path: '/',
    name: 'Home',
    components: {
      default: () => import('@/components/Home/HomeDefault.vue')
    }
  },
  {
    path: '/place/:id',
    name: 'PlaceProfile',
    components: {
      default: () => import('@/components/PlaceProfile/PlaceProfileDefault.vue')
    },
    beforeEnter (to, from, next) {
      store.dispatch('fetchPlace', to.params.id).then(() => {
        if (store.state.placeModule.selectedPlace === undefined) {
          next({ name: 'NotFound' })
        } else {
          next()
        }
      })
    }
  }
]

Что я пробовал: - Изменение new google.maps.places.PlacesService на new window.new google.maps.places.PlacesService - Использование beforeRouteEnter() вместо beforeEnter() в качестве навигационного стража - Замена google.maps... на gmapApi.google.maps... и gmapApi.maps... - Кричать в бездну - Ставить под сомнение каждое решение, которое я когда-либо принимал

РЕДАКТИРОВАТЬ: I ' Мы также пробовали this.$gmapApiPromiseLazy(), предложенные в wiki здесь

1 Ответ

0 голосов
/ 26 мая 2020

Плагин добавляет миксин, предоставляющий this.$gmapApiPromiseLazy только Vue экземпляров (компонентов), но вам повезло ... он также добавляет тот же метод к Vue статически

Исходный код

Vue.mixin({
  created () {
    this.$gmapApiPromiseLazy = gmapApiPromiseLazy
  }
})

Vue.$gmapApiPromiseLazy = gmapApiPromiseLazy

Итак, все, что вам нужно сделать в вашем магазине или маршрутизаторе, это использовать

import Vue from 'vue'

// snip...

Vue.$gmapApiPromiseLazy().then(() => {
  let service = new google.maps.places....
})
...