在Vue异步功能中引用数据

时间:2020-01-08 10:13:04

标签: typescript vue.js axios

在我的组件之一中,我使用Axios从各种api来源获取响应。投放服务时一切正常,但构建时却不行。

我相信这是因为我不了解如何使用Vue正确执行异步功能,以使其符合TypeScript类型检查并尝试了各种尝试,但到目前为止没有成功。

checkin.vue

<script lang="ts">
import axios from "axios";

export default {
  name: "checkin",
  components: {},
  data() {
    return {
      myCoordinates: {
        longitude: "",
        latitude: ""
      },
      myAddress: {
        city: "",
        country: "",
        country_code: "",
        county: "",
        neighbourhood: "",
        postcode: "",
        road: "",
        state: ""
      },
      addressName: "",
      timeZone: "",
      currentTime: "",
      temperature: "",
      description: ""
    };
  },
  methods: {
    fetchDetails() {
      this.setAddress();
      this.setTimezone();
      this.setWeather();
    },
    addCheckin() {
      const checkInDetails = {
        long: this.myCoordinates.longitude,
        lat: this.myCoordinates.latitude,
        localDate: this.currentTime,
        timezone: this.timeZone,
        city: this.myAddress.city || "undefined",
        state: this.myAddress.state || "undefined",
        country: this.myAddress.country || "undefined",
        temperature: this.temperature,
        description: this.description || "undefined"
      };
      console.log(checkInDetails);
      this.$store.dispatch("addCheckIn", checkInDetails);
    },

    async setCoordinates() {
      const coordinates: any = await this.currentCoordinates();
      this.myCoordinates.latitude = coordinates.latitude;
      this.myCoordinates.longitude = coordinates.longitude;
      return coordinates;
    },
    async setAddress() {
      const address = await this.addressByCoordinates();
      return address;
    },
    async setTimezone() {
      const getTimezone = await this.timezoneByCordinates();
      return getTimezone;
    },
    async setWeather() {
      const weather = await this.weatherByCoordinates();
      return weather;
    },
    async currentCoordinates() {
      return new Promise((resolve, reject) => {
        navigator.geolocation.getCurrentPosition(
          ({ coords }) => resolve(coords),
          error => reject(error)
        );
      });
    },
    addressByCoordinates: async function() {
      await axios
        .get("https://nominatim.openstreetmap.org/reverse",{
          params: {
            format: "jsonv2",
            lat: this.myCoordinates.latitude,
            lon: this.myCoordinates.longitude,
            "accept-language": "en",
          }
        })
        .then(response => {
          console.log("response", response);
          this.addressName = response.data.display_name;
          this.myAddress = response.data.address;
        })
        .catch(error => {
          console.log("error ", error);
        });
    },
    timezoneByCordinates: async function() {

      await axios
        .get("http://api.timezonedb.com/v2.1/get-time-zone", {
          params: {
            key: "KEY",
            format: "json",
            by: "position",
            lat: this.myCoordinates.latitude,
            lng: this.myCoordinates.longitude
          }
        })
        .then(response => {
          console.log("response", response);
          this.timeZone = response.data.abbreviation;
          this.currentTime = response.data.formatted;
        })
        .catch(error => {
          console.log("error ", error);
        });
    },
    weatherByCoordinates: async function() {

      await axios
        .get("https://api.openweathermap.org/data/2.5/weather", {
          params: {
            lat: this.myCoordinates.latitude,
            lon: this.myCoordinates.longitude,
            appid: "APPID",
            units: "metric"
          }
        })
        .then(response => {
          console.log("response", response);
          this.temperature = response.data.main.temp;
        })
        .catch(error => {
          console.log("error ", error);
        });
    }
  }, // end of methods
  mounted() {
    this.setCoordinates();
  },
};
</script>

当我尝试执行npm run build时,会出现如下错误消息:

175:23 Property 'myCoordinates' does not exist on type '{ fetchDetails(): void; addCheckin(): void; setCoordinates(): Promise<any>; setAddress(): Promise<void>; setTimezone(): Promise<void>; setWeather(): Promise<...>; currentCoordinates(): Promise<...>; addressByCoordinates: () => Promise<...>; timezoneByCordinates: () => Promise<...>; weatherByCoordinates: () => Promis...'. Did you mean 'setCoordinates'?
    173 |           params: {
    174 |             format: "jsonv2",
  > 175 |             lat: this.myCoordinates.latitude,
        |                       ^
    176 |             lon: this.myCoordinates.longitude,
    177 |             "accept-language": "en"
    178 |           }

283:10 Property 'setCoordinates' does not exist on type '{ name: string; components: {}; data(): { myCoordinates: { longitude: string; latitude: string; }; myAddress: { city: string; country: string; country_code: string; county: string; neighbourhood: string; postcode: string; road: string; state: string; }; ... 4 more ...; description: string; }; methods: { ...; }; moun...'.
    281 |   }, // end of methods
    282 |   mounted() {
  > 283 |     this.setCoordinates();
        |          ^
    284 |   },
    285 |   computed: {}
    286 | };

我也尝试了如下功能,但这是同样的问题

    async addressByCoordinates() {
      ...
    },

调试日志指出以下内容:

16 verbose Windows_NT 10.0.18362
17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\ashle_000\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "run" "build"
18 verbose node v12.14.1
19 verbose npm  v6.13.4
20 error code ELIFECYCLE
21 error errno 1
22 error travelling@0.1.0 build: `vue-cli-service build`
22 error Exit status 1
23 error Failed at the travelling@0.1.0 build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

我研究了ELIFECYCLE并尝试了一些建议(清理缓存,删除node_modules,再次安装等),但并不高兴。

数据本身很好,只是不能让我运行npm run build,而且我不知道要使它正常工作需要做什么。

干杯。

1 个答案:

答案 0 :(得分:0)

正确,您需要使用Vue.extend方法才能allow Typescript to infer types

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
    name: "checkin",
    components: {},
    methods: {
        // ...
    },
});
</script>

您还需要设置数据对象的数据类型。为数据功能的返回对象添加类型注释。

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({    
    data(): {
        myCoordinates: {
            longitude: string,
            latitude: string,
        },
        // add the rest of data types
        // ....
    } {
      return {
        myCoordinates: {
          longitude: "",
          latitude: ""
        },
        myAddress: {
          city: "",
          country: "",
          country_code: "",
          county: "",
          neighbourhood: "",
          postcode: "",
          road: "",
          state: ""
        },
        addressName: "",
        timeZone: "",
        currentTime: "",
        temperature: "",
        description: ""
      };
    },
});
</script>