【问题标题】:Referencing data in Vue async function在 Vue 异步函数中引用数据
【发布时间】:2020-04-25 20:35:26
【问题描述】:

在我的一个组件中,我使用 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 并且我不知道我需要做什么才能让它工作。

干杯。

【问题讨论】:

    标签: typescript vue.js axios


    【解决方案1】:

    首先,你需要使用 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>
    

    【讨论】:

      猜你喜欢
      • 2018-11-16
      • 2020-05-12
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 2016-08-20
      • 2020-03-09
      • 2022-11-16
      • 1970-01-01
      相关资源
      最近更新 更多