まず、普通にJavaScriptで書いた場合このようになります。
~/plugins/mixins.js
export const delayMixin = {
methods: {
$delay(ms): Promise {
return new Promise((resolve) => setTimeout(resolve, ms));
},
},
});
Component.vue
<script>
import { delayMixin } from '~/plugins/mixins';
export default {
mixins: [delayMixin],
methods: {
async animate() {
await this.$delay(100);
// ...
},
}
};
</script>
TypeScriptで書いた場合。
Vue.extendにして、Vueの型を拡張するようにします。
~/plugins/mixins.ts
import Vue from 'vue';
export const delayMixin = Vue.extend({
methods: {
$delay(ms: number): Promise<void> {
return new Promise<void>((resolve) => setTimeout(resolve, ms));
},
},
});
Vueインスタンスの this
に
as InstanceType<typeof Mixinの型>
として型を拡張します。
Component.vue
<script lang="ts">
import Vue from 'vue';
import { delayMixin } from '~/plugins/mixins';
export default Vue.extend({
mixins: [delayMixin],
methods: {
async animate() {
await (this as InstanceType<typeof delayMixin>).$delay(100);
// ...
},
}
});
</script>
ビルド時に.vueファイルを認識してくれない場合には、以下のようなvue-shims.d.tsを用意して読み込ませます。
vue-shims.d.ts
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
同じ要領で、Vueの親コンポーネントから子コンポーネントのメソッドを呼び出したいときには、以下のようにすればTypeScriptの型チェックでエラーがでなくなります。
TheParent.vue
<template>
<div>
<TheChild ref="childRef" />
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import TheChild from '~/components/TheChild.vue';
export default Vue.extend({
components: {
TheChild
},
methods: {
foo() {
(this.$refs.childRef as InstanceType<typeof TheChild>).doChildMethod();
}
}
});
</script>