v-autocomplete是否与Google商家信息自动填充API兼容

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了v-autocomplete是否与Google商家信息自动填充API兼容相关的知识,希望对你有一定的参考价值。

我尝试利用Google Places Autocomplete API填充Vuetify Autocomplete Component如下:

<template>
  <v-autocomplete
    ref="autocomplete" 
    label="Location"
  >
  </v-autocomplete>
</template>

<script>
export default {
  mounted() {
    var autocomplete = new google.maps.places.Autocomplete(
      /** @type {!htmlInputElement} */(this.$refs.autocomplete),
      {types: ['geocode']})
  }
}
</script>

但是,在浏览器的开发人员控制台中,它会引发错误:

InvalidValueError:不是HTMLInputElement的实例

我的猜测是v-autocomplete不是HTMLInputElement类型。

(并且不仅仅是v-autocomplete的情况:用v-input替换它也会导致相同的错误。)

有没有办法让v-autocomplete充满Google Places Autocomplete API,比如手动将它作为HTMLInputElement的实例?

答案

我现在也在搞乱这个问题,让它部分工作,当我完全刷新它时会更新,但现在你的代码存在问题。

当您在模板中应用ref="autocomplete"时,您将ref应用于组件而非输入。为了使它工作,我设置了一个id="autocomplete",它直接应用于输入,在我的挂载函数中创建一个变量来引用输入id,然后我将它传递给自动完成函数。我在下面更新了您的代码以反映这一点。

<template>
  <v-autocomplete
    id="autocomplete" 
    label="Location"
  >
  </v-autocomplete>
</template>

<script>
export default {
  mounted() {
    var autocompleteInput = document.querySelector('#autocomplete');
    var autocomplete = new google.maps.places.Autocomplete(
      /** @type {!HTMLInputElement} */(autocompleteInput),
      {types: ['geocode']})
  }
}
</script>

您可以将相同的原则应用于v-text field,但Google自动填充结果将显示在输入下方的自己的容器中,而不是像v-autocomplete这样的选择下拉容器中。

另一答案

当仅仅使用v-autocomplete时,似乎没有直接的方式来保持google.maps.places.Autocomplete的材料外观。为了实现这一点,我包装了API的getPlacePredictions()方法 - 不是一个名为Autocomplete Service的组件:

PlacesUtils.js

/* global google */

const GetSuggestions = async searchText => {
  let result

  try {
    const rawResult = await searchLocation(searchText)
    result = rawResult.map((res) => {
      return {
        id: res.place_id,
        value: res.description
      }
    })
  } catch (err) {
    console.log('An error occurred', err)
    result = null
  }
  return result
}

// Auxiliary functions
// wrap google api's callback to an async function
const searchLocation = async val => {
  let promise = await new Promise((resolve, reject) => {
    var displaySuggestions = (predictions, status) => {
      if (status !== google.maps.places.PlacesServiceStatus.OK) {
        reject(status)
      }
      resolve(predictions)
    }

    var service = new google.maps.places.AutocompleteService()
    service.getPlacePredictions({
      input: val,
      types: ['geocode']
    },
    displaySuggestions)
  }).catch(function (err) { throw err })

  return promise
}

export { GetSuggestions }

然后,为watch的模型添加一个v-autocomplete我将这个方法称为用户所做的更改,如下所示:

Place.vue

<template>
  <v-layout row justify-center>
    <!-- ... -->
      <v-autocomplete
        label="Location"
        v-model="autocompleteLocationModel"
        :items="locationFoundItems"
        :search-input.sync="locationSearchText"
        item-text="value"
        item-value="id"
        hide-no-data
        return-object
      >
    </v-autocomplete>
    <!-- ... -->
  </v-layout>
</template>

<script>
/* eslint handle-callback-err: "warn" */
import { GetSuggestions } from '@/utils/PlaceUtils'

export default {
  data () {
    return {
      autocompleteLocationModel: null,
      locationSearchText: null,
      locationEntries: []
    }
  },
  computed: {
    locationFoundItems () {
      return this.locationEntries
    }
  },
  watch: {
    locationSearchText (newVal) {
      var _vue = this

      // If less than 3 chars typed, do not search
      if (!newVal || newVal.length <= 3) return

      // Call the method from the previous section here
      GetSuggestions(newVal)
        .then(function (res) {
          _vue.locationEntries = res
        })
        .catch(function (err) {
          // error handling goes here
        })
    }
  }
  // ...
}
</script>

以上是关于v-autocomplete是否与Google商家信息自动填充API兼容的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何可能的方法在 Vuetify 的 v-autocomplete 中搜索多个属性?

如何测试一个 vue vuetify v-autocomplete

将自定义部分添加到 v-autocomplete 下拉列表

谷歌商家中心

v-autocomplete 并将用户输入设置为其值

vue.js - 测试 v-autocomplete 的观察者