父数据更新时,VueJS子组件GMAP不会重新呈现

时间:2018-11-27 07:08:21

标签: google-maps vue.js vuejs2 html-framework-7

嗨,我是Vue的新手,我遇到了这个问题,当我更新位置时,它不会反映在子组件上。我使用了计算和观看功能,但仍然没有更新。原谅我,因为我对VueJS并不了解。

因此在我的代码中,我有location(计算的),它侦听绑定到localLocation的{​​{1}}(数据)。我使用方法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)")
  

初始页面尚无地址

enter image description here

  

添加位置后的实际输出

enter image description here

  

预期产量

enter image description here

0 个答案:

没有答案