とりあえず動かしてみる
- codepenを使って動かしてみる
- https://codepen.io/
- htmlタグ、bodyタグは不要
- pタグにHello Wrold!記述
- リアルタイムでプレビューが表示される
Vue.jsを読み込む方法
- CDN(タグの読み込み)
- 直接読み込み(ファイルをダウンロードして配置)
- NPM(パッケージ管理ソフトの利用)
- Vue CLIを使ってプロジェクトの基礎を作る
今回は簡単なCDNで読み込み
- vue.js 3のサイトでインストールの欄から確認できる
<script src="https://unpkg.com/vue@3.1.5"></script>
こちらを利用した
- バージョンがちゃんと表示されたらOK
Vueインスタンスを作成しよう
const app = Vue.createApp({
// 各種options
})
- 「Vue.createApp」メソッドの戻り値はVue.jsの機能を提供するVueインスタンスとなる
- 戻り値のVueインスタンスを変数appに入れる
- 「app」は任意の名前付けOK
- これで空のVueインスタンスの作成ができた
ルートのテンプレートを作成する
- ルートのテンプレートとは?
→テンプレートの中でも頂点に位置するテンプレート
<div id="app">
</div>
- このルートのテンプレートの中がVue.jsの世界として利用できる
- ただしマウントする操作が必要
const app = Vue.createApp({
// 各種options
})
app.mount('#app')
app.mount('#app')
- vueインスタンスのmountメソッドを呼び出している
- これでHTML内でVue.jsの世界が適用されるのは
id="app"
を指定した中ですよ、ということになる - これがマウントの処理
mountの別の書き方
const app = Vue.createApp({
// 各種options
}).mount('#app')
-
.
で繋ぐ、メソッドチェーンで書いている - メソッドの実行に対してさらにメソッドを実行
- こういう書き方もできるよ~くらいのニュアンス
データバインディング
- データと描画を同期する仕組み
テキストのデータバインディング
- まず表示するテキストのデータを定義する
- DOMの更新を自動化するデータバインディングを行うにはテンプレートで使用するすべてのデータはリアクティブデータとして使用する必要がある
- リアクティブとは?
→各要素をつなげて反応的に変化させること
const app = Vue.createApp({
data: () =>({
message: 'Hello Vue.js!'
})
})
app.mount('#app')
- リアクティブなデータの定義
- アプリケーションで使用するデータを宣言するには「data」オプションを使用する
- dataオプションはテンプレート側から参照できる値を格納したオブジェクト
- ※アロー関数で記述されています
<div id="app">
<p>{{ message }}</p>
</div>
- マスタッシュ構文で記述することでページに表示ができる
アロー関数とそうでない書き方
- どちらがよいとかは無いが迷ったらアロー関数の方がシンプルなのでよさそう
▼アロー関数
const app = Vue.createApp({
data: () =>({
message: 'Hello Vue.js!'
})
})
app.mount('#app')
▼これと同じ
const app = Vue.createApp({
data: function(){
return{
message: 'Hello Vue.js!'
}
}
})
app.mount('#app')
dataオプションにオブジェクトや配列要素を設定する
- ↑↑↑このように表示させたい
const app = Vue.createApp({
data: () =>({
message: 'Hello Vue.js!',
count: 99,
user:{
lastName: 'Nakamura',
firstName: 'Yuta',
prefecture: 'Tokyo'
},
colors: ['Red', 'Green', 'Blue']
})
})
app.mount('#app')
<div id="app">
<p>{{ message }}</p>
<p>{{ count }}</p>
<p>{{ user.prefecture }}</p>
<p>{{ colors[1] }}</p>
</div>
- 数字も設定できる↓↓↓
count: 99
- オブジェクトの配置↓↓↓
user:{
lastName: 'Nakamura',
firstName: 'Yuta',
prefecture: 'Tokyo'
}
- 配列の配置↓↓↓
colors: ['Red', 'Green', 'Blue']
ディレクティブとは
-
v-
で始まる特別な属性のこと - vue.jsになんらかの指示を行う仕組み
-
v-bimd
、v-if
、v-show
、v-for
、v-on
、v-model
など
v-bind(属性のデータバインディング)
- 属性へのバインディングにはマスタッシュ構文{{}}ではなく、v-bindディレクティブを使用する
const app = Vue.createApp({
data: () =>({
message: 'Hello Vue.js!'
})
})
app.mount('#app')
<div id="app">
<input type="text" v-bind:value="message">
</div>
- jsの方には通常通りdataの中にmessageを指定
- html側で、valueを
v-bind:value
とする - 中身はdataに設定した
message
- こちらでページ表示上はインプットの中にdataで設定した「Hello Vue.js!」が表示される
NG例
<div id="app">
<input type="text" value="{{ message }}">
</div>
- これができないということ!
- 属性の中ではマスタッシュ構文は使えない
v-if(条件分岐)
- ページの表示・非表示を切り替えできる
const app = Vue.createApp({
data: () =>({
toggle: false
})
})
app.mount('#app')
<div id="app">
<p v-if="toggle">Hello</p>
</div>
- pタグにに
v-if
を設定(toggleを対象とする) - data内にtoggleを配置、falseに設定することで「非表示」の設定になり、ページには何も表示されない
const app = Vue.createApp({
data: () =>({
toggle: true
})
})
app.mount('#app')
- toggleの値を「true」に設定することでページに「Hello」が表示される
v-for(繰り返し描画をする)
- dataオプションに登録した配列の値を番号付きのリストで表示する
const app = Vue.createApp({
data: () =>({
colors: ['Red', 'Green', 'Blue']
})
})
app.mount('#app')
<div id="app">
<ol>
<li v-for="color in colors">{{ color }}</li>
</ol>
</div>
- dataオプションに配列「colors」を設定
- html側のliタグにv-forを設定
-
v-for="color in colors"
このように設定する - 【js側】の配列
colors
と【html側】のcolor in colors
のcolors
が対応 - 【html側】の
color in colors
のcolor
と{{ color }}
が対応している - それぞれ任意で変更しても問題はない
v-forその2(オブジェクトの繰り返し描画)
- dataオプションに登録したユーザーオブジェクトの値をすべてリスト表示したい
- ここで言うオブジェクトとはkeyとvalueによって構成されるデータのことを指している
ひとまず普通のリスト表示
const app = Vue.createApp({
data: () =>({
user:{
firstName: 'Taro',
lastName: 'Yamada',
age: 23
}
})
})
app.mount('#app')
<div id="app">
<ul>
<li v-for="value in user">
{{ value }}
</li>
</ul>
</div>
-
v-for="value in user"
このように設定 - 【js側】のオブジェクト
user
と【html側】のvalue in user
のuser
が対応 - 【html側】の
value in user
のcolor
と{{ value }}
が対応している
valueだけじゃなくオブジェクトのkeyもリスト表示させる
const app = Vue.createApp({
data: () =>({
user:{
firstName: 'Taro',
lastName: 'Yamada',
age: 23
}
})
})
app.mount('#app')
<div id="app">
<ul>
<li v-for="(value, key) in user">
{{ key }}:{{ value }}
</li>
</ul>
</div>
- js側はそのまま
- v-forの箇所を
v-for="(value, key) in user"
と変更 - それぞれマスタッシュ構文で
{{ key }}:{{ value }}
と記述 - これでkeyとvalueのどちらもリストに表示できる
注意点
<li v-for="(value, key) in user">
- 第一引数が
value
、第二引数がkey
となるので注意!
任意の箇所は変更してもOK
<div id="app">
<ul>
<li v-for="(v, k) in user">
{{ k }}:{{ v }}
</li>
</ul>
</div>
- 表示は変わらず
v-on(イベントの基本処理)
- ボタンをクリックしたら現在時刻をページに表示したい
const app = Vue.createApp({
data: () =>({
now: '-'
}),
methods: {
onClick: function(){
this.now = new Date().toLocaleString()
}
}
})
app.mount('#app')
<div id="app">
<button v-on:click="onClick">Click!</button>
<p>{{ now }}</p>
</div>
js側
- dataでnowの初期値に「-」を設定
※ボタンを押す前の状態は「-」が表示されている - methodsオプションを追記
onClick
のイベントに対して、関数を設定 -
this.now = new Date().toLocaleString()
現在時刻を取得してdataオプションのnowに格納する
ここのthis
はdataオプションのことを指している
html側
- buttonタグに
v-on
を設定
v-on:click="onClick"
-
v-on:click
でクリックイベントへ設定 - クリックすると「onClick」に設定したイベントを発生
ページの表示
- ボタンを押す前は「-」のみ表示
- ボタンを押すと現在時刻が表示される
v-model(双方向データバインディング)
- dataオブジェクトの値変更⇔テンプレートの値変更
const app = Vue.createApp({
data: () =>({
message: 'Hello Vue.js!'
}),
})
app.mount('#app')
<div id="app">
<p><input type="text" v-model="message"></p>
<p><input type="text" v-model="message"></p>
</div>
- dataオプションには通常通りmessageを設定
- html側で、inputタグにv-modelを設定
-
v-model="message"
とdataオプションで設定した値を記述する
ページの表示
- どちらのinput欄にもdataオプションで設定したmessageの値「Hello Vue.js!」が表示
- 片側にテキストを追加してみると下段の方のinputにも同じテキストが追加される
構造を少しわかりやすく表示
const app = Vue.createApp({
data: () =>({
message: 'Hello Vue.js!'
}),
})
app.mount('#app')
<div id="app">
<p><input type="text" v-model="message"></p>
<p><input type="text" v-model="message"></p>
<pre>{{ $data }}</pre>
</div>
- html側に
<pre>{{ $data }}</pre>
を追記
これによりdataオブジェクトの中身を可視化できる
簡易的にデバックするのに便利 - dataに設定した
message: 'Hello Vue.js!'
が表示されている状態
- 上部のinputにテキストを追記してみる
- 下部のinputにもテキスト追加される(ここは変わりなし)
- デバック表示したdataオブジェクトの値もテキストが追加されていることがわかる
→ページの記入によってjs側のdataの中身が変化している状態!
コンポーネントを利用する
- 名前付きの再利用可能なインスタンス
- ページを構成するUI部品
- よく使う機能をコンポーネント化することで再利用性が高くなり、コードの見通しが良くなる
const app = Vue.createApp({
data: () =>({
}),
})
app.component('hello-component', {
template: '<p>Hello!</p>'
})
app.mount('#app')
<div id="app">
<hello-component></hello-component>
</div>
- 下記を追記した↓↓↓
app.component('hello-component', {
template: '<p>Hello!</p>'
})
- コンポーネント設定の書き方に関しては覚えるしかないのかも
-
<p>Hello!</p>
をhello-component
タグに登録したような記述
<div id="app">
<hello-component></hello-component>
<hello-component></hello-component>
<hello-component></hello-component>
</div>
- タグを増やすとページ内の表示も増やせる