繰り返しで長いコードにはVue.jsのtemplateを使用

Vue.jsプログラミング備忘録
https://jp.vuejs.org/からの画像
スポンサーリンク

どうも、ちゃんカマでございます。

もしかして、HTMLで同じような内容のコードを繰り返しで書いていませんか?
「何度も繰り返して使うコードは、テンプレ化が出来れば良いのに・・・」と思っていませんか?
それならVue.jsのtemplate(テンプレート)を使うと良いですよ。

私は点数計算を行うWebアプリを制作する過程で、Vue.jsのtemplate(テンプレート)を使いました。
その結果、何度も繰り返して使うHTMLコードをテンプレ化することが出来ましたよ。
テンプレ化が出来るとコードはスッキリとするし、後からのメンテナンスも楽ですよね。

そこで今回はVue.jsのtemplateを使って、繰り返しで使用するHTMLコードをテンプレ化する方法について解説します。

ちなみに私が作ったアプリはこんな感じです。( ↓ GIF動画参照)

点数計算アプリの動作の様子
点数計算アプリの動作の様子

「+」や「ー」のボタンを押すと数字がカウントされて、その合計や条件に応じた加算点を自動で計算する、というアプリです。

この記事ではこんな疑問や悩みにお答えします
  • Vue.jsのtemplateの使用方法を知りたい
  • 長くなったHTMLをスッキリさせたい
  • コードをテンプレ化して、メンテナンスを楽に行いたい
この記事の内容
  • Vue.jsのtemplateの使用方法
  • テンプレ化したコードを、slotを使用して編集する方法

テンプレ化する前のコード

HTMLをそのまま書いている、テンプレ化する前のコードです。
下記に記載します。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>

	<!-- Normalize CSS -->
	<link rel="stylesheet" href="normalize.css">

	<!-- Bootstrap CSS -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">

	<!-- Style CSS -->
	<link rel="stylesheet" href="style.css">

	<!-- Vue.js(本番用) -->
	<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script> -->

	<!-- Vue.js(開発用) -->
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
	<table class="table table-bordered table-striped">
		<thead class="thead-light">
			<tr>
				<th class="col-sm"></th>
				<th class="col-lg">ゲート1</th>
				<th class="col-lg">ゲート2</th>
				<th class="col-lg">ゲート3</th>
				<th class="col-lg">ゲート4</th>
				<th class="col-lg">ゴール</th>
				<th class="col-md">総打数</th>
				<th class="col-md">加算点</th>
				<th class="col-md">Total</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<th>Aさん</th>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						ゴールイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>総打数</td>
				<td>加算点</td>
				<td>Total</td>
			</tr>
			<tr>
				<th>Bさん</th>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						フープイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>
					<form>
						打数
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-primary btn-up">+</button>
							</div>
							<input type="number" min="0" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-down">-</button>
							</div>
						</div>
					</form>
					<form>
						ゴールイン
						<div class="form-group input-group">
							<div class="input-group-prepend">
								<button type="button" class="btn btn-info btn-add">○</button>
							</div>
							<input type="text" disabled class="form-control">
							<div class="input-group-append">
								<button type="button" class="btn btn-secondary btn-remove">☓</button>
							</div>
						</div>
					</form>
				</td>
				<td>総打数</td>
				<td>加算点</td>
				<td>Total</td>
			</tr>
		</tbody>
	</table>

	<!-- Bootstrap JavaScript -->
	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>

	<!-- Main.js -->
	<script src="main.js"></script>
</body>
</html>
style.css
@charset "UTF-8";

body {
	min-width: 1024px;
}

.col-sm {
	width: 8%;
}

.col-lg {
	width: 14%;
}

.col-md {
	width: 8%;
}

input[type="number"][disabled],
input[type="text"][disabled]{
	background-color: #fff;
}

.btn-up,
.btn-down,
.btn-add,
.btn-remove {
	width: 37px;
}

上記のコードでページを表示すると、このようになります。

アプリ外観

同じコードを繰り返し書いていて、とても長いです。
見た目が良くないし、これではメンテナンスも大変ですね。

そこで、繰り返し書いている部分をテンプレ化して、スッキリとしたコードにしたいと思います。

テンプレ化したい部分を確認

前述のindex.htmlの中で、テンプレ化したい部分を確認します。
下記になります。

index.html
<form>
	打数
	<div class="form-group input-group">
		<div class="input-group-prepend">
			<button type="button" class="btn btn-primary btn-up">+</button>
		</div>
		<input type="number" min="0" disabled class="form-control">
		<div class="input-group-append">
			<button type="button" class="btn btn-secondary btn-down">-</button>
		</div>
	</div>
