【问题标题】:Vue.prototype.$property doesn't work with TypescriptVue.prototype.$property 不适用于 Typescript
【发布时间】:2019-09-17 11:56:10
【问题描述】:

在 main.ts 中:

Vue.prototype.$http = http

然后在另一个组件中,在一个类中我不能调用this.$http。我已经阅读了有关增强类型的信息,但不知道将文件放在哪里,如何调用它,关于这个主题的文档不是很清楚:https://vuejs.org/v2/guide/typescript.html#Augmenting-Types-for-Use-with-Plugins

所以我创建了一个文件'src/types/vue.d.ts':

import Vue from 'vue'
import http from '@/http'

declare module 'vue/types/vue' {
  interface Vue {
    $http: http
  }
}

http.ts 的内容:

import axios from 'axios'

const HTTP = axios.create({
  baseURL: process.env.VUE_APP_API_URL
})

export default {
  login(credentials: any) {
    return HTTP.post('/auth', {
      account_email: credentials.email,
      account_password: credentials.password
    })
  }
}

但我仍然不能在组件中使用this.$http。我的目标是在每个组件中全局使用 this.$http 引用 http.ts(此处为 axios 模块)。

【问题讨论】:

  • 但是为什么要扩充 Vue 类型呢?每个组件都需要http函数吗?您可以为 http 调用创建一个辅助类...
  • @Kokodoko,几乎每个组件都需要$http,在每个组件中都导入它很烦人。
  • 那些减去我的人,请解释你为什么这样做。

标签: typescript vue.js


【解决方案1】:

Vue 3 答案

增强 Vue 以支持您的自定义组件属性是通过 module augmentation 完成的。要添加您的 $http 声明并支持它,您可以创建 vue-shim.d.ts 文件并增加 vue/runtime-core

import axios from 'axios'

declare module '@vue/runtime-core' {
  export interface ComponentCustomProperties {
    $http: typeof axios
  }
}

Vue 还断言,对于版本 3,您必须将其导入或导出为 ts 文件中的顶级代码行,以确保将其视为模块:

确保声明文件是 TypeScript 模块 为了利用模块扩充,您需要确保文件中至少有一个顶级导入或导出,即使它只是 export {}。

现在,当您安装自定义插件时,您可以将其挂在 app.config.globalProperties 对象上:

// my-custom-plugin.js
import axios from 'axios'
import http from 'plugins/http'

export default {
  install (app, options) {
    app.config.globalProperties.$http = http
  }
}

请参阅下面的 Vue 2 答案。

Vue 2 答案

您不能将$http 的类型声明为值,而是进行新的类型:

// http.d.ts

export default interface {
  login(credentials: any): PromiseLike<any> 
}

然后将其用作您的打字声明:

import http from '@/types/http'

...
interface Vue {
  $http: http
}

现在请点击上面评论中的链接,创建您的http.ts

import _Vue from 'vue'
import axios from 'axios'

const http = {
  login(credentials: any) {
    return HTTP.post('/auth', {
      account_email: credentials.email,
      account_password: credentials.password
    })
  }
}

export function http(Vue: typeof _Vue): void {
  Vue.prototype.$http = http;
}        

现在您需要将http.ts 文件和Vue.use 导入main.ts 之类的文件中

import Http from '@/http'

Vue.use(Http)

现在你的组件可以使用你的 http 插件了:

mounted() {
  this.$http.login(credentials)
  .then((response) => console.log(response))
  .catch((error) => console.warn(error))
}

【讨论】:

  • 我是否必须将每个方法(从 http.ts)复制到接口?例如,如果我不仅有login,还有logingetUsers,等等。我必须在一个界面中描述它们吗?我也可以直接在 http.d.ts 中使用接口,对吧?
  • @AlexanderKim 你肯定需要复制它们。但你并没有真正复制它们,你是typing他们。您将希望对您希望公开的每种方法都执行此操作。你可以在http.d.ts中使用interfaces,是的
  • 谢谢,您不认为 TS 让生活变得复杂多于帮助吗?
  • 一点也不。强类型非常有用,尤其是在寻找错误时。我不会用它来换世界。通过点击 IDE 中的函数和属性来浏览 javascript,这简直是梦想成真。
  • OP 的疑惑就在这里。如果我们已经使用 typescript,为什么还需要创建外部类型?它要么是 typescript 要么是 vue 糟糕的设计。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 2019-05-30
相关资源
最近更新 更多