目次
(参考資料)
・Vue3 日本語ドキュメント
https://v3.ja.vuejs.org/
・Vue.js3超入門(掌田津耶乃著)秀和システム
1.Vueの動作環境
(1)動作環境
・Windows 10 Pro
・XAMPP Control Panel v3.2.4
(2)Node.jsのインストール
Node.jsはJavaScript実行環境でパッケージ管理ツールnpm(Node Package Manager)が組み込まれています。
下記のサイトにアクセスしてダウンロードします。https://nodejs.org/ja/
Node.jsのバージョンは偶数が長期サポートの安定版。
任意のバージョンをダウンロードしたいときは下記のページ。
https://nodejs.org/ja/download/releases/
Version16.13.0 LTSをダウンロード
・ファイル名:node-v16.13.0-x64.msiを実行
ネイティブモジュール用ツールオプションはデフォルトのままチェックOFF
・動作を確認します
> node –version
・VueCLIのインストール
VueCLIはVue開発のためのコマンドツールです。
> npm i -g @vue/cli-service-global
(3)プロトタイプアプリケーションの作成
・フォルダを作ります。
C:\Users\・・・\Desktop\vue_work
・ app.vueファイルを作成します。
app.vue
<template>
<div id="app">
<h1>Hello!</h1>
<p>This is message...</p>
</div>
</template>
・app.vueファイルを置いたフォルダに移動して次のコマンドを実行します。
> vue serve
またはファイルを指定して
> vue serve app.vue
・ブラウザでアクセス
・Webサーバの停止
Ctrl+C
2.プロジェクトの作成
(1)VueCLIコマンドを使ったプロジェクトの作成
> vue create (プロジェクト名)
> vue create hello_app
Default(Vue3)・・・を選択
パッケージマネージャー NPMを選択
(2)プロジェクトの実行
> cd hello_app
> npm run serve
(3)プロジェクトフォルダの内容
(4)プロジェクトのビルド
> npm run build
distフォルダが作成され、この中に公開するファイルが一式まとめられている
XAMPPのApatchサーバを起動し、distフォルダ内のファイル、フォルダをhtdocs配下に置く。
ブラウザでhttp://localhost:80にアクセスする
3.Vue3の基本
3.1 Vue3のオブジェクトからの{{プロパティ}}の表示
Vueオブジェクトがマウントされたタグ内にある{{プロパティ}}にはVueオブジェクトで定義されたプロパティの値が入ります。またこの値はオブジェクト内の値がリアルタイムにチェックされ、値が更新されると、自動的に{{}}の表示も更新されます。
sample1
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<h1>Vue3</h1>
<div id="app">
{{ message }}
</div>
<script>
const appdata = {
data() {
return {
message: 'Hello Vue!'
}
}
}
Vue.createApp(appdata).mount('#app')
</script>
</body>
</html>
3.2 v-htmlによるHTML要素の出力
タグの中にv-html属性を使うことで、Vueオブジェクト側で用意したHTMLのコードで画面に表示できます。
タグには、<div v-html=”変数名”></div>とし、
Vueオブジェクトのdataプロパティの中で”変数名”にテンプレートリテラル
を設定します。
テンプレートリテラルはプレースホルダー(${変数名}と書き、予め用意した変数をはめ込める)が使えます。
sample2
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<h1>Vue3</h1>
<div id="app">
<div v-html="message"></div>
</div>
<script>
const list = ['One', 'Two', 'Three']
const appdata = {
data() {
return {
message: `<ul>
<li>${list[0]}</li>
<li>${list[1]}</li>
<li>${list[2]}</li>
</ul>`
}
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
3.3 v属性によるタグの属性の設定
タグの中に「v-bind:属性名=”設定する値”」を記述することで、Vueオブジェクトからタグの属性を設定することができます。
(1)Vueオブジェクトからのスタイルの設定
タグの中で「v-bind:style=”変数”」で設定します。または「v-bind:style=”オブジェクト名”」としてVueインスタンスにdataプロパティの中にオブジェクトを用意しておくこともできます。
sample3
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p v-bind:style="style">{{ message }}</p>
</div>
<script>
const appdata = {
data() {
return {
message : null,
style:'font-size:32pt; color:red;'
}
},
mounted() {
this.message = 'This is sample page.'
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
(2)Vueオブジェクトからのクラスの設定
タグの中で「v-bind:class={クラス名:”変数”}」で設定します。または「v-bind:class=”オブジェクト名”」としてVueインスタンスにdataプロパティの中にオブジェクトを用意しておくこともできます。
sample4
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<style>
.red {
color:red;
}
.blue {
color:blue;
}
</style>
<div id="app">
<p v-bind:class="{red:isRed, blue:isBlue}">
{{ message }}
</p>
</div>
<script>
const appdata = {
data() {
return {
message : null,
isRed: true,
isBlue: false
}
},
mounted() {
this.message = 'This is sample page.'
setInterval(()=>{
this.isBlue = !this.isBlue
this.isRed = !this.isRed
},1000)
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
1秒毎に文字色が赤、青交互に変わります。
(3)v-ifによる条件付きレンダリング
タグの中で「v-if=”条件”」で設定します。
sample5
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<style>
.red {
color:red;
}
.blue {
color:blue;
}
</style>
<div id="app">
<p v-if="isRed" class="red">
{{ message }}
<p v-else class="blue">
{{ message }}
</p>
</div>
<script>
const appdata = {
data() {
return {
message : null,
isRed: true,
isBlue: false
}
},
mounted() {
this.message = 'This is sample page.'
setInterval(()=>{
this.isBlue = !this.isBlue
this.isRed = !this.isRed
},1000)
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
<タグ v-if=”条件”>・・・</タグ>
<タグ v-else>・・・</タグ>
のとき、条件のtrue/falseでどちらかのタグが表示されます。
1秒毎にclass属性を変えて、文字色が赤、青交互に変わるようにしています。
(4)HTMLのタグを<template>タグでまとめる
複数のタグを<template>タグでまとめることで、v-ifの条件によって、複数のタグを切り替えることができます。<template>タグは表示されません。
sample6
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<template v-if="isRed">
<p v-bind:style="style1">{{ message }}</p>
</template>
<template v-else>
<p v-bind:style="style2">{{ message }}</p>
</template>
</div>
<script>
const appdata = {
data() {
return {
message : null,
style1:'font-size:32pt; color:red;',
style2:'font-size:48pt; color:blue;',
isRed: true,
isBlue: false
}
},
mounted() {
this.message = 'This is sample page.'
setInterval(()=>{
this.isBlue = !this.isBlue
this.isRed = !this.isRed
},1000)
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
1秒毎に<template>タグの条件を変えて、文字スタイルが交互に変わるようにしています。
(5)v-forによる配列データのレンダリング
<タグ v-for=”変数” in 配列> ・・・表示内容・・・</タグ>
の形で記述します。
sample7
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<table class="table">
<tr>
<th>Name</th>
<th>Mail</th>
<th>Tel</th>
</tr>
<tr v-for="item in items">
<td>{{item.name}}</td>
<td>{{item.mail}}</td>
<td>{{item.tel}}</td>
</tr>
</table>
</div>
<script>
const appdata = {
data() {
return {
message :"データの一覧表示",
items:[
{name:'Suzuki', mail:'suzuki@com', tel:'123-456'},
{name:'Yamasita', mail:'yamasita@com', tel:'456-789'},
{name:'Tanaka', mail:'tanaka@com', tel:'789-123'},
]
}
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
v-forは配列から要素を取り出し
<タグ v-for=”取り出した要素を入れる変数,インデックス” in 配列>・・・表示内容・・・</タグ>
の形で記述することで第2引数として配列のインデックスを取り出せます。
sample8
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<table class="table">
<tr>
<th>ID</th>
<th>Name</th>
<th>Mail</th>
<th>Tel</th>
</tr>
<tr v-for="(item,id) in items">
<td>{{id}}</td>
<td>{{item.name}}</td>
<td>{{item.mail}}</td>
<td>{{item.tel}}</td>
</tr>
</table>
</div>
<script>
const appdata = {
data() {
return {
message :"データの一覧表示",
items:[
{name:'Suzuki', mail:'suzuki@com', tel:'123-456'},
{name:'Yamasita', mail:'yamasita@com', tel:'456-789'},
{name:'Tanaka', mail:'tanaka@com', tel:'789-123'},
]
}
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
(6)v-forによるオブジェクトデータのレンダリング
<タグ v-for=”(値,キー)” in オブジェクト>・・・表示内容・・・</タグ>の形で記述します。
sample9
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<table class="table">
<tr>
<th>ID</th>
<th>Name</th>
<th>Mail</th>
<th>Tel</th>
</tr>
<tr v-for="(item,key) in items">
<td>{{key}}</td>
<td>{{item.name}}</td>
<td>{{item.mail}}</td>
<td>{{item.tel}}</td>
</tr>
</table>
</div>
<script>
const appdata = {
data() {
return {
message :"データの一覧表示",
items:{
Suzuki:{mail:'suzuki@com', tel:'123-456'},
Yamasita:{mail:'yamasita@com', tel:'456-789'},
Tanaka:{mail:'tanaka@com', tel:'789-123'},
}
}
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
4.コンポーネントの基本
4.1 コンポーネントの作成と利用
コンポーネントは、JavaScript側とHTML側(テンプレート)をひとまとめにして部品化して再利用できるようにしたものです。
コンポーネントの作成は、Vueアプリケーション.component(名前,{設定情報})
HTMLの中で使うときは、コンポーネントの名前のタグを記述します。
<コンポーネント />
sample10
「Hello component!」を表示するコンポーネントを作成します。下記の順番で実装します。
①Vueアプリケーション(オブジェクト)を作成する
let app = Vue.createApp(appdata)
②アプリケーションにコンポーネントを組み込む
app.component(‘hello’, {
template:'<p>Hello component! </p>’
})
③HTMLにアプリケーションを組み込む
app.mount(‘#app’)
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<hello/>
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します'
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
template: '<p> Hello component! </p>'
})
app.mount('#app')
</script>
</body>
</html>
4.2 変数をコンポーネントに渡す
コンポーネントのdataプロパティに変数を定義することでコンポーネントに変数をわたすことができ、テンプレートの外で変数の値を設定できます。
sample11
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<hello/>
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します'
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
data:function(){ //短縮形 data(){
return {
message : 'helloコンポーネント'
}
},
template: '<p> {{message}} </p>'
})
app.mount('#app')
</script>
</body>
</html>
4.3 コンポーネントのタグに属性をもたせる
コンポーネントのタグに属性を設定してテンプレートで使えるようにするためには、コンポーネントに”props”プロパティを用意します。
props:[名前1,名前2,・・・]
sample12
コンポーネントのタグの属性に設定した文字列をテンプレートに表示します。
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{message}}</p>
<hello name="Suzuki" />
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します'
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
props:['name'],
template: '<p> Hello component! {{name}} </p>'
})
app.mount('#app')
</script>
</body>
</html>
sample13
props:[‘name’]の配列は、変数の型や初期値を指定したいときは、オブジェクトとして
props:{
name:{
type:String,
default:”}
},
}
とすることもできます。
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{message}}</p>
<hello name="Suzuki" />
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します'
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
props:{
name:{
type:String,
default:''
}
},
template: '<p> Hello component! {{name}} </p>'
})
app.mount('#app')
</script>
</body>
</html>
4.4 コンポーネントのタグの属性の設定
前述のようにVueオブジェクトにマウントされたHTMLのタグにv-bindで属性の設定ができたように、コンポーネントでもv-bindで属性の設定ができます。
(1)コンポーネントのタグにv-bindによる属性の設定
sample14
配列から取り出したデータをv-bindでname属性に設定し、
テンプレートに表示します。
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{message}}</p>
<hello v-for="item in data" v-bind:name="item" />
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します',
data:['Suzuki','Yamasita','Yamamoto']
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
props:['name'],
template: '<p> Hello component! {{name}} </p>'
})
app.mount('#app')
</script>
</body>
</html>
(2)inputタグにv-modelの設定
inputタグに設定されたv-model属性は、入力された値をVueオブジェクトの変数にバインドする働きをします。
sample15
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{message}}</p>
<div><hello v-bind:name="name" /></div>
<div><input type="text" v-model="name" ></div>
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します',
name:"suzuki"
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
props:['name'],
template: '<p> Hello component! {{name}} </p>'
})
app.mount('#app')
</script>
</body>
</html>
(3)コンポーネントのタグにv-onの設定
v-on属性を使うことでイベントに値をバインドして、Vueオブジェクトで扱うことができます。
sample16
ボタンを押す毎に数字をインクリメントして、カウンタ表示します。
index.html
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{message}}</p>
<hello/>
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します',
name:""
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
data(){
return{
counter:0,
}
},
template: '<p v-on:click="counter++"> counter! {{counter}} </p>'
})
app.mount('#app')
</script>
</body>
</html>
(4)イベント処理をメソッドにまとめる
上記(3)では 「v-on:click=”counter++”」として直接、値(式)を記述しましたが、ここではこの式をメソッドから呼ぶようにします。
sample17
ボタンを押す毎に数字をインクリメントして、カウンタ表示します。
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{message}}</p>
<hello/>
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します',
name:""
}
}
}
let app = Vue.createApp(appdata)
app.component('hello', {
data(){
return{
counter:0,
}
},
methods:{
countup(){
this.counter++;
}
},
template: '<p v-on:click="countup"> counter! {{counter}} </p>'
})
app.mount('#app')
</script>
</body>
</html>
・メソッドで変数を扱うとき、このオブジェクトの変数であることを示すため「this.counter++;」のようにthisを付けます。
4.5 算術プロパティ
methodsプロパティとcomputedプロパティ(算術プロパティ)には関数式を定義できますが、算術プロパティは依存する値が更新された時に実行されます。
上記ではイベントでメソッドを呼び出して値を更新しましたが、算術プロパティにcountup()を定義したときはカウントアップしません。
4.6 ローカルコンポーネント
上記では、
(アプリケーション).component(‘hello’,{ data、method、templateなどのプロパティの定義})で定義したグローバルコンポーネントは全て読み込まれます。これに対してローカルコンポーネントで定義することで、必要なコンポーネントのみ読み込んで使うことができます。
sample18
sample17をローカルコンポーネントとして書き換えたコードです。
sample17では、app.component(‘hello’・・・)でVueオブジェクトに組み込んでいた(グローバルコンポーネント)をアプリケーション変数にcomponentsプロパティで登録してローカルコンポーネントとして登録します。
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue@next"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="app">
<p>{{message}}</p>
<hello/>
</div>
<script>
const appdata = {
data() {
return {
message : 'コンポーネントを表示します',
name:""
}
},
components:{
hello:{
data(){
return{
counter:0,
}
},
methods:{
countup(){
this.counter++;
}
},
template: '<p v-on:click="countup"> counter! {{counter}} </p>'
}
}
}
let app = Vue.createApp(appdata)
app.mount('#app')
</script>
</body>
</html>
The end