简体   繁体   English

如何使用带有组合的 Vue 2 键入提示 vue 组件方法 API

[英]How to type hint a vue component method using Vue 2 with Composition API

I have two components <Modal> and <App> and I want to call a method of the Modal component.我有两个组件<Modal><App> ,我想调用 Modal 组件的方法。 The code works when adding @ts-ignore , but TypeScript is complaining.添加@ts-ignore时代码有效,但 TypeScript 正在抱怨。 I'm using Vue2 with Composition API.我正在使用 Vue2 和组合 API。

Simplified example (I'm leaving out app initialization):简化示例(我省略了应用程序初始化):

Modal.vue模态.vue

<template>
   <div ref="modalEl">I'm the modal<slot></slot></div>
</template>
<script lang="ts">
import {defineComponent, onMounted, ref} from '@vue/composition-api';
import Modal from 'bootstrap/js/dist/modal';

export default defineComponent({
    setup(props) {
       const modalEl = ref<Element | string>('');
       let modal: Modal;

       onMounted(() => {
          modal = new Modal(modalEl.value);
       });

       const show = () => modal.show();

       return {
          modalEl,
          show,
       } 
    }
});
</script>

App.vue App.vue

<template>
   <div>
       <Modal ref="modalSave">I'm modal content</Modal>
       <button @click="showModal">show modal</button>
   </div>
</template>
<script lang="ts">
import {ref,defineComponent} from '@vue/composition-api';
import Modal from 'Modal.vue';
export default defineComponent({
  components: {
      Modal
  },
  setup(props) {
      const modalSave = ref<InstanceType<typeof Modal> | null>(null);
      const showModal = () => modalSave.value?.show();

      return {
          modalSave,
          showModal
      }
  }
});

</script>

As mentioned, it works and I get even code completion in PhpStorm.如前所述,它可以工作,我什至可以在 PhpStorm 中完成代码。 But when I'm compiling I get the error:但是当我编译时出现错误:

ERROR in App.vue.ts(115,24) TS2339: Property 'show' does not exist on type '{ readonly $el: Element; App.vue.ts(115,24) TS2339 中的错误:属性“show”在类型“{readonly $el: Element; readonly $options: { data?: DefaultData |只读 $options: { data?: DefaultData | undefined;不明确的; props?: string[] |道具?:字符串[] | { [x: string]: Prop | { [x: 字符串]: 道具 | { type?: Prop | { 类型?:道具 | Prop[] |道具[] | undefined;不明确的; required?: boolean |需要吗?:boolean | undefined;不明确的; default?: any;默认值?:任何; validator?: ((value: any) => boolean) |验证器?: ((value: any) => boolean) | undefined;不明确的; } | } | Prop<...>[];道具<...>[]; } | } | undefined;不明确的; ... 35 more...'. ... 35 更多...'。

Does anyone know how to make TypeScript happy here without adding ts-ignore ?有谁知道如何在不添加ts-ignore情况下让 TypeScript 快乐?

You will need to use defineExpose ( docs ):您将需要使用defineExpose ( docs ):

<!-- MyModal.vue -->
<script setup lang="ts">
<template>
   <div ref="modalEl">I'm the modal<slot></slot></div>
</template>
<script lang="ts">
import {defineComponent, onMounted, ref} from '@vue/composition-api';
import Modal from 'bootstrap/js/dist/modal';

export default defineComponent({
    setup(props) {
       const modalEl = ref<Element | string>('');

       onMounted(() => {
          modal = new Modal(modalEl.value);
       });

       const show = () => modal.show();

       defineExpose({ show }); 👈

       return {
          modalEl,
          show,
       } 
    }
});
</script>
</script>

I was now able to solve it with (global) augmentation by putting this into a *.d.ts file.我现在可以通过将其放入 *.d.ts 文件中来使用(全局)扩充来解决它。 It's probably not the best solution, but as it's just temporary until the app is upgraded to vue3 it seems to be a simple solution without lots of rewriting:这可能不是最好的解决方案,但由于在应用程序升级到 vue3 之前它只是暂时的,因此它似乎是一个简单的解决方案,无需大量重写:

declare module 'vue/types/vue' {
    interface Vue {
        show: () => void
    }
}

export {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM