代码之家  ›  专栏  ›  技术社区  ›  Riyenz

VueJS子组件GMAP在父数据更新时不重新加载

  •  1
  • Riyenz  · 技术社区  · 7 年前

    嗨,我是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

    0 回复  |  直到 7 年前
    推荐文章