【问题标题】:Importing Vue JS component raises "Uncaught SyntaxError: Unexpected identifier"导入 Vue JS 组件引发“Uncaught SyntaxError: Unexpected identifier”
【发布时间】:2019-09-21 11:38:52
【问题描述】:

我对@9​​87654323@ 很陌生,我正在尝试在我的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 之后导入它,但它仍然会引发错误:

【问题讨论】:

    标签: javascript html vue.js


    【解决方案1】:

    试试

    Vue.use(vue-google-autocomplete)

    您可能需要替换名称。

    import 无法被 JavaScript 解释器识别。需要先转译。

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

    <script type="module" src="main.js"></ 
    

    【讨论】:

    • 我创建了 create.js 并使用了 Vue.use('vue-google-autocomplete') 但组件根本没有加载。
    • 从源码看,组件的名字是VueGoogleAutocomplete。也许 Vue.use(VueGoogleAutocomplete)
    【解决方案2】:

    您无法从外部 URL 导入/加载 .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

    还有一件事:如果您在地图 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组件使用的consts(在.vue文件中没有导出),需要在注册组件之前声明,因为组件在内部使用它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 2015-12-30
      • 1970-01-01
      • 2018-08-21
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多