当 Google Places API 自动完成授权失败时输入被禁用

Input gets disabled when Google Places API Autocomplete fails authorization

当使用 Google Places API Autocomplete with Vue/Vuetify 时,如果 API 脚本授权失败,文本字段将被禁用,并且在第一个字符。

如何让它在后台安静地失败并允许输入文本?

我知道有 gm_authFailure() 并且 Places API 会在发生故障时全局调用它,但我不确定如何允许该函数在 Vue 中调用它.

JSFiddle:https://jsfiddle.net/wya72b0j/

HTML:

<div id="app">
  <v-app>
    <v-container class="ma-auto pa-auto blue-grey darken-4 fill-height">
      <v-row justify="center" class="mx-5 px-5">
        <v-text-field
          v-model="billingAddress"
          @focus="billingAutocomplete()"
          required
          ref="billautocomplete">
          </v-text-field>
      </v-row>
    </v-container>
  </v-app>
</div>

Vue:

new Vue({
  el: "#app",
  vuetify: new Vuetify({
    theme: {
      dark: true,
    }
  }),
  data: () => ({
    billingAddress: '',
  }),
  mounted() {
    const placesapi = document.createElement('script')
    placesapi.setAttribute(
      'src',
      'https://maps.googleapis.com/maps/api/js?key=ThisKeyNotDoesNotWork&libraries=places'
    )
    document.head.appendChild(placesapi)
  },
  methods: {
    billingAutocomplete() {
      let addressArray = {
        street_number: '',
        route: '',
        locality: '',
        administrative_area_level_1: '',
        country: '',
        postal_code: '',
      }

      let element = this.$refs.billautocomplete.$refs.input
      const google = window.google

      let autocomplete = new google.maps.places.Autocomplete(element, {
        types: ['geocode'],
        componentRestrictions: {
          country: 'us'
        },
      })

      autocomplete.setFields(['address_component'])

      autocomplete.addListener('place_changed', () => {
        const componentForm = {
          street_number: 'short_name',
          route: 'long_name',
          locality: 'long_name',
          administrative_area_level_1: 'short_name',
          country: 'long_name',
          postal_code: 'short_name',
        }

        let place = autocomplete.getPlace()

        for (const component of place.address_components) {
          const addressType = component.types[0]

          if (componentForm[addressType]) {
            const val = component[componentForm[addressType]]
            addressArray[addressType] = val
          }
        }

        this.billingAddress = addressArray
      })
    }
  }
})

我让它工作了,但它有点老套。首先,我向 v-text-field 添加了一个 id 标记,以防止禁用和空占位符。在 <script> 标签下,我在一个基本为空的函数中添加了 window.gm_authFailure(),最后在 mounted 下,我添加了处理输入的真实函数,使其不被禁用。我确定有一个 better/proper 方法,但这行得通。

更新了 JSFiddle:https://jsfiddle.net/90ua3xzy/

HTML:

<v-text-field
  v-model="billingAddress"
  @focus="billingAutocomplete()"
  required
  ref="billautocomplete"
  id="billingautocomplete">
</v-text-field>

Vue:

<script>
window.gm_authFailure = function() {
  return false
}
[...]
mounted() {
  window.gm_authFailure = function() {
    document.getElementById('billingautocomplete').disabled = false
    document.getElementById('billingautocomplete').placeholder = ''
  }
[...]