Vue 3 + TypeScript 和增强类型与插件一起使用的问题

7

有没有人知道如何在Vue3和TypeScript中实现类型增强的可行示例?我一直在尝试按照Vue2文档的步骤来实现,但是没有成功,并且花了过去三个小时搜索也没有找到任何结果。

似乎应该通过vue-class-component模块中的Vue对象进行增强处理,但是如何实现呢?

我的实现方式与以下示例类似:

有什么建议吗?

https://v2.vuejs.org/v2/guide/typescript.html#Augmenting-Types-for-Use-with-Plugins

import { App, Plugin } from "vue";

export interface IHelloModule {
  sayHello: (name: string) => string;
}

export const helloPlugin: Plugin = (app: App, options) => {

  const helloModule:IHelloModule = {

    sayHello: function(name: string) {
      return `Hello ${name}`;
    }

  };

  app.provide("$hello", helloModule);
};

import { Vue } from 'vue-class-component';
import { IHelloModule } from "@/hello";

declare module "vue/types/vue" {
  interface Vue {
    $hello: IHelloModule;
  }
}

declare module "vue/types/vue" {
  interface VueConstructor {
    $auth: IHelloModule;
  }
}

<template>
  <div class="home">
     .....
  </div>
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component';

@Options({
  components: {
  },
})
export default class Home extends Vue {
  mounted() {
    console.log(this.$hello.sayHello("World"))
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
                     Neither TS nor vue-cli recognize this
  }
}
</script>

import { createApp } from "vue";
import App from "./App.vue";
import { helloPlugin } from "./hello";
import router from "./router";

createApp(App)
  .use(router, helloPlugin)
  .mount("#app");

1个回答

11

据我所知,vue-class-component目前还不完全支持Vue 3。他们仍在讨论库中的修改。 因此,我不知道下面的示例是否适用于它,但这是我用来增强插件类型的方法。

hello.plugin.ts

import { App } from "vue";

export interface IHelloModule {
  sayHello: (name: string) => string;
}

export default {
  install: (app: App) => {
    const helloModule: IHelloModule = {
      sayHello: function(name: string) {
        return `Hello ${name}`;
      }
    }; 

    app.config.globalProperties.$hello = helloModule;
  }
}

declare module "@vue/runtime-core" {
  //Bind to `this` keyword
  interface ComponentCustomProperties {
    $hello: IHelloModule;
  }
}

我在插件文件本身中声明了类型,但你也可以在shims-vue.d.ts文件中声明它们。

main.ts

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import Hello from "./hello.plugin";

createApp(App)
  .use(router)
  .use(Hello)
  .mount("#app");

你好.vue

<script lang="ts">
import { defineComponent } from "vue";

const Hello = defineComponent({
  mounted() {
    console.log(this.$hello.sayHello("World"));
  }
});

export default Hello;
</script>

1
我使用了其中一个 CLI 模板,HelloWorld 组件的代码如下: class HelloWorld extends Vue { msg!: string; }。在组件内部,我定义了 mounted 函数,并且编译器报错说 $ 变量(从你的示例中是 $hello)在 this 关键字上不存在。我对 Vue 不是很熟悉,所以不确定缺少什么,也没有找到太多关于 Vue + TS + 插件的资源。 - Rodrigo Gomez-Palacio
@RodrigoGomez-Palacio 抱歉,之前没有看到你的评论。也许是因为你正在使用类组件而不是函数组件?我已经不再使用Vue了,但据我所记,建议在Vue 3 + TS中使用defineComponent。 - A.Terra
你如何自动声明多个插件? - Pixsa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接