はじめに
Vueでそこそこの規模のサイト作ろうとするとき、index.html
にすべての処理を書き下すのではなく、コンポーネント別に.vue
ファイル、作りたいですよね。
Vue-CLIなら手順がいくらでもありますが、CDNの場合そんなに情報が見当たりません。
こちらはありますが、http-vue-loader
を用いているものはVue2限定です。
ということで、テンプレート化します。
結論
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>タイトル</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue3-sfc-loader/dist/vue3-sfc-loader.js"></script>
</script>
</head>
<body>
<div id="app"></div>
<script>
//vue3-sfc-loader初期設定
const options = {
moduleCache: {
vue: Vue
},
//read subdirectory vue component file.
async getFile(url) {
const res = await fetch(url);
if ( !res.ok )
throw Object.assign(new Error(res.statusText + ' ' + url), { res });
return {
getContentData: asBinary => asBinary ? res.arrayBuffer() : res.text(),
}
},
addStyle(textContent) {
const style = Object.assign(document.createElement('style'), { textContent });
const ref = document.head.getElementsByTagName('style')[0] || null;
document.head.insertBefore(style, ref);
},
}
const { loadModule } = window["vue3-sfc-loader"];
//Appコンポーネントをマウント
const app = Vue.createApp(
Vue.defineAsyncComponent(
() => loadModule("./src/components/App.vue", options)
),
)
app.mount('#app');
</script>
</body>
</html>
慣習に倣って、root
のdivをApp
コンポーネントにした例をご紹介していますが、マウントの処理は用途にあわせて編集して大丈夫です。
App.vue
<template>
</template>
<script>
export default Vue.defineComponent({
name: 'App',
components: {
"COMPONENT": Vue.defineAsyncComponent(() => loadModule("PATH.vue", options))
},
})
</script>
<style>
</style>
.vue
ファイルはCLIと同じように構成して大丈夫ですが、コンポーネントの読み込みはVue.defineAsyncComponent(() => loadModule("PATH.vue", options))
を用いることだけ注意してください。
解説
vue3-sfc-loaderを使います。これにより、CDNでも.vue
ファイルを読み込むことができます。
しかし、初期設定がhttp-vue-loader
と比べてメンドウなので、index.html
の初期設定のスクリプトはテンプレートと考えて大丈夫です。