Дочерний компонент VueJS GMAP не перерисовывается при обновлении родительских данных - PullRequest
0 голосов
/ 27 ноября 2018

Привет, я новичок в Vue и столкнулся с этой проблемой, когда , когда я обновляю местоположение, оно не отражается на дочернем компоненте. Я использовал computed и watch, но все еще не обновляю.простите меня, поскольку у меня нет сильных знаний о VueJS.

, поэтому в моем коде у меня есть location (вычисленный), который слушает localLocation (данные), который связан с project.location.Я обновляю местоположение, используя метод setPlace()

, надеюсь, кто-нибудь может помочь.вот мой код ниже:

<template lang="pug">
  .google-maps-wrapper
    template(v-if="!location")
      f7-list.no-margin-top
        f7-list-button(title='Add Location' @click="isAutocompleteOpen = true")
    template(v-if="location")
      f7-list.no-margin(inline-labels no-hairlines-md)
        f7-list-item.short-text Address: {{ location.formattedAddress }}
      div
        gmap-map.main-map(ref="googleMap" :options="mapOptions" :center="location.position" :zoom="16" :map-type-id="mapTypeId")
          gmap-marker(:position="location.position" :clickable="false")
      f7-actions(ref='mapsAction')
        f7-actions-group
          f7-actions-group
            f7-actions-button(@click="copyToClipboard()") Copy to Clipboard
            f7-actions-button(@click="isAutocompleteOpen = true") Change Address
            f7-actions-button(v-if="$root.$device.ios || $root.$device.macos" @click="$refs.navigateActions.f7Actions.open()") Navigate
            f7-actions-button(v-else @click="googleMapsNavigate()") Navigate
        f7-actions-group
          f7-actions-button
            b Cancel
      f7-actions(ref='navigateActions')
        f7-actions-group
          f7-actions-group
            f7-actions-button(@click="googleMapsNavigate()") Google Maps
            f7-actions-button(@click="appleMapsNavigation()") Apple Maps
        f7-actions-group
          f7-actions-button
            b Cancel
    f7-popup.locate-project(:opened='isAutocompleteOpen' @popup:closed='closeAutocomplete()')
      f7-page
        f7-navbar
          f7-nav-title Search Location
          f7-nav-right
            f7-link(@click="closeAutocomplete()") Close
        f7-searchbar.searchbar(search-container=".search-list" search-in=".item-title" @input="searchLocation($event)" placeholder="Enter Location" clear-button)
        f7-list.not-found(v-if="!pendingSearch && !suggestedLocations.length && searchedLocation")
          f7-list-item(title="Nothing found")
        f7-block-title.gmap-preloader(v-if="pendingSearch")
          f7-preloader(size="16")
        f7-list.search-list.searchbar-found.gmap-search-list(v-if="!pendingSearch && suggestedLocations.length" media-list)
          f7-list-item.item-button(v-for='(location, index) in suggestedLocations' :title="location.structured_formatting.main_text" :subtitle="location.structured_formatting.secondary_text" @click="updateLocation(location)")
</template>

<script>

import { debounce } from 'lodash-es'
import { Plugins } from '@capacitor/core'

const { Clipboard } = Plugins
const { Browser } = Plugins

const debounceSearch = debounce(run => {
  run()
}, 500)

import defaultMixin from '@/mixins/default'
import {
  f7Actions,
  f7ActionsLabel,
  f7ActionsGroup,
  f7ActionsButton,
  f7Popup,
  f7Page,
  f7NavRight,
  f7NavTitle,
  f7Navbar,
  f7Block,
  f7BlockTitle,
  f7Label,
  f7Link,
  f7Preloader,
  f7List,
  f7ListButton,
  f7ListItem,
  f7ListInput,
  f7Icon,
  f7Searchbar
} from 'framework7-vue'
import { gmapApi } from 'vue2-google-maps'

