我在工作中使用Google places API,一切都很正常。然而,我有一个独特的情况下,我需要有一个以上的送货地址,因此,我需要使谷歌地方API的工作方式。
这是我目前的代码。
<template>
<div>
<div v-for="(search, index) in searchInput" :key="index">
<input type="text" ref="search" v-model="search.city">
</div>
<button type="button" @click="addMore">Add more</button>
</div>
</template>
<script>
export default {
name: "App",
data: () => ({
location: null,
searchInput: [
{
city: ""
}
]
}),
mounted() {
window.checkAndAttachMapScript(this.initLocationSearch);
},
methods: {
initLocationSearch() {
let autocomplete = new window.google.maps.places.Autocomplete(
this.$refs.search
);
autocomplete.addListener("place_changed", function() {
let place = autocomplete.getPlace();
if (place && place.address_components) {
console.log(place.address_components);
}
});
},
addMore() {
this.searchInput.push({ city: "" });
}
}
};
</script>
我从API中得到这个错误。InvalidValueError: not an instance of HTMLInputElement
and b.ownerDocument is undefined
我怎么做 refs
我添加的单个项目的唯一性,然后将其传递给 initLocationSearch
方法?请大家帮忙,谢谢。
她是一个 代码和盒子 演示
鉴于你提供的完整场景的细节,我将如何做。
我会使用一个简单的计数器来跟踪输入的数量,并设置其初始值为 1
并用它来显示输入。
<div v-for="(n, index) in this.counter" :key="index">
<input type="text" ref="search">
</div>
然后根据计数器,将自动完成小组件绑定到最后添加的输入。
autocomplete = new window.google.maps.places.Autocomplete(
this.$refs.search[this.counter - 1]
);
然后使用你的 addMore()
方法来递增计数器。
addMore() {
this.counter++;
}
使用 updated()
用于每当一个新的输入被添加到DOM中时,就会触发 initLocationSearch()
方法。
updated() {
this.initLocationSearch();
},
在 place_changed
事件,根据不同的输入值更新所选城市的列表。
this.selectedCities = this.$refs["search"].map(item => {
return { city: item.value };
});
这样,无论输入值发生了什么变化,你总是有一个最新的城市列表。当然,你需要处理清空输入和可能的其他边缘情况。
完整的代码。
<template>
<div>
<div v-for="(n, index) in this.counter" :key="index">
<input type="text" ref="search">
</div>
<button type="button" @click="addMore">Add more</button>
<hr>Selected cities:
<ul>
<li v-for="(item, index) in this.selectedCities" :key="index">{{ item.city }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "App",
data: () => ({
selectedCities: [],
counter: 1
}),
mounted() {
window.checkAndAttachMapScript(this.initLocationSearch);
},
updated() {
this.initLocationSearch();
},
methods: {
setSelectedCities() {
this.selectedCities = this.$refs["search"].map(item => {
return { city: item.value };
});
},
initLocationSearch() {
let self = this,
autocomplete = new window.google.maps.places.Autocomplete(
this.$refs.search[this.counter - 1],
{
fields: ["address_components"] // Reduce API costs by specifying fields
}
);
autocomplete.addListener("place_changed", function() {
let place = autocomplete.getPlace();
if (place && place.address_components) {
console.log(place);
self.setSelectedCities();
}
});
},
addMore() {
this.counter++;
}
}
};
</script>
你可以动态地绑定到 ref.D。类似于 :ref="'search' + index"
<template>
<div>
<div v-for="(search, index) in searchInput" :key="index">
<input type="text" :ref="'search' + index" v-model="search.city">
</div>
<button type="button" @click="addMore">Add more</button>
</div>
</template>
然后在addMore中,在创建推送一个新的对象到searchInput之前,抓住searchInput中最后一个索引。然后你可以得到新创建的 ref,并将其传递给 initLocationSearch
.
initLocationSearch(inputRef) {
let autocomplete = new window.google.maps.places.Autocomplete(
inputRef
);
autocomplete.addListener("place_changed", function() {
let place = autocomplete.getPlace();
if (place && place.address_components) {
console.log(place.address_components);
}
});
},
addMore() {
const lastInputRef = this.$refs['search' + this.searchInput.length - 1];
this.initLocationSearch(lastInputRef);
this.searchInput.push({ city: "" });
}