@takayuki-miura0203 さんが書いてくださったこちらの記事 Vue.js + Typescript のディレクトリ構造一例 を参考にVue3プロジェクトを作成していました。
plugins/materials のセクションで紹介されている、atoms、molecules 粒度のコンポーネントを
createApp(App)
.use(XXXX)
を使用してまるっとグローバルで使用できるように登録するコードが便利そうで組み込もうとしましたが、Vue3では以下のエラーが発生、解決のため調査をした。
ERROR in src/plugins/materials/index.ts:1:32
TS2307: Cannot find module 'vue/types/umd' or its corresponding type declarations.
> 1 | import { VueConstructor } from 'vue/types/umd'
| ^^^^^^^^^^^^^^^
2 |
3 | // @/plugins/materials 配下の全vueファイルを取得
4 | const context = require.context('.', true, /.vue$/)
結論として、以下の通り修正を行った。
import { App } from 'vue'
// @/plugins/materials 配下の全vueファイルを取得
const context = require.context('.', true, /.vue$/)
// eslint-disable-next-line
const components: { [key: string]: any } = {}
// 取得したコンポーネント一覧を、ファイル名がキーのオブジェクトに変換
context.keys().forEach(contextKey => {
const keys = contextKey.match(/.+\/(.+)\.vue/)
if (keys) {
const key = keys[1]
components[key] = context(contextKey).default
}
})
// ファイル名をキーとしたコンポーネントとしてグローバル登録
export default {
install(app: App) {
Object.keys(components).forEach(key => {
app.component(key, components[key])
})
},
}
修正した内容
- 呼び出されるinstallメソッドの引数は、VueConstructorから、Appに変わったので、その箇所とimportを修正。
-
typescript const components: { [key: string]: any } = {}
の箇所が以下、lintエラーになってしまった
/Users/quqjp/Documents/works/ymorimo/lounge-m/vq-frontend/src/plugins/materials/index.ts
9:36 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
解決方法が不明だったので、
// eslint-disable-next-line
で逃げています。。。
単体のコンポーネント登録
記事のタイトルと内容があまりマッチしていなそうなので、念の為単体のコンポーネント登録について書いておきます。
const app = createApp(App)
app.component('PopupWindow', PopupWindow)
main.ts に、createAppのコードがありますが、
componentメソッドで、コンポーネント名、コンポーネント実態を渡すことで、
vueファイルのscriptのcomponents でコンポーネントをいちいち登録せずともtemplate内で使用できるようになる。
参考ページ
How to Register a Vue3 Global Component
https://learnvue.co/2020/08/how-to-register-a-vue3-global-component/