Vue.js とやらを勉強2
Vue.js で基本の属性をまとめる。
目次
ほとんど使わないじゃないかなって思ってるやつ。
v-html="---html---" で指定した html が差し込めるってやつ。 サンプル。
ボタン押すと入力した文字がどんどん追加されるってやつ。
こういう、追加作業するときって Web アプリだと多いのだろうか・・・。
そんななさそうなので、「使わない」と勝手に思っている。 html 中に if 文が書き込めるやーつ。
ちゃんと else も書ける。 サンプルはボタン押すと内容が切り替わるよってやつ。
まとめてないけど template 構文を使ってる。 template 構文のおかげで、中身をまるっと変更できる。
後述するコンポーネントとか、実際に Vue.js でアプリ
作ってくってなるとこの template 構文が基本になる(と思っている)。 v-if = "条件" といったふうに書く。
「条件」に bool 値の変数名を書いて、data がその bool 値持ってれば
Vue.js がきれいに変数として扱ってくれる。ありがたい。 さっきの v-if と一緒で html に for 文が書ける。
これのおかげでリスト表示とかもらくらくってわけ。 注意すべきなのは、v-if と併用すると
「v-if が後になる」ってことくらい?
v-for が優先で動く。 使い方は v-for = " val in values " みたいなかんじ。
values がオブジェクトだとプロパティも抜き出せて、
( obj, prop ) in values みたいな書き方になる。 index 番号が欲しい時もオブジェクトと同じ書き方で、
( element, index ) in values になる。
( javascript の for-in ループとは違うのがちょっと面倒・・?) サンプルはオブジェクトを対象に、さらに v-if を組み合わせたやつ。 すーぱー使う。絶対に使う。
必ず習得すべきもの。 できることは、新しい html のタグを作るようなもの。
C# でいうところのカスタムコントロールとかユーザコントロール。
ユーザコントロールのが近いかな。 このコンポーネントにプロパティ持たせて、そこに値をバインドとかできる。
XAML みたいだと思えば楽かも。(こういう時、自分の得意な言語にあてはめて考えれるのは楽だ) 単一のファイルでコンポーネントを作るときは Vue の関数を呼び出す。
そうでない場合、つまりちゃんとしたアプリだと *.vue っていう拡張子が vue の
ファイルに書く感じ。 今回は前者で書く。 Vue.component(conponentName, { conponent が持ついろんなプロパティ }) こんな感じで使う。
conponentName はコンポーネント名で、これがタグになる。文字列で指定する。 第2引数はコンポーネントの本体で、オブジェクトで指定する。 ほんじゃまかサンプル。
「Hello ○○」って書いてくれるだけのコンポーネント。
サンプルは以下の仕様になってる。 v-bind については後述する。 v-for で複数の name を取得する。names は Vue オブジェクトが持つ data に設定されたプロパティである。 1つ取り出した name が v-bind によってコンポーネントの name 属性にバインドされる。 そして、name 属性が template の {{ name }} 部分に入る仕組み。
name 属性は props: ['name'] で設定されている。(配列なんで複数書けるよ!) Hello 部分を担う message はコンポーネント内の data プロパティが返している message プロパティのこと。
こいつが {{ message }} に入る。 間違いなく超使うやつ。
バインドなんで、XAML でもいっぱい出てきてる。
つまり、特定の値に特定の値を割り当てる感じ。
ただし、v-bind は単方向だから、入力値をプロパティに代入とかはできない。
双方向でバインドしたいときは v-model を使う。 ちょっと前に v-bind で name 属性に変数 name をバインドした。
つまり、こいつは属性に対してバインドできる。 つまり、自分で設定した属性だけでなく html のタグの style とか class にもちゃんとバインドできる。 ほんじゃサンプル。
ボタンを押すと文字色が変わる。
文字色は css 側で class 「red」, 「blue」に対して変えてる単純なもの。 classes でクラスを代入してる。プロパティ名がそのままクラス名になる。 そんで、bool 値に従ってクラスが適用される。 サンプルだとプロパティでクラスを代入してるが、下記のようにばちこり書いてもOK。 class="{red: isRed, blue: isBlue}" v-model もバインドなんだけど、 違った、v-model は双方向バインドのこと。
XAML でもあったやつ。入力した値をプロパティに渡すことができるし、プロパティの値を表示したりもできる。 これ以下の説明は一応そのとおりなんでそのままにしておくが、双方向バインドなんでもっとうまいことできるし、
ちゃんと考えないとたぶんだが沼る。 v-bind と組み合わせれば、input の値をプロパティにバインドして、プロパティにバインドした値を
属性にバインドする。これでリアルタイムに input の値がほかのタグに反映される。 下記がサンプル。
上記で書いてるとおり、input の内容を hello コンポーネントに渡している。 v-model でまとめたとおりの簡単なサンプルなので、これ以上は特に説明なし。 v-on はイベントの発生のこと。
指定した関数を実行してくれる。 下記のように書けば、click 時に func1 が実行される。 v-on:click="func1();" 複数個の関数を実行したいときは v-on:click="func1();func2();func3()" みたいに複数個繋げて書く。 コンポーネントに関数をオブジェクトとして持てる。 methods というプロパティを用意し、そこにオブジェクトを書く。
プロパティ名が関数名になり、「function () { ... } 」で関数を設定してやればいい。 サンプルはボタンを押すと以下の機能が働くもの。 文字色はクラスを変更し、 css で変えてる。
カウンターとかメッセージは関数の中身でゴリゴリと。 v-on も好きな関数を実行できるんで、よく使うだろうなぁ。 次はばちこり vue/cli でアプリ作ったやつをまとめたい。
まだ勉強中なんでまたまとまってきたら書く・・・。v-html
<div id="app">
<ol v-html = "message"></ol>
<hr>
<input type="text" oninput="tempValue(event);">
<button onclick="add();">add</button>
</div>
<script>
let data = {
message: '<li>one</li>',
tempInput: ''
}
let app = new Vue({
el: '#app',
data: data
});
function add(){
data.message += `<li>${data.tempInput}</li>`
}
function tempValue(event){
data.tempInput = event.target.value;
}
v-if
<div id="app">
<template v-if="flag" >
<p>Display data table.</p>
<table>
<tr><th>Name</th><th>mail</th></tr>
<tr><td>Taro</td><td>taro@yamada</td></tr>
<tr><td>Hanako</td><td>hanako@flower</td></tr>
<tr><td>Sachiko</td><td>sachiko@happy</td></tr>
</table>
</template>
<template v-else>
<p>Display data list</p>
<ul>
<li>name: Taro, mail: taro@yamada</li>
<li>name: Hanako, mail: hanako@flower</li>
<li>name: Sachiko, mail: sachiko@happy</li>
</ul>
</template>
</div>
<button onclick="onChangeFlag();">
change flag
</button>
<script>
let data = {
flag: true
}
let app = new Vue({
el: '#app',
data: data
});
function onChangeFlag(){
data.flag = !data.flag;
}
</script>
v-for
<div id="app">
<p>Display data list</p>
<table>
<tr>
<th>name</th>
<th>mail</th>
<th>tel</th>
</tr>
<!-- v-for が優先で動く。v-if は v-for のあと。 -->
<tr v-for="( obj, key ) in items" v-if="obj.isPublic">
<td>{{ key }}</td>
<td>{{ obj.mail }}</td>
<td>{{ obj.tel }}</td>
</tr>
<tr v-else>
<td>{{ key }}</td>
<td>*** 非公開 ***</td>
<td>*** 非公開 ***</td>
</tr>
</table>
</div>
<script>
let data = {
items: {
Taro: {mail: 'taro@ssss', tel: '777-777', isPublic: true},
Machiko: {mail: 'machiko@ieiieieie', tel: '888-888', isPublic: true},
Administrator: {mail: 'admin@opertor', tel: '999-999', isPublic: false},
Tester: {mail: 'tester@test', tel: '999-999', isPublic: false},
Takeshi: {mail: 'takeshi@iwatype', tel: '999-999', isPublic: true}
}
};
let app = new Vue({
el: '#app',
data: data
});
</script>
コンポーネント
<div id="app">
<hello v-for="name in names" v-bind:name="name"></hello>
</div>
<script>
Vue.component("hello", {
props: ['name'],
data: () => {
return {
message: "Hello ",
};
},
template: '<p class="hello">{{ message }} {{ name }}</p>',
});
let app = new Vue({
el: "#app",
data: {
names: ['taro', 'hanako', 'sachiko', 'takeshi']
}
});
</script>
v-bind
.red {
color: red;
}
.blue {
color: blue;
}
<div id="app">
<p v-bind:class="classes">{{ message }}</p>
<button onclick="onChnageColor();">{{ btnText }}</button>
</div>
<script>
let classObj = {
// プロパティ名がそのままクラス名になる
red: true,
blue: false
};
let data = {
message: "This is Message.",
classes: classObj,
btnText: "To Blue"
};
let app = new Vue({
el: "#app",
data: data
});
function onChnageColor() {
classObj.red = !classObj.red;
classObj.blue = !classObj.blue;
data.btnText = classObj.red ? "To Blue" : "To Red";
}
</script>
v-model
こいつは input タグの値をプロパティにバインドするやつ。 <div id="app">
<!-- name 属性に name プロパティを代入してる -->
<hello v-bind:name="name"></hello>
<!-- v-model により name プロパティに対して値が代入される。 -->
<input type="text" v-model="name">
</div>
<script>
// name プロパティを定義し、html 側で name 属性を指定すればここのプロパティとして入る
Vue.component('hello', {
props: ['name'],
template: '<p class="hello">Hello, {{ name }}</p>'
});
let app = new Vue({
el: '#app',
data: {
name: 'no-name'
}
})
</script>
v-on
<div id="app">
<click></click>
</div>
<script>
Vue.component("click", {
methods: {
// この this は component 内のネストのみ
onChangeColor: function () {
this.classes.red = !this.classes.red;
this.classes.blue = !this.classes.blue;
},
onAddCounter: function () {
this.counter++;
},
onChangeMessage: function () {
this.message = this.classes.red
? `To Blue counter: ${this.counter}`
: `To Red counter: ${this.counter}`;
},
},
data: function () {
return {
counter: 0,
classes: {
red: true,
blue: false,
},
message: `To Blue counter: 0`
};
},
template:
'<button v-on:click="onChangeColor();onAddCounter();onChangeMessage();" v-bind:class="classes">{{ message }}</button>',
});
let app = new Vue({
el: "#app",
});
</script>
次にまとめるの