【Vue入門】Vueついて学ぶ /v-bind v-on v-model v-for v-ifなどの実用例あり!
今回は-bind v-on v-model v-for v-ifについての紹介です。
v-bindとは
v-bind
は、Vue.jsにおいてHTML属性に対してデータを動的にバインドするためのディレクティブです。
v-bindを使用することで、変数を特定の値やオブジェクトに関連付けることができる属性のことです。
v-bindが難しく感じるかもしれないので、
まずはこのコードを見てから説明を見てください。
以下のコードは同じ意味です。
<div v-bind:id="vueId"></div>
<div id="vueId">
もっと例を出すとこんな感じです。
これだとわかりやすいですね?
<!-- v-bind を使用して動的にid属性を変更 -->
<div v-bind:id="hoge"></div>
<!-- v-bind を使用しない場合の名前 -->
<div id="hoge"></div>
<!-- v-bind を使用して動的にhref属性を変更 -->
<a v-bind:href="hoge">Visit the website</a>
<!-- v-bind を使用しない場合の名前 -->
<a href="hoge">Visit the website</a>
<!-- v-bind を使用して動的にdisabled属性を変更 -->
<button v-bind:disabled="hoge">Click me</button>
<!-- v-bind を使用しない場合の名前 -->
<button disabled>Click me</button>
<!-- v-bind を使用して動的にplaceholder属性を変更 -->
<input v-bind:placeholder="hoge">
<!-- v-bind を使用しない場合の名前 -->
<input placeholder="hoge">
<!-- v-bind を使用して動的にsrc属性を変更 -->
<img v-bind:src="hoge" alt="Dynamic Image">
<!-- v-bind を使用しない場合の名前 -->
<img src="hoge" alt="Static Image">
<!-- v-bind を使用して動的にtitle属性を変更 -->
<button v-bind:title="hoge">Hover me</button>
<!-- v-bind を使用しない場合の名前 -->
<button title="hoge">Hover me</button>
<!-- v-bind を使用して動的にstyle属性を変更 -->
<div v-bind:style="{ width: hoge + 'px' }">Resizable Container</div>
<!-- v-bind を使用しない場合の名前 -->
<div style="width: hoge;">Fixed-width Container</div>
<!-- v-bind を使用して動的にdata-*属性を変更 -->
<div v-bind:data-id="hoge">Item</div>
<!-- v-bind を使用しない場合の名前 -->
<div data-id="hoge">Item</div>
<!-- v-bind を使用して動的にtextContentを変更 -->
<p v-bind:textContent="hoge">Dynamic Text</p>
<!-- v-bind を使用しない場合の名前 -->
<p>Static Text</p>
<!-- v-bind を使用して動的にaria-label属性を変更 -->
<button v-bind:aria-label="hoge">Click me</button>
<!-- v-bind を使用しない場合の名前 -->
<button aria-label="hoge">Click me</button>
<!-- v-bind を使用して動的にrole属性を変更 -->
<div v-bind:role="hoge">Content</div>
<!-- v-bind を使用しない場合の名前 -->
<div role="hoge">Content</div>
<!-- v-bind を使用して動的にdata-custom属性を変更 -->
<span v-bind:data-custom="hoge">Custom Data</span>
<!-- v-bind を使用しない場合の名前 -->
<span data-custom="hoge">Custom Data</span>
v-bindの略記と非略記法の書き方
v-bindは略記法でかくこともできます。
<!-- 非略記法 -->
<a v-bind:href="url">Click me</a>
<!-- 略記法 -->
<a :href="url">Click me</a>
<!-- 非略記法 -->
<img v-bind:src="imageSource">
<!-- 略記法 -->
<img :src="imageSource">
<!-- 非略記法 -->
<div v-bind:class="{ active: isActive, 'text-danger': hasError }">Hello</div>
<!-- 略記法 -->
<div :class="{ active: isActive, 'text-danger': hasError }">Hello</div>
<!-- 非略記法 -->
<div v-bind:style="{ color: textColor, fontSize: fontSize + 'px' }">Styled text</div>
<!-- 略記法 -->
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">Styled text</div>
<!-- 動的な属性のバインディング -->
<!-- 非略記法 -->
<img v-bind:src="imageSource">
<!-- 略記法 -->
<img :src="imageSource">
<!-- クラスのバインディング -->
<!-- 非略記法 -->
<div v-bind:class="{ active: isActive, 'text-danger': hasError }">Hello</div>
<!-- 略記法 -->
<div :class="{ active: isActive, 'text-danger': hasError }">Hello</div>
<!-- スタイルのバインディング -->
<!-- 非略記法 -->
<div v-bind:style="{ color: textColor, fontSize: fontSize + 'px' }">Styled text</div>
<!-- 略記法 -->
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">Styled text</div>
<!-- 属性のバインディング -->
<!-- 非略記法 -->
<input v-bind:disabled="isDisabled" />
<!-- 略記法 -->
<input :disabled="isDisabled" />
<!-- ダイナミックなタグ名の指定 -->
<!-- 非略記法 -->
<component v-bind:is="currentComponent"></component>
<!-- 略記法 -->
<component :is="currentComponent"></component>
<!-- 動的なキーの指定 -->
<!-- 非略記法 -->
<div v-bind:[dynamicKey]="value"></div>
<!-- 略記法 -->
<div :[dynamicKey]="value"></div>
<!-- プロパティのバインディング -->
<!-- 非略記法 -->
<MyComponent v-bind:myProp="someValue" />
<!-- 略記法 -->
<MyComponent :myProp="someValue" />
<!-- 非略記法 -->
<button v-on:click="handleClick">Click me</button>
<!-- 略記法 -->
<button @click="handleClick">Click me</button>
<!-- イベントのリスナーを動的にバインド -->
<!-- 非略記法 -->
<button v-on:click="handleClick">Click me</button>
<!-- 略記法 -->
<button @click="handleClick">Click me</button>
複数のbind
これは複数のbindの例です。
<div v-bind="vueObject"></div>
const vueObject = {
id: 'vueId',
class: 'vueClass'
}
<div id="vueId" class="vueClass">
</div>
複数のbindもHTMLに置き換えれば分かりやすいですよね?
ここまで見ていただいたので、ここから説明を入れていきますね。
バインドとは
バインドとは、ある要素や属性に対してデータを関連付けることを指します。
Vue.jsでは、v-bind
ディレクティブを使用してHTML属性にデータをバインドします。
バインドすることで、動的にHTML要素や属性に値を設定できます。
バインディングはデータとDOMを連動させ、データの変更に応じてDOMが自動的に更新されるメカニズムを提供します。
ディレクティブとは
ディレクティブはHTMLの属性の形で表現され、プレフィックスとして v-
を持ちます。
ディレクティブは、DOM要素やコンポーネントに対して特定の振る舞いや効果をもたらします。v-bind
はディレクティブの一例で、要素の属性にデータをバインドするために使用されます。
他にも次のようなVueディレクティブが存在します。
v-if
v-for
v-on
v-bind
ディレクティブは、要素の id
という属性を、コンポーネントが持つvueIdというプロパティと同期させるようVueに指示しています。
バインドされた値がnull
またはundefined
の場合、その属性はレンダリングされる要素から除外されます。
※HTML属性の中ではマスタッシュ構文は使えません。
bindは「:」から始まる記述です。
v-bindを使ったimgの使用例
imgでのv-bind
<img v-bind:src="imageURL" alt="logo">
<img :src="imageURL" alt="logo">
:src
ディレクティブ(または v-bind:src
ディレクティブ)を使用して、imageURL
変数の値を画像の src
属性にバインドしています。これにより、imageURL
の値が変更されると、画像の src
属性も自動的に更新されます。
v-bindを使ったclassの使用例
class名でのv-bind
v-bindはclass名に対して使用することもできます。
今回の例では現場でもよく使うバリデーションに対してエラークラスの判定の実装です。
<input
v-model="username"
:class="{ 'is-valid': isValidInput('username'), 'is-error': hasError('username') }"
id="username"
type="text"
placeholder="ユーザー名を入力してください"
/>
isValidInput('username')
がtrue
の場合、'is-valid'
クラスが適用されます。入力が有効な場合に適用されるクラスで、通常はスタイルを設定するために使用されます。hasError('username')
がtrue
の場合、'is-error'
クラスが適用されます。エラーがある場合に適用されるクラスで、通常はエラーを視覚的に強調するために使用されます。
全体のコードです。
<template>
<div>
<form @submit.prevent="submitForm">
<label for="username">ユーザー名:</label>
<input
v-model="username"
:class="{ 'is-valid': isValidInput('username'), 'is-error': hasError('username') }"
id="username"
type="text"
placeholder="ユーザー名を入力してください"
/>
<span v-if="hasError('username')" class="error-message">ユーザー名は必須です。</span>
<br />
<label for="password">パスワード:</label>
<input
v-model="password"
:class="{ 'is-valid': isValidInput('password'), 'is-error': hasError('password') }"
id="password"
type="password"
placeholder="パスワードを入力してください"
/>
<span v-if="hasError('password')" class="error-message">パスワードは必須です。</span>
<br />
<button type="submit">送信</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
username: '',
password: '',
};
},
methods: {
isValidInput(field) {
return this[field].trim() !== '';
},
hasError(field) {
return !this.isValidInput(field);
},
submitForm() {
if (this.isValidInput('username') && this.isValidInput('password')) {
alert('フォームが正常に送信されました!');
} else {
alert('すべての必須フィールドに入力してください。');
}
},
},
};
</script>
<style>
.is-error {
border: 1px solid red;
}
.error-message {
color: red;
}
</style>
以下実装の補足です。
isValidInput
メソッドは特定のフィールドの入力が有効かどうかをチェックします(例:空でないかどうか)。hasError
メソッドは特定のフィールドにエラー条件があるかどうかをチェックします(例:入力が空)。:class
ディレクティブは入力が有効な場合に 'active’ クラスを、エラーがある場合に 'text-danger’ クラスを動的に適用します。- フォームには
submitForm
メソッドがあり、これはフォーム送信ロジックをシミュレートし、入力フィールドの妥当性に基づいてメッセージをアラート表示します。
今回はあくまでもv-bindのclassについてです。
判定に伴ってtrueまたはfalseを付与することでメッセージを表示するようにしています。
v-bindを使ったinputの使用例
<input>
要素にはtype="email"
があり、ユーザーが入力したメールアドレスが user.email
にバインドされています。v-on:input
で入力が行われるたびに updateEmail
メソッドが呼び出され、ユーザーが入力した値が user.email
にセットされます。
<template>
<div>
<label for="email">Email:</label>
<input type="email" id="email" v-bind:value="user.email" v-on:input="updateEmail">
<p>Entered Email: {{ user.email }}</p>
</div>
</template>
<script>
export default {
data() {
return {
user: {
email: ''
}
};
},
methods: {
updateEmail(event) {
this.user.email = event.target.value;
}
}
};
</script>
v-bindを使ったselectの使用例
<select>
要素にはユーザーが選択した部署が user.department
にバインドされ、v-on:change
イベントで選択が変更されたときに チェンジ
メソッドが呼び出されます。
v-bindの値を随時取得して<p>タグに表示をしています。
<template>
<div>
<label for="department">Select your department:</label>
<select v-bind:value="user.department" id="department" v-on:change="updateDepartment">
<option value="hr">Human Resources</option>
<option value="it">Information Technology</option>
<option value="sales">Sales</option>
</select>
<p>Selected Department: {{ user.department }}</p>
</div>
</template>
<script>
export default {
data() {
return {
user: {
department: ''
}
};
},
methods: {
updateDepartment(event) {
this.user.department = event.target.value;
}
}
};
</script>
v-bindを使ったradioの使用例
<input type="radio">
要素にはユーザーが選択した役割が user.role
にバインドされ、v-on:change
イベントで選択が変更されたときに changeメソッドが呼び出されます。
changeメソッドでチェックした値を取得しています。
<template>
<div>
<label>
<input type="radio" v-bind:checked="user.role === 'admin'" v-on:change="updateRole('admin')"> Admin
</label>
<label>
<input type="radio" v-bind:checked="user.role === 'user'" v-on:change="updateRole('user')"> User
</label>
<p>Selected Role: {{ user.role }}</p>
</div>
</template>
<script>
export default {
data() {
return {
user: {
role: 'user'
}
};
},
methods: {
updateRole(role) {
this.user.role = role;
}
}
};
</script>
v-onとは
v-on
は、DOMイベント(クリック、マウスオーバー、キー入力、チェンジなど)が発生した際に、Vue.jsで指定したメソッドや式を実行するために利用されます。
v-onはよく使うコードなので多用するので、省略で記述することができます。
v-on:イベント名
@イベント名
「v-on:」と「@」は同じ意味をします。
以下、イベントの例です。
<div @mouseover="handleMouseOver" @mouseleave="handleMouseLeave">
Hover over me
</div>
mouseover
イベントが発生した時に handleMouseOver
メソッドが呼ばます。
mouseover
イベントは、ポインティングデバイス (マウスやトラックパッドなど) のカーソルが要素またはその子要素のうちの一つの上を移動したときに、その要素 (Element
) に発行されます。
mouseleave
イベントが発生した時に handleMouseLeave
メソッドが呼ばれます。
mouseleave
イベントは、ポインティングデバイス(ふつうはマウス)のカーソルが要素 (Element
) の外に移動したときに発行されます。
<input @keydown="handleKeyDown" />
keydown
イベントが発生するたびに handleKeyDown
メソッドが呼ばれます。
他にも keyup
、keypress
などがあります。
<input @input="handleInput" />
input
イベントは、テキストボックスなどの入力フィールドの内容が変更されたときに発生します。handleInput
メソッドがこれに対応しています。
<input @focus="handleFocus" @blur="handleBlur" />
focus
イベントは要素がフォーカスを受け取ったときに発生し、blur
イベントはフォーカスを失ったときに発生します。
v-onの略記と非略記法の書き方
<!-- クリックイベント -->
<!-- 非略記法 -->
<button v-on:click="handleClick($event)">Click me</button>
<!-- 略記法 -->
<button @click="handleClick($event)">Click me</button>
<!-- ダブルクリックイベント -->
<!-- 非略記法 -->
<button v-on:dblclick="handleDoubleClick">Double Click me</button>
<!-- 略記法 -->
<button @dblclick="handleDoubleClick">Double Click me</button>
<!-- マウスオーバーイベント -->
<!-- 非略記法 -->
<div v-on:mouseover="handleMouseOver">Mouse over me</div>
<!-- 略記法 -->
<div @mouseover="handleMouseOver">Mouse over me</div>
<!-- マウスアウトイベント -->
<!-- 非略記法 -->
<div v-on:mouseout="handleMouseOut">Mouse out me</div>
<!-- 略記法 -->
<div @mouseout="handleMouseOut">Mouse out me</div>
<!-- キーダウンイベント -->
<!-- 非略記法 -->
<input v-on:keydown="handleKeyDown" />
<!-- 略記法 -->
<input @keydown="handleKeyDown" />
<!-- フォーカスインイベント -->
<!-- 非略記法 -->
<input v-on:focus="handleFocus" />
<!-- 略記法 -->
<input @focus="handleFocus" />
<!-- フォーカスアウトイベント -->
<!-- 非略記法 -->
<input v-on:blur="handleBlur" />
<!-- 略記法 -->
<input @blur="handleBlur" />
<!-- チェンジイベント(フォーム要素の値が変更されたとき) -->
<!-- 非略記法 -->
<input v-on:change="handleChange" />
<!-- 略記法 -->
<input @change="handleChange" />
<!-- サブミットイベント -->
<!-- 非略記法 -->
<form v-on:submit="handleSubmit">Submit</form>
<!-- 略記法 -->
<form @submit="handleSubmit">Submit</form>
<!-- ウィンドウリサイズイベント -->
<!-- 非略記法 -->
<div v-on:resize="handleResize">Resizable container</div>
<!-- 略記法 -->
<div @resize="handleResize">Resizable container</div>
<!-- メソッドの動的な呼び出し -->
<!-- 非略記法 -->
<button v-on:[dynamicEvent]="handleEvent">Click me</button>
<!-- 略記法 -->
<button @[dynamicEvent]="handleEvent">Click me</button>
v-onを使ったinputの使用例
<template>
<div>
<input :value="inputValue" v-on:input="handleInput">
<p>{{ inputValue }}</p>
</div>
</template>
<script>
export default {
data() {
return {
inputValue: ''
};
},
methods: {
handleInput(event) {
this.inputValue = event.target.value;
this.showAlert(`Input Value: ${this.inputValue}`);
},
showAlert(message) {
alert(message);
}
}
};
</script>
v-onを使ったselectの使用例
<template>
<div>
<select :value="selectedOption" v-on:change="handleSelectChange">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</select>
<p>Selected Option: {{ selectedOption }}</p>
</div>
</template>
<script>
export default {
data() {
return {
selectedOption: ''
};
},
methods: {
handleSelectChange(event) {
this.selectedOption = event.target.value;
this.showAlert(`Selected Option: ${this.selectedOption}`);
},
showAlert(message) {
alert(message);
}
}
};
</script>
v-onを使ったradioの使用例
<template>
<div>
<label>
<input type="radio" :checked="radioValue === 'radioOption1'" v-on:change="handleRadioChange('radioOption1')"> Radio Option 1
</label>
<label>
<input type="radio" :checked="radioValue === 'radioOption2'" v-on:change="handleRadioChange('radioOption2')"> Radio Option 2
</label>
<p>Selected Radio Option: {{ radioValue }}</p>
</div>
</template>
<script>
export default {
data() {
return {
radioValue: ''
};
},
methods: {
handleRadioChange(value) {
this.radioValue = value;
this.showAlert(`Selected Radio Option: ${this.radioValue}`);
},
showAlert(message) {
alert(message);
}
}
};
</script>
スポンサードサーチ
v-modelとは
v-model
とはVue.jsで双方向データバインディングを行うためのディレクティブです。
ディレクティブはできますが、特定の要素にバインドできるわけではありません。
v-modelはv-onとv-bindを合わせて、一行で書くことができます。v-model
はテキストボックスやセレクトボックスのような特定のフォーム要素にのみ適用できるため、v-model
は使用できない要素もあるので覚えておきましょう。
次のコードは全て同じ意味をします。
<input
v-bind:value="hoge"
v-on:input="foo"
>
<input
:value="hoge"
@input="foo"
>
<input v-model="hoge">
今回の例を各自パターンで書くとこうなります。
<template>
<div>
<input v-bind:value="hoge" v-on:input="foo">
<p>{{ "あなたの秘密のメッセージ: " + hoge }}</p>
<button v-on:click="revealSecret">秘密を明かす</button>
<p v-if="revealed">{{ "ヒント: その秘密はすごいことが起こるかもしれません!" }}</p>
</div>
</template>
<script>
export default {
data() {
return {
hoge: "",
revealed: false,
};
},
methods: {
foo(event) {
this.hoge = event.target.value;
},
revealSecret() {
this.revealed = true;
},
},
};
</script>
<template>
<div>
<input :value="hoge" @input="foo">
<p>{{ "あなたの秘密のメッセージ: " + hoge }}</p>
<button @click="revealSecret">秘密を明かす</button>
<p v-if="revealed">{{ "ヒント: その秘密はすごいことが起こるかもしれません!" }}</p>
</div>
</template>
<script>
export default {
data() {
return {
hoge: "",
revealed: false,
};
},
methods: {
foo(event) {
this.hoge = event.target.value;
},
revealSecret() {
this.revealed = true;
},
},
};
</script>
<template>
<div>
<input v-model="hoge">
<p>{{ "あなたの秘密のメッセージ: " + hoge }}</p>
<button @click="revealSecret">秘密を明かす</button>
<p v-if="revealed">{{ "ヒント: その秘密はすごいことが起こるかもしれません!" }}</p>
</div>
</template>
<script>
export default {
data() {
return {
hoge: "",
revealed: false,
};
},
methods: {
revealSecret() {
this.revealed = true;
},
},
};
</script>
v-model
ディレクティブは、フォーム要素(input、textarea、selectなど)と結びついて、データのバインディングを行うために使用されます。
v-modelを使ったinputの使用例
inputの例ではbuttonをクリックすると、
inputの値とlengthを取得してています。
inputValueが値になり<p>タグに表示させています。
<template>
<div>
<input v-model="inputValue">
<p>{{ inputValue }}</p>
<button @click="showAlert">Show Alert</button>
</div>
</template>
<script>
export default {
data() {
return {
inputValue: ''
};
},
methods: {
showAlert() {
const value = this.inputValue;
const length = value.length;
alert(`Value: ${value}, Length: ${length}`);
}
}
};
</script>
scriptタグ内で関数など使用することもできます。
this.inputValue
v-modelを使ったselectの使用例
v-modelでselect分での例です。
選択するたびに@changeでv-modelの値をmethods内でalertでindexをvalueを表示させています。
<template>
<div>
<select v-model="selectedOption" @change="showAlert">
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
selectedOption: ''
};
},
methods: {
showAlert() {
const selectedIndex = this.$refs.select.selectedIndex;
const selectedValue = this.selectedOption;
alert(`Selected Index: ${selectedIndex}, Selected Value: ${selectedValue}`);
}
}
};
</script>
v-modelを使ったradioの使用例
ボタンをクリックしたときに、ラジオボタン選択されたオプションとインデックスと値を alert
で表示します。
<template>
<div>
<label v-for="(option, index) in options" :key="index">
<input type="radio" v-model="selectedOption"> {{ option }}
</label>
<button @click="showSelectedInfo">Show Selected Info</button>
</div>
</template>
<script>
export default {
data() {
return {
options: ['Option 1', 'Option 2', 'Option 3'],
selectedOption: 'Option 2' // デフォルトで選択されるオプションを指定
};
},
methods: {
showSelectedInfo() {
// 選択されたオプションのインデックスと値を取得してアラートで表示
const selectedIndex = this.options.indexOf(this.selectedOption);
alert(`Selected Index: ${selectedIndex}, Selected Value: ${this.selectedOption}`);
}
}
};
</script>
v-if
v-ifはif文条件をvueへ記述します。
真偽値はscriptタグ内に書くことでtemplateタグ内でif分岐することができます。
<template>
<div>
<input type="radio" id="man" value="true" v-model="isMan">
<label for="man">男性</label>
<input type="radio" id="woman" value="false" v-model="isMan">
<label for="woman">女性</label>
<p v-if="isMan">男性です</p>
<p v-else>女性です</p>
</div>
</template>
<script>
export default {
data() {
return {
isMan: true
};
},
watch: {
isMan(newValue) {
this.isWoman = !newValue;
}
},
computed: {
isWoman: {
get() {
return !this.isMan;
},
set(value) {
this.isMan = !value;
}
}
}
};
</script>
watchについても説明しますね。
watch
プロパティとcomputed
プロパティを使用して、isMan
が変更されるとそれに応じて isWoman
を更新します。
これにより、ラジオボタンの選択に合わせて “男性" と “女性" の表示が切り替わります。
スポンサードサーチ
v-for
v-forはv-for
連想配列内の各要素についてループ処理を行います。
「object」
は各要素を表し、「index
」は現在の要素のインデックスを表します。「:key
」バインディングは、各要素に一意なキーを提供し、Vue.jsがリストを効率的に更新できるようにします。
<template>
<div>
<ul>
<li v-for="(object, index) in object.value" :key="index">
{{ object }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
object: {
value: [], // サンプルデータをここに入れる
},
};
},
async beforeCreate() {
// サンプルデータを非同期で取得する代わりに、ハードコーディングします
this.object.value = ['Apple', 'Banana', 'Orange'];
},
};
</script>
今回は直接値をしていますが、beforeCreateで非同期処理でデータを取得して来れば、デフォルトの値を空にして、取得した結果を格納できます。
<template>
<div>
<ul>
<li v-for="(object, index) in object.value" :key="index">
{{ object }}
</li>
</ul>
</div>
</template>
<script>
data() {
object: {
value: [],
},
}
async beforeCreate() {
await this.$store.dispatch('components/api/method')
this.items = this.$store.state.components.purchaseList.value;
},
</script>
以上になります。
これでvueについて少しは詳しくなれましたね。