export default {
  name: "google-maps",
  mixins: [defaultMixin],
  props: ['project'],
  components: {
    f7Actions,
    f7ActionsLabel,
    f7ActionsGroup,
    f7ActionsButton,
    f7Popup,
    f7Page,
    f7NavRight,
    f7NavTitle,
    f7Navbar,
    f7Block,
    f7BlockTitle,
    f7Label,
    f7Link,
    f7Preloader,
    f7List,
    f7ListButton,
    f7ListItem,
    f7ListInput,
    f7Icon,
    f7Searchbar
  },
  data() {
    return {
      mapTypeId: "terrain",
      directionsService: undefined,
      directionsDisplay: undefined,
      autocompleteService: undefined,
      autocompleteRequest: undefined,
      navigate: false,
      localLocation: this.project.location,
      mapOptions: {
        disableDefaultUI: true,
        backgroundColor: '#d3d3d3',
        draggable: false,
        zoomControl: false,
        fullscreenControl: false,
        streetViewControl: false,
        clickableIcons: false
      },
      isAutocompleteOpen: false,
      suggestedLocations: [],
      pendingSearch: false,
      origin: '',
      searchedLocation: ''
    }
  },
  computed: {
    location() {
      return this.localLocation
    },
    google: gmapApi
  },
  methods: {
    appleMapsNavigation(){
      window.open(`http://maps.apple.com/?daddr=${encodeURI(this.project.location.formattedAddress)}`)
    },
    googleMapsNavigate(){
      if(this.$root.$device.ios){
        window.open(`comgooglemaps://?daddr=${encodeURI(this.project.location.formattedAddress)}`)
      }else{
        window.open(`https://www.google.com/maps/dir//${encodeURI(this.project.location.formattedAddress)}`)
      }
    },
    closeAutocomplete() {
      this.isAutocompleteOpen = false
      this.searchedLocation = ''
      this.suggestedLocations = []
      this.$f7.searchbar.clear('.searchbar')
    },
    updateLocation( location ){
      this.getGeocode(location.place_id, output => {
        this.suggestedLocations = []
        this.setPlace(output[0])
      })
    },
    getGeocode( placeId, callback ){
      const geocoder = new google.maps.Geocoder()

      this.$f7.dialog.preloader()

      geocoder.geocode({placeId}, output => {
        callback(output)
        this.closeAutocomplete()
        this.$f7.dialog.close()
      })
    },
    searchLocation( event ) {
      this.pendingSearch = true
      this.searchedLocation = event.target.value

      debounceSearch(() => {
        if(!this.searchedLocation) {
          this.pendingSearch = false
          this.suggestedLocations = []
          return
        }
        const autocompleteService = new google.maps.places.AutocompleteService()

        autocompleteService.getPlacePredictions({input: this.searchedLocation}, output => {
          if(this.pendingSearch){
            this.suggestedLocations = output || []
            this.pendingSearch = false
          }
        })
      })
    },
    setPlace( selectedLocation ) {
      if(!selectedLocation.formatted_address) return;
      const data = {
        location: {
          formattedAddress: selectedLocation.formatted_address,
          position: {
            lat: selectedLocation.geometry.location.lat(),
            lng: selectedLocation.geometry.location.lng()
          }
        }
      };
      this.$f7.popup.close('.add-location')
      if(this.$refs.autocomplete) this.$refs.autocomplete.$el.disabled = true
      this.localLocation = data.location

      db.collection("projects")
        .doc(this.project.id)
        .set(data, {
          merge: true
        })
        .then()
    },
    copyToClipboard() {
      Clipboard.write({
        string: this.project.location.formattedAddress
      });
    }
  }
}
</script>

Сводка кода (только сводка всего кода выше)

Шаблон, который отображает адрес и карту

  .google-maps-wrapper
    template(v-if="!location")
      f7-list.no-margin-top
        f7-list-button(title='Add Location' @click="isAutocompleteOpen = true")
    template(v-if="location")
      f7-list.no-margin(inline-labels no-hairlines-md)
        f7-list-item.short-text Address: {{ location.formattedAddress }}
      div
        gmap-map.main-map(ref="googleMap" :options="mapOptions" :center="location.position" :zoom="16" :map-type-id="mapTypeId")
          gmap-marker(:position="location.position" :clickable="false")

Последняя строка шаблона, в которой обновляется местоположение

  f7-list-item.item-button(v-for='(location, index) in suggestedLocations' :title="location.structured_formatting.main_text" :subtitle="location.structured_formatting.secondary_text" @click="updateLocation(location)")

Скрипт, обновляющий местоположение

updateLocation( location ){
  this.getGeocode(location.place_id, output => {
    this.suggestedLocations = []
    this.setPlace(output[0])
  })
},
setPlace( selectedLocation ) {
  if(!selectedLocation.formatted_address) return;
  const data = {
    location: {
      formattedAddress: selectedLocation.formatted_address,
      position: {
        lat: selectedLocation.geometry.location.lat(),
        lng: selectedLocation.geometry.location.lng()
      }
    }
  };
  this.$f7.popup.close('.add-location')
  if(this.$refs.autocomplete) this.$refs.autocomplete.$el.disabled = true
  this.localLocation = data.location

  db.collection("projects")
    .doc(this.project.id)
    .set(data, {
      merge: true
    })
    .then()
},

Начальная страница Пока нет адреса

enter image description here

Фактический вывод после добавления местоположения

enter image description here

Ожидаемый результат

enter image description here

...