1

我很陌生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&region=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,但它仍然引发错误:

在此处输入图像描述

4

2 回答 2

0

尝试

Vue.use(vue-google-autocomplete)

您可能需要替换名称。

importJavaScript 解释器无法识别。它需要先被转译。

如果您想使用import,您必须创建一个文件(即 main.js)并将其包含在您的 HTML 文件中,如下所示:

<script type="module" src="main.js"></ 
于 2019-09-21T11:51:46.073 回答
0

您不能.vue从外部 url 导入/加载文件。

这样做的干净方法是将.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 }

在此处查看一个工作示例。如果您在public/index.html.

我将文件导入/App.vue并保存到components/VueGoogleAutocomplete.vue.

还有一件事:如果你async在 maps js 链接上使用,你的.vue组件会抱怨google对象没有被定义。基本上,您希望保持安装 VueGoogleAutocomplete 直到地图 js 加载(使用 av-if和辅助模型属性,或者不要async在地图 js 脚本上使用)。


如果您想在单个文件中执行此操作,请按以下步骤操作(基本上定义一个 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 密钥。


文档中所述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 }
})

注意constvue 组件使用的 s (在.vue文件中没有导出),需要在注册组件之前声明,因为组件在内部使用它们。

于 2019-09-22T03:27:23.073 回答