我对Vue.js
很陌生,我正在尝试在我的Django
项目中使用它。我需要导入vue-google-autocomplete
,但收到以下错误:
"Uncaught SyntaxError: Unexpected identifier"
问题出在这一行:
import VueGoogleAutocomplete from 'vue-google-autocomplete'
我不使用任何包管理器(例如npm
),而我试图仅使用html
来导入库。
这是代码:
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=onLoaded&language=sk®ion=SR"
async defer></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-google-autocomplete@1.1.0/src/VueGoogleAutocomplete.vue" type="application/octet-stream"></script>
<script>
import VueGoogleAutocomplete from 'vue-google-autocomplete'
Vue.component('vue-google-autocomplete', VueGoogleAutocomplete);
var app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
data: {
address: '',
business_type_text: '',
},
methods: {
....
}
});
</script>
编辑
我创建了一个新文件create.js
,该文件在vue.js
和自动完成CDN之后导入,但是仍然会引发错误:
答案 0 :(得分:0)
尝试
Vue.use(vue-google-autocomplete)
您可能需要替换名称。
JavaScript解释器无法识别 import
。需要先进行编译。
如果要使用import
,则必须创建一个文件(即main.js),并将其包含在HTML文件中,如下所示:
<script type="module" src="main.js"></
答案 1 :(得分:0)
您无法从外部网址导入/加载.vue
文件。
一种干净的方法是将.vue
文件保存在您的项目中,并将其导入到您选择的组件中:
import VueGoogleAutocomplete from './VueGoogleAutocomplete.vue'
// assuming you save the .vue file as VueGoogleAutocomplete.vue,
// in the same folder with the parent component.
,并在组件的components
中:
components: { VueGoogleAutocomplete }
请参见有效示例here。如果您在public/index.html
中使用有效的API密钥,则可以使用。
我将文件导入了/App.vue
,并保存到了components/VueGoogleAutocomplete.vue
。
另一件事:如果在maps js链接上使用async
,则您的.vue
组件将抱怨google
对象未定义。基本上,您要一直挂载VueGoogleAutocomplete,直到地图js加载完毕(使用v-if
和辅助模型属性,或者不要在地图js脚本上使用async
)。
如果要在单个文件中执行此操作,请按以下步骤操作(基本上定义一个
在Vue.component
中复制粘贴.vue
的内容(包括模板)。由于您是在全局Vue
实例上定义的,因此无需在components
中声明即可使用它:
Vue.config.productionTip = false;
Vue.config.devtools = false;
const ADDRESS_COMPONENTS = {
street_number: "short_name",
route: "long_name",
locality: "long_name",
administrative_area_level_1: "short_name",
administrative_area_level_2: "county",
country: "long_name",
postal_code: "short_name"
};
const CITIES_TYPE = ["locality", "administrative_area_level_3"];
const REGIONS_TYPE = [
"locality",
"sublocality",
"postal_code",
"country",
"administrative_area_level_1",
"administrative_area_level_2"
];
Vue.component('vue-google-autocomplete', {
name: "VueGoogleAutocomplete",
template: `<input
ref="autocomplete"
type="text"
:class="classname"
:id="id"
:placeholder="placeholder"
v-model="autocompleteText"
@focus="onFocus()"
@blur="onBlur()"
@change="onChange"
@keypress="onKeyPress"
@keyup="onKeyUp"
>`,
props: {
id: {
type: String,
required: true
},
classname: String,
placeholder: {
type: String,
default: "Start typing"
},
types: {
type: String,
default: "address"
},
country: {
type: [String, Array],
default: null
},
enableGeolocation: {
type: Boolean,
default: false
},
geolocationOptions: {
type: Object,
default: null
}
},
data() {
return {
/**
* The Autocomplete object.
*
* @type {Autocomplete}
* @link https://developers.google.com/maps/documentation/javascript/reference#Autocomplete
*/
autocomplete: null,
/**
* Autocomplete input text
* @type {String}
*/
autocompleteText: "",
geolocation: {
/**
* Google Geocoder Objet
* @type {Geocoder}
* @link https://developers.google.com/maps/documentation/javascript/reference#Geocoder
*/
geocoder: null,
/**
* Filled after geolocate result
* @type {Coordinates}
* @link https://developer.mozilla.org/en-US/docs/Web/API/Coordinates
*/
loc: null,
/**
* Filled after geolocate result
* @type {Position}
* @link https://developer.mozilla.org/en-US/docs/Web/API/Position
*/
position: null
}
};
},
watch: {
autocompleteText: function(newVal, oldVal) {
this.$emit("inputChange", { newVal, oldVal }, this.id);
},
country: function(newVal, oldVal) {
this.autocomplete.setComponentRestrictions({
country: this.country === null ? [] : this.country
});
}
},
mounted: function() {
const options = {};
if (this.types) {
options.types = [this.types];
}
if (this.country) {
options.componentRestrictions = {
country: this.country
};
}
this.autocomplete = new google.maps.places.Autocomplete(
document.getElementById(this.id),
options
);
this.autocomplete.addListener("place_changed", this.onPlaceChanged);
},
methods: {
/**
* When a place changed
*/
onPlaceChanged() {
let place = this.autocomplete.getPlace();
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
this.$emit("no-results-found", place, this.id);
return;
}
if (place.address_components !== undefined) {
// return returnData object and PlaceResult object
this.$emit("placechanged", this.formatResult(place), place, this.id);
// update autocompleteText then emit change event
this.autocompleteText = document.getElementById(this.id).value;
this.onChange();
}
},
/**
* When the input gets focus
*/
onFocus() {
this.biasAutocompleteLocation();
this.$emit("focus");
},
/**
* When the input loses focus
*/
onBlur() {
this.$emit("blur");
},
/**
* When the input got changed
*/
onChange() {
this.$emit("change", this.autocompleteText);
},
/**
* When a key gets pressed
* @param {Event} event A keypress event
*/
onKeyPress(event) {
this.$emit("keypress", event);
},
/**
* When a keyup occurs
* @param {Event} event A keyup event
*/
onKeyUp(event) {
this.$emit("keyup", event);
},
/**
* Clear the input
*/
clear() {
this.autocompleteText = "";
},
/**
* Focus the input
*/
focus() {
this.$refs.autocomplete.focus();
},
/**
* Blur the input
*/
blur() {
this.$refs.autocomplete.blur();
},
/**
* Update the value of the input
* @param {String} value
*/
update(value) {
this.autocompleteText = value;
},
/**
* Update the coordinates of the input
* @param {Coordinates} value
*/
updateCoordinates(value) {
if (!value && !(value.lat || value.lng)) return;
if (!this.geolocation.geocoder)
this.geolocation.geocoder = new google.maps.Geocoder();
this.geolocation.geocoder.geocode(
{ location: value },
(results, status) => {
if (status === "OK") {
results = this.filterGeocodeResultTypes(results);
if (results[0]) {
this.$emit(
"placechanged",
this.formatResult(results[0]),
results[0],
this.id
);
this.update(results[0].formatted_address);
} else {
this.$emit("error", "no result for provided coordinates");
}
} else {
this.$emit("error", "error getting address from coords");
}
}
);
},
/**
* Update location based on navigator geolocation
*/
geolocate() {
this.updateGeolocation((geolocation, position) => {
this.updateCoordinates(geolocation);
});
},
/**
* Update internal location from navigator geolocation
* @param {Function} (geolocation, position)
*/
updateGeolocation(callback = null) {
if (navigator.geolocation) {
let options = {};
if (this.geolocationOptions)
Object.assign(options, this.geolocationOptions);
navigator.geolocation.getCurrentPosition(
position => {
let geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
this.geolocation.loc = geolocation;
this.geolocation.position = position;
if (callback) callback(geolocation, position);
},
err => {
this.$emit("error", "Cannot get Coordinates from navigator", err);
},
options
);
}
},
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
biasAutocompleteLocation() {
if (this.enableGeolocation) {
this.updateGeolocation((geolocation, position) => {
let circle = new google.maps.Circle({
center: geolocation,
radius: position.coords.accuracy
});
this.autocomplete.setBounds(circle.getBounds());
});
}
},
/**
* Format result from Geo google APIs
* @param place
* @returns {{formatted output}}
*/
formatResult(place) {
let returnData = {};
for (let i = 0; i < place.address_components.length; i++) {
let addressType = place.address_components[i].types[0];
if (ADDRESS_COMPONENTS[addressType]) {
let val =
place.address_components[i][ADDRESS_COMPONENTS[addressType]];
returnData[addressType] = val;
}
}
returnData["latitude"] = place.geometry.location.lat();
returnData["longitude"] = place.geometry.location.lng();
return returnData;
},
/**
* Extract configured types out of raw result as
* Geocode API does not allow to do it
* @param results
* @returns {GeocoderResult}
* @link https://developers.google.com/maps/documentation/javascript/reference#GeocoderResult
*/
filterGeocodeResultTypes(results) {
if (!results || !this.types) return results;
let output = [];
let types = [this.types];
if (types.includes("(cities)")) types = types.concat(CITIES_TYPE);
if (types.includes("(regions)")) types = types.concat(REGIONS_TYPE);
for (let r of results) {
for (let t of r.types) {
if (types.includes(t)) {
output.push(r);
break;
}
}
}
return output;
}
}
});
new Vue({
el: '#app',
methods: {
getAddressData(result, place, id) {
console.log('getAddressData was called with:', {result, place, id});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_HERE&libraries=places"></script>
<div id="app">
<vue-google-autocomplete
id="map"
class="form-control"
placeholder="Start typing"
@placechanged="getAddressData"
:country="['ie']"
/>
</div>
注意:仅适用于有效的API密钥。
如the docs中所述,除了使用Vue.component()
之外,您还可以使用普通的JavaScript对象:
const ADDRESS_COMPONENTS = {
//same as above...
};
const CITIES_TYPE = [
// same...
];
const REGIONS_TYPE = [
// same...
];
let VueGoogleAutocomplete = {
// exactly same contents from above, in the `Vue.component()` call...
}
new Vue.app({
el: '#app',
components: { VueGoogleAutocomplete }
})
请注意,在注册组件之前,必须先声明vue组件使用的const
(在.vue
文件中不会导出),因为该组件在内部使用它们。>