</form>
<form>
	フープイン
	<div class="form-group input-group">
		<div class="input-group-prepend">
			<button type="button" class="btn btn-info btn-add">○</button>
		</div>
		<input type="text" disabled class="form-control">
		<div class="input-group-append">
			<button type="button" class="btn btn-secondary btn-remove">☓</button>
		</div>
	</div>
</form>

上記は、「打数」と「フープイン(ゴールイン)」のカウンターを表示しているコードです。

これが1行に5箇所、2行あるので5箇所 ✕ 2行で10箇所も同じコードが書かれています。
コードが長くなっている原因はこれですね。
そこで、この部分をテンプレ化します。

Vue.jsのtemplateでコードをテンプレ化

Vue.jsのコンポーネントを作成

Vue.jsのtemplateとは、「Vue.jsのコンポーネントのtemplateオプション」のことです。
コンポーネントとは繰り返し使えるインスタンスのことです。
コンポーネントには、templateの他にもデータを渡せるdataオプションや、計算を実行させるcomputedオプションなどがあります。

では、実際にVue.jsのコンポーネントを作成します。
打数のカウンター表示のコードをテンプレ化するために「counterHit」、フープインのカウンター表示には「hoopIn」というコンポーネントを作成します。

main.jsに下記のコードを書きます。

main.js
const counterHit = {

};

const hoopIn = {

};

このようにコンポーネントをオブジェクトとして定義します。
上記のコードで、「counterHit」と「hoopIn」という名前のコンポーネントを作成出来ました。

コンポーネントにtemplateオプションを指定

作成したコンポーネントにtemplateオプションを指定します。
templateオプションは指定したHTMLコードをテンプレ化し、繰り返し使えるようにしてくれます。

下記のとおりにコードを書き加えます。

main.js
const counterHit = {
	template: `
		<form>
			打数
			<div class="form-group input-group">
				<div class="input-group-prepend">
					<button type="button" class="btn btn-primary btn-up">+</button>
				</div>
				<input type="number" min="0" disabled class="form-control">
				<div class="input-group-append">
					<button type="button" class="btn btn-secondary btn-down">-</button>
				</div>
			</div>
		</form>
	`,
};

const hoopIn = {
	template: `
		<form>
			フープイン
			<div class="form-group input-group">
				<div class="input-group-prepend">
					<button type="button" class="btn btn-info btn-add">○</button>
				</div>
				<input type="text" disabled class="form-control">
				<div class="input-group-append">
					<button type="button" class="btn btn-secondary btn-remove">☓</button>
				</div>
			</div>
		</form>
	`,
};

上記のように、template:の後にテンプレ化したいHTMLのコードを指定すればOKです。
改行が反映されるように、「`・・・・・`」のようにテンプレート文字列で書くことがポイントです。

では、テンプレ化したコードをindex.htmlで使用できるようにします。
そのためにはindex.htmlの中の、テンプレを使用する箇所をVue.jsの管理下に置きます。

難しく思えるかもしれませんが、具体的にはHTMLの要素にクラス名を指定し、そのクラス名の要素内をVue.jsの管理下に置くコードを書けば良いだけです。

下記のとおりにコードを書き加えます。

index.html
<!-- 省略 -->

<body>
	<table class="table table-bordered table-striped">
		<thead class="thead-light">
			<tr>
				<th class="col-sm"></th>
				<th class="col-lg">ゲート1</th>
				<th class="col-lg">ゲート2</th>
				<th class="col-lg">ゲート3</th>
				<th class="col-lg">ゲート4</th>
				<th class="col-lg">ゴール</th>
				<th class="col-md">総打数</th>
				<th class="col-md">加算点</th>
				<th class="col-md">Total</th>
			</tr>
		</thead>
		<tbody class="row-item">
			<tr>
				<th>Aさん</th>
				<td>

<!-- 省略 -->

				</td>
				<td>総打数</td>
				<td>加算点</td>
				<td>Total</td>
			</tr>
		</tbody>
	</table>

<!-- 省略 -->

</body>

テンプレ化したコードは<tbody>の<td></td>内で使用したいので、ここでは<td>タグよりも親の要素である<tbody>タグに、「class=”row-item”」を与えました。

<tbody class="row-item">

では、この「class=”row-item”」を与えた<tbody></tbody>内をVue.jsの管理下に置きます。
下記のとおりにコードを書き加えます。

