基本編(コンポーネントの作り方)です。
この記事を読めば「膨大なindex.html
」から解放されます
命名規則(スネークケース、ケバブケース、キャメルケースの使い分け)がバックエンド言語に寄せていまして、推奨とはかなり違います。動作は問題ありません。
https://ja.vuejs.org/style-guide/rules-strongly-recommended.html
はじめに
HTML直書き、めんどくさいですよね
フロントエンド初心者のみなさん、HTML直書き楽しんでますか??
楽しんでないですよね(断定)
ページが大きくなればなるほど辛くなってきますよね
なぜ辛くなるのか当てましょう。
- 全てを1ファイルに書き、内容が膨れ上がるほどだんだん視認性・メンテナンス性が悪くなるから
- 同じような要素を再利用できないから
(template
を使うというのもありますが) - 変数が多くなればなるほど、更新時のコールバックなりのやりとりが多くなるから
当たりですか?
もう、苦しむのはやめませんか?やめましょう
Vueを使おう
Vue
を使いましょう。Vue
はいいものです。 こら、React
の方を向くんじゃない。今からVue
をするんや。
Vue
は先述した3論点を全て解決します。
すなわち、
- 部品ごとにHTMLもJavaScriptもCSSもまとめてファイルを分けられるため、視認性がとても良い
- 同じ部品を気楽に再利用でき、なんなら
for
文まで用意されている - 変数の更新時、依存したデータ自動で更新させることができる
ということができます。素敵ですね。
フレームワークは覚えること多いってよく聞きますよね?大丈夫!
今回は
- テキトーに!とりあえず
Vue
を扱えるように! - 環境構築は簡単(というか無し)に!
簡略化してお届けします。
使い方
環境構築
VSCode
をインストールして、拡張機能に
の2つを入れてください。終わり。
npm
? やりたかったらやってください。
理解不要テンプレート
こちらのレポジトリのディレクトリ構成でそのまま動きます:https://github.com/konbraphat51/Vue3_CDN_template
こちらにもスクリプトを掲載します
メインのHTMLとなるindex.html
、理解不要
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TITLE</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/vue-i18n@9"></script>
<script src="https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue3-sfc-loader/dist/vue3-sfc-loader.js"></script>
</head>
<body>
<div id="app"></div>
<script>
//initialize i18n
const i18n = VueI18n.createI18n({
legacy: false,
locale: navigator.language,
fallbackLocale: "en",
});
//initialize 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);
},
//read <i18n> tag
customBlockHandler(block, filename, options) {
if (block.type !== 'i18n')
return
const messages = JSON.parse(block.content);
for (let locale in messages)
i18n.global.mergeLocaleMessage(locale, messages[locale]);
}
}
const { loadModule } = window["vue3-sfc-loader"];
//Mount App.vue
const app = Vue.createApp(
Vue.defineAsyncComponent(
() => loadModule("./src/components/App.vue", options)
),
)
app.use(i18n);
</script>
<script src="./src/scripts/router.js"></script>
<script>
app.use(router)
app.mount('#app');
</script>
</body>
</html>
特に変更しなくともVue
は動作します。
ページタイトル変えたいときなどはどうぞ編集してください。
別にこれが何をするhtmlか理解しなくとも大丈夫なのですが、気になる人のために。
めっちゃ簡単に言えば、
- ネット上から
Vue
ライブラリを引っ張ってきて(CDNといいます)、 - 後述するコンポーネントを
div(id="app")
にマウント(ひっつけ)しています
いろいろスクリプトが長いのは、vue3-sfc-loader
のセットアップをしています。ファイル分けする場合Vue CDNは本来使うものではないですが、無理やり可能にしています。
こちらが我々が今から操作するコンポーネントのテンプレート
<template>
<!-- <div id="COMPONENT_NAME">
any HTML you want
<button id="example" @click="select('example')">{{ t("Example.button") }}</button>
<SUB_COMPONENT :sub_component_props_name:"example_parameter" @event_name="function_name()"/>
<SOMETHING v-for="example in example_list" :key="example.id" :example_props_name="example">
</div> -->
</template>
<script>
export default Vue.defineComponent({
name: 'COMOPNENT_NAME',
components: {
//"SUB_COMPONENT": Vue.defineAsyncComponent(() => loadModule("src/components/SUB_COMPONENT.vue", options)),
},
setup() {
//一番最初に走るjavascript
//i18n設定
const { t } = VueI18n.useI18n()
return { t }
},
mounted() {
//マウントされたときに走るjavascript。setup()より基本的にこれを使う。
},
updated() {
//表示内容が更新されたときに走るjavascript
},
data() {
//プライベート変数
return {
//example_variable: "example"
}
},
props: {
//コンポーネントの引数
// example_parameter: {
// type: String,
// required: true
// }
},
methods: {
// このコンポーネントのメソッド
// select(example) {
// this.$emit("onSelected", example)
// },
// example_method() {
//
// }
},
watch: {
// 変化監視
// example_variable: {
// handler: function (newVal, oldVal) {
// //script called when example_variable is changed
// },
// deep: true
// }
},
computed: {
// プライベート変数の一種。
// 中身の計算に使われている変数が更新されると、これを検知してこちらも更新される。
// example_computed() {
//
// return this.example_variable + " computed"
// }
}
})
</script>
<i18n>
{
"en": {
"Example": {
"button": "example"
}
},
"ja": {
"Example": {
"button": "例"
}
}
}
</i18n>
<style>
/*.COMPONENT_NAME {
font-size: 1.5em;
font-weight: bold;
}*/
</style>
これ見てヴゥエってなりましたか? 大丈夫です。このテンプレートをコピペして、お好きな箇所を付け足すだけで 大丈夫です。
難しそうに見えて、頭空っぽでできます
コンポーネントとは?
簡単に言うと 「部品」 であり、自作HTMLタグ ともいえます。
例えば、標準HTMLでは<button>
と書けば、「クリックするとイベントを発し、四角い枠で囲まれた文字列」がセットで設置されますよね?
こんなタグが作れます。例えば「クリックすると振動する説明文タグ」でもみたいな誰得HTMLタグでも。
例えばUserList
というコンポーネントを作れば、<UserList />
というタグを書けるようできるわけです。
これを使うことで、 デザインの再利用も簡単 になりますね。
そして、コンポーネントごとにファイルを作るので、 ファイルがかさばらずに、見たいところだけ見えて視認性が良く なりますね。
コンポーネントの作り方
まずは、拡張子が.vue
のファイルを良い感じのところに置いてください。慣習的には、src/components
ディレクトリに設置しますが、どこでもいいです。
上記TEMPLATE.vue
の中身をコピペしてください。
そして、下記の2点の操作をしてください:
-
<template>
の中身を、欲しいHTML
に書き換えてください。 -
<script>
の中、defineComponent
の中、name
を欲しいコンポーネント名にしてください。
これでコンポーネントの完成です。
ここでは例として、こんな例を用意しました。(不要な箇所は省略していますが、あってもいいです)
<template>
<div id="Tamago">
Tamago
</div>
</template>
<script>
export default Vue.defineComponent({
name: 'Tamago',
})
</script>
コンポーネントを表示させる
ドラクエでは装備を持つだけでは効果がないのと同じで、コンポーネントも作るだけでは意味がありません。(表示されません)
表示させるには、App
コンポーネントに追加させる必要があります
App.vue
をこのように編集(不要な箇所は削除していますが、あってもいいです)
<template>
<div id="app">
+ <Tamago />
</div>
</template>
<script>
export default Vue.defineComponent({
name: 'App',
components: {
+ "Tamago": Vue.defineAsyncComponent(() => loadModule("src/components/Tamago.vue", options)),
},
})
</script>
loadModule()
のパスに注意。
options
はグローバル変数なので思考停止で書いてください。
ちなみに、コンソールがこのような感じで表示されますが、健全です。(無理してファイル分けしているのでね。しかし全然問題ありません)
重要なところは3点。
-
App.vue
の<template>
はページ全体のHTML。
index.html
をそのままにしていたら、ですけど。 - コンポーネントAにコンポーネントBを取り込むには、
components
に
"Tamago": Vue.defineAsyncComponent(() => loadModule("src/components/Tamago.vue", options))
を追加する。
コピペ呪文で大丈夫です。 キー名をコンポーネント名に、パスはもちろん.vue
ファイルの場所、options
はグローバル変数です。 - コンポーネントを作れば、
<(コンポーネント名) />
タグを使える
最後の/
に注意してください。
コンポーネントにスタイルを付加する
もうお気づきかとおもいますけど、<styles>
に **そのままCSS
を書けば大丈夫です。
Copilot
を使っていれば、普通にCSS書くよりもかなり当意即妙のスタイリングをしてくれます。
例えば、このサイトのCSSはほぼ全てCopilot
が書いてくれました:
https://konbraphat51.github.io/HSS_examples/
今回はここまで
今あなたができるようになったこと
超簡単に、HTMLを部品に分割することができるようになりました。
デカいindex.html
とはもうおさらばです。
これからは、積極的にwebページをコンポーネントに分解し、気持ちよく、頭空っぽでページを作りましょう。
Vue
最高!!
次回予告
テンプレートにある通り、まだまだ機能がいっぱいあります。
次回は、変数・データのコンポーネント間の受け渡しを扱います。
いいね頂けると泣きながら喜びます><