main.js
const counterHit = {
	template: `
		<form>
			打数
			<div class="form-group input-group">
				<div class="input-group-prepend">
					<button type="button" class="btn btn-primary btn-up">+</button>
				</div>
				<input type="number" min="0" disabled class="form-control">
				<div class="input-group-append">
					<button type="button" class="btn btn-secondary btn-down">-</button>
				</div>
			</div>
		</form>
	`,
};

const hoopIn = {
	template: `
		<form>
			フープイン
			<div class="form-group input-group">
				<div class="input-group-prepend">
					<button type="button" class="btn btn-info btn-add">○</button>
				</div>
				<input type="text" disabled class="form-control">
				<div class="input-group-append">
					<button type="button" class="btn btn-secondary btn-remove">☓</button>
				</div>
			</div>
		</form>
	`,
};

new Vue({
	el: '.row-item',
	components: {
		'counter-hit': counterHit,
		'hoop-in': hoopIn,
	},
});

先程のmain.jsにnew Vue以降を書き加えています。

new Vue({
	el: '.row-item',
	components: {
		'counter-hit': counterHit,
		'hoop-in': hoopIn,
	},
});

new Vueの中で「el: ‘.row-item’」とすることで、index.html内の「class=”row-item”」の<tbody>要素をVue.jsの管理下に置くことが出来ます。

さらに「components:」で、テンプレ化したコードをhtmlタグとして使えるようになります。
上記のコードでは、<counter-hit></counter-hit>と<hoop-in></hoop-in>いうタグで、テンプレ化したコードを使うことが出来ます。

ちなみに、htmlタグは<counter-hit>のようにケバブケースで書きます。
<counterHit>のようなキャメルケースでは、htmlタグとして認識されません。

さらに、<counter>のような1文字のタグも推奨されません。
これは、例えば将来HTMLのバージョンが更新された時に、新しく<counter>というタグが出てきた場合に、かぶってしまうことを防ぐためです。
そのため、テンプレ化したhtmlタグは必ず「-」(ハイフン)が入ったケバブケースで書くようにします。

では、index.htmlを書き換えてみます。

index.html
<table class="table table-bordered table-striped">
	<thead class="thead-light">
		<tr>
			<th class="col-sm"></th>
			<th class="col-lg">ゲート1</th>
			<th class="col-lg">ゲート2</th>
			<th class="col-lg">ゲート3</th>
			<th class="col-lg">ゲート4</th>
			<th class="col-lg">ゴール</th>
			<th class="col-md">総打数</th>
			<th class="col-md">加算点</th>
			<th class="col-md">Total</th>
		</tr>
	</thead>
	<tbody class="row-item">
		<tr>
			<th>Aさん</th>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>総打数</td>
			<td>加算点</td>
			<td>Total</td>
		</tr>
		<tr>
			<th>Bさん</th>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>総打数</td>
			<td>加算点</td>
			<td>Total</td>
		</tr>
	</tbody>
</table>

長かったコードを、スッキリと書き直すことが出来ました。
ページを表示させてみます。

テンプレ化後もきちんとページは表示されている
テンプレ化後もきちんとページは表示されている

テンプレ化する前と同じように、ページがきちんと表示されていますね。
ブラウザのデベロッパーツールで確認すると、<counter-hit>や<hoop-in>のタグの箇所に、テンプレ化したhtmlが生成されているのが分かります。

ただし、ここで1つ問題が・・・。
実はゴールの箇所のフープインのカウンターは、本当は「ゴールイン」と表示させたいんですね。

このように、テンプレ化したhtmlの一部の箇所だけは編集できるようにしたい場合に、Vue.jsには良い機能があります。
それは<slot>という機能です。

テンプレ化したコードをちょこっとだけ編集したい場合はslotを使う

では、Vue.jsのslotを使って、テンプレ化したコードの一部を編集できるようにします。

今回編集したいのは、<hoop-in>でテンプレ化したコードの「フープイン」という文字の箇所です。
その箇所を<slot></slot>で囲みます。

下記のとおりにコードを書き換えます。

main.js
const hoopIn = {
	template: `
		<form>
			<slot>フープイン</slot>
			<div class="form-group input-group">
				<div class="input-group-prepend">
					<button type="button" class="btn btn-info btn-add">○</button>
				</div>
				<input type="text" disabled class="form-control">
				<div class="input-group-append">
					<button type="button" class="btn btn-secondary btn-remove">☓</button>
				</div>
			</div>
		</form>
	`,
};

「フープイン」の文字を<slot></slot>で囲んでいます。

<slot>フープイン</slot>

では、index.htmlを編集して、ゴールのカウンターには「ゴールイン」の文字を表示させたいと思います。
下記のとおりにコードを書き換えます。

index.html
<table class="table table-bordered table-striped">
	<thead class="thead-light">
		<tr>
			<th class="col-sm"></th>
			<th class="col-lg">ゲート1</th>
			<th class="col-lg">ゲート2</th>
			<th class="col-lg">ゲート3</th>
			<th class="col-lg">ゲート4</th>
			<th class="col-lg">ゴール</th>
			<th class="col-md">総打数</th>
			<th class="col-md">加算点</th>
			<th class="col-md">Total</th>
		</tr>
	</thead>
	<tbody class="row-item">
		<tr>
			<th>Aさん</th>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in>ゴールイン</hoop-in>
			</td>
			<td>総打数</td>
			<td>加算点</td>
			<td>Total</td>
		</tr>
		<tr>
			<th>Bさん</th>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in></hoop-in>
			</td>
			<td>
				<counter-hit></counter-hit>
				<hoop-in>ゴールイン</hoop-in>
			</td>
			<td>総打数</td>
			<td>加算点</td>
			<td>Total</td>
		</tr>
	</tbody>
</table>

ゴールの箇所の<hoop-in></hoop-in>タグの間に、「ゴールイン」という文字を書き加えています。

<hoop-in>ゴールイン</hoop-in>

ページを表示させてみます。

ゴールインと表示させることが出来た
ゴールインと表示させることが出来た

ゴールの箇所のカウンターにのみ、「ゴールイン」という文字を表示させることが出来ました。

このように<slot>を使うと、テンプレ化したコードの一部を編集出来るようになります。

完成コードを記載

テンプレ化が完了したコードを下記に記載します。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>

	<!-- Normalize CSS -->
	<link rel="stylesheet" href="normalize.css">

	<!-- Bootstrap CSS -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">

	<!-- Style CSS -->
	<link rel="stylesheet" href="style.css">

	<!-- Vue.js(本番用) -->
	<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script> -->

	<!-- Vue.js(開発用) -->
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
	<table class="table table-bordered table-striped">
		<thead class="thead-light">
			<tr>
				<th class="col-sm"></th>
				<th class="col-lg">ゲート1</th>
				<th class="col-lg">ゲート2</th>
				<th class="col-lg">ゲート3</th>
				<th class="col-lg">ゲート4</th>
				<th class="col-lg">ゴール</th>
				<th class="col-md">総打数</th>
				<th class="col-md">加算点</th>
				<th class="col-md">Total</th>
			</tr>
		</thead>
		<tbody class="row-item">
			<tr>
				<th>Aさん</th>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in>ゴールイン</hoop-in>
				</td>
				<td>総打数</td>
				<td>加算点</td>
				<td>Total</td>
			</tr>
			<tr>
				<th>Bさん</th>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in></hoop-in>
				</td>
				<td>
					<counter-hit></counter-hit>
					<hoop-in>ゴールイン</hoop-in>
				</td>
				<td>総打数</td>
				<td>加算点</td>
				<td>Total</td>
			</tr>
		</tbody>
	</table>

	<!-- Bootstrap JavaScript -->
	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>

	<!-- Main.js -->
	<script src="main.js"></script>
</body>
</html>
main.js
const counterHit = {
	template: `
		<form>
			打数
			<div class="form-group input-group">
				<div class="input-group-prepend">
					<button type="button" class="btn btn-primary btn-up">+</button>
				</div>
				<input type="number" min="0" disabled class="form-control">
				<div class="input-group-append">
					<button type="button" class="btn btn-secondary btn-down">-</button>
				</div>
			</div>
		</form>
	`,
};

const hoopIn = {
	template: `
		<form>
			<slot>フープイン</slot>
			<div class="form-group input-group">
				<div class="input-group-prepend">
					<button type="button" class="btn btn-info btn-add">○</button>
				</div>
				<input type="text" disabled class="form-control">
				<div class="input-group-append">
					<button type="button" class="btn btn-secondary btn-remove">☓</button>
				</div>
			</div>
		</form>
	`,
};

new Vue({
	el: '.row-item',
	components: {
		'counter-hit': counterHit,
		'hoop-in': hoopIn,
	},
});

おわりに

HTMLのコードを、Vue.jsのtemplateを使用してテンプレ化する方法について解説してみました。
コードをテンプレ化すると短くスッキリと書けるし、メンテナンスも楽になりますよね。

今回の記事が皆さんの参考になれば幸いです。
以上、ちゃんカマでした。

コメント

タイトルとURLをコピーしました