jQueryはユーザーインターフェイスを構築するJavaScriptライブラリである。2019年時点では、多くのサイトに採用されている。2014年2月に初版が公開され、2019年12月13日に公開されたバージョン2.6.11が2020年7月時点では最新である。バージョン2.6.11を用いて解説する。
とほほのWWW入門のページを参考にしている。
逆引き:ロード、ひな形、inner/content、クリック、v-showでdisplay:none、モデル、表示条件、自動計算、タグでインスタンス参照、コードでインスタンス参照、配列とタグの対応、データからタグ属性へバインド、スタイルへバインド、変換フィルタ、フック、トランジション効果、ミックスイン
グローバルAPI編の逆引き:タグエイリアス、data操作の追加と削除、スタイルのエイリアスと操作、変換フィルタ、ミックスイン、バージョン
jQueryのときと同じようなパターンである。
CDN(コンテンツデリバリネットワーク)からのロードも可能である。
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script>
もちろん、ローカルにロードしてもよい。また、「dist/vue.js」は「dist/vue.min.js」に変えると、圧縮したコードを使用する。
ひな形は一例として以下のようになる。重要なところは太字にしてある。
<!DOCTYPE html>
<head>
<title>title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
</head>
<body>
<div id="id1">{{ id1_data }}</div>
<script>
var vuei1 = new Vue({
el: '#id1',
data: { id1_data: 'データ書き込み' }
})
</script>
</body>
</html>
実行すると「データ書き込み」と表示される。
エレメントのidに指定した文字列がJavaScriptのelと連携される。ここでは「id1」である。div要素その内部の「{{ id1_data }}」のところは出力先となっている。
vueの「el: '#id1'」はjQueryでは「$("#id1")」とするセレクタ部分であり、vueの「data: { id1_data: 'データ書き込み' }」はjQueryの「.text('データ書き込み');」とするところである。「el: '#id1'」のelはelementのことある。インスタンス変数はvuei+1からはじまる連番にしている。
開始時、「{{ id1_data }}」と一瞬表示されることがあるが、「<div id="id1">」を「<div id="id1" v-cloak>」とすることで防ぐことができる。
以降、解説では主に太字の部分を変えていく。
テキストの置き換えはJavaScriptではinnerHTMLとtextContentとinnerTextの3種類ある。JavaScript / vue / jQueryの順で対応を示す。
innerHTML / v-html / html
textContent / v-text または {{ }} / text
innerText / なし / なし
innerTextはvueにはない。これはC言語のような'\n'で改行するパターンである。
HTMLのサンプルを示す。
<div id="id2">
<div>{{ data }}</div>
<div v-text="data"></div>
<div v-html="data"></div>
<div id="id2-1"></div>
</div>
<script>
const id2Text = '<b>太字</b>\nC言語改行後';
var vuei2 = new Vue({
el: '#id2',
data: { data: id2Text }
})
document.getElementById("id2-1").innerText = id2Text;
</script>
v-textとv-htmlは属性のような方法で指定する。実行結果を示す。
<b>太字</b> C言語改行後
<b>太字</b> C言語改行後
太字 C言語改行後
<b>太字</b>
C言語改行後
太字になっているところは b タグによるものである。
JavaScriptではdisplay:none;でない扱い、visibility: hidden;で見えない、要素を消すなどの方法で要素を消すことができる。また、クリックなどのイベントを設定できる。vueの場合のサンプルを示す。
<div id="id3">
<input type="checkbox" @click="change" checked>
<span v-show="seen">Hello!1</span>
<div v-show="seen">Hello!2</div>
<div>Hello!3</div>
</div>
<script>
var vuei3 = new Vue({
el: '#id3',
data: { seen: true },
methods: {
change: function(e) {
this.seen = e.target.checked
}
}
})
</script>
実行結果はチェック1つと以下が表示される。
Hello!1
Hello!2
Hello!3
チェックを押すと、1つ改行後「Hello!3」だけが表示される。
「@click="change"」の部分はイベントを設定している。ここで「@」は「v-on:」と同じである。イベントは「methods」の「change」が実行される。v-showは値がfalseのときは、「display: none;」が設定される。これは「Hello!2」と表示されるdiv要素が詰められることから「display: none;」が設定されると推測でき、Chromeの検証で設定されることを確認できる。
ifのような条件によって要素を消すことができる。サンプルを示す。
<div id="id4">
<input type="text" v-model="message">
<div v-if="error.require">入力して。</div>
<div v-else-if="error.tooLong">5文字以下にして。</div>
<div v-else>OK</div>
</div>
<script>
var vuei4 = new Vue({
el: '#id4',
watch: {
message: function(newVal, oldVal) {
this.error.require = newVal.length < 1;
this.error.tooLong = newVal.length > 5;
}
},
data: {
message: '既定入力',
error: {
require: false,
tooLong: false
}
}
})
</script>
実行するとテキストボックスと、その下にテキストが表示される。テキストボックスの文字の長さによって下のテキストが変化する。Chromeで検証を行うと表示されない要素は削除されることが分かる。
「v-if」、「v-else-if」、「v-else」はプログラミングの条件文のような形になっている。条件に合っている部分が表示される。watchは監視プロパティと呼ばれ、この場合はmessageが変更されるたびにメソッドが呼び出される。監視対象は「v-model」はvueオブジェクトと関連付けを行う。
watchではなく、算出プロパティと呼ばれるcomputedを使う方法もある。
<div id="id5">
<input type="text" v-model="message">
<div>{{ status }}</div>
</div>
<script>
var vuei5 = new Vue({
el: '#id5',
computed: {
status: function () {
var len = this.message.length;
return len < 1 ? '入力して。' : len > 5 ? '5文字以下にして。' : 'OK';
}
},
data: {
message: '既定入力'
}
})
</script>
表示結果は前のid4サンプルと同じである。
this.message.lengthで入力された文字列の長さを取得している。テキストボックスの文字が変化するとcomputedが呼び出される仕掛けである。
今まで「var vuei5 = new Vue()」のようにインスタンスを生成していながら、インスタンスへの参照は使わなかった。ここではラジオボタンから参照する例を示す。
<div id="id6">
<input type="radio" name="vuei6radio-group" onclick="vuei6.hour='8'" checked>8
<input type="radio" name="vuei6radio-group" onclick="vuei6.hour='12'">12
<input type="radio" name="vuei6radio-group" onclick="vuei6.hour='17'">17
時<br>
<span v-if="hour=='8'">おは</span>
<span v-else-if="hour=='12'">こんちは</span>
<span v-else>バイバイ</span>
</div>
<script>
var vuei6 = new Vue({
el: '#id6',
data: { hour: '8' }
})
</script>
実行するとラジオボタンが3つ配置され、下の行にメッセージが表示される。ラジオボタンを毎にメッセージが変更される。「onclick="vuei6.hour='8'"」などのところでvueインスタンスを参照している。
練習を含めてid6サンプルを書き換える。
<div id="id7">
<input type="radio" name="vuei6radio-group" onclick="vuei7.greet='おは'" checked>8
<input type="radio" name="vuei6radio-group" onclick="vuei7.greet='こんちは'">12
<input type="radio" name="vuei6radio-group" onclick="vuei7.greet='バイバイ'">17
時<br>
<span>{{ greet }}</span>
</div>
<script>
var vuei7 = new Vue({
el: '#id7',
data: { greet: 'おは' }
})
vuei7.greet = 'やあ'; // vueインスタンス参照(おまけ扱い)
</script>
実行結果は最初に「やあ」と表示される以外は変わらない。dataは時間ではなく、メッセージにしている。「greet: 'おは'」の部分はコード最後の「vuei7.greet = 'やあ';」で上書きされる(実行結果としては「greet: 'おは'」は無効である)。
配列を表示したい時に利用できる。
<div id="id8">
<ul>
<li v-for="country in countries">{{ country }}</li>
</ul>
</div>
<script>
var vuei8 = new Vue({
el: '#id8',
data: { countries: [ 'アメリカ', '中国', '日本' ] }
})
vuei8.countries.push('インド'); // 追加
</script>
表示結果はリストで、アメリカ、中国、日本、インドと表示される。
dataは配列が使用されている。v-forでは配列要素を全てループ表示している。「vuei8.countries.push('インド');」では要素を最後に追加している。
属性を変更するには v-bind: を使う。サンプルを示す。
<div id="id9">
<input type="text" v-model="inputText">
<input type="button" v-bind:value="inputText">
<div>{{ inputText }}</div>
<div v-html="inputText"></div>
</div>
<script>
var vuei9 = new Vue({
el: '#id9',
data: { inputText: 'hello<br>line 2' }
})
</script>
まず、表示結果は「hello<br>line 2」と書かれたテキストボックスとボタン。それから以下のテキストである。
hello<br>line 2
hello
line 2
紛らわしくなってきたので復習のためv-htmlなどを追加したが、重要なのは太字の「v-bind:value」である。value要素が更新されるのである。
応用でスタイルを適用してみよう。
<div id="id10">
<input type="text" size="80" v-model="myStyle">
<div v-bind:style="myStyle">div</div>
</div>
<script>
var vuei10 = new Vue({
el: '#id10',
data: { myStyle: 'width:162px; height:100px; background-color:red; margin:10px;' }
})
</script>
実行すると上のテキストボックスにスタイルが入力されており、下のdiv要素にそのスタイルが適用される。style属性にも v-bind: が使えることが分かる。バインドされているので、テキストボックスのスタイルがリアルタイムに更新される。
なお、「v-bind:」は「:」と省略できるが、ソースの文字列検索しにくくなるので省略しない方が良い気がする。また、「v-model.」を「v-model.lazy」とlazy修飾子を付けるとchange イベントを監視し、決定時、つまりEnterを押したときや他をクリックしたときまでイベント発生を遅延できる。
「{{ }}」のところにフィルタを設定する例である。
<div id="id11">
<div>{{ message | pon }}</div>
<div>{{ message | tolower }}</div>
</div>
<script>
var vuei11 = new Vue({
el: '#id11',
data: { message: 'Congratulations!' },
filters: {
pon: function(value) {
return '(*゚▽゚)_∠※ ' + value;
},
tolower: function(value) {
return value.toLowerCase();
}
}
})
</script>
結果は以下のようになる。
(*゚▽゚)_∠※ Congratulations!
congratulations!
HTMLでは「{{ message | pon }}」で、JavaScriptではfiltersでフィルタを設定している。
フック関数はオブジェクトが作成されたときなどに呼び出すことができる。
<div id="id12">
</div>
<script>
var vuei12 = new Vue({
created: function() {
document.getElementById("id12").textContent = 'Vue created.';
}
})
</script>
結果は「Vue created. 」と表示される。
インスタンスの作成、破棄、データ更新、renderの各前後と、コンポーネントの活性化、非活性化、エラー時に設定できる。
公式のEnter/Leave とトランジション一覧ページのコードを使用する。
<div id="id13">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
<script>
var vuei13 = new Vue({
el: '#id13',
data: {
show: true
}
})
</script>
結果はtoggleボタンとhelloテキストが表示されて、ボタンをクリックするたびに表示・非表示が切り替わる。加えて以下のcssを追加する。
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
これでトランジションエフェクトがかかり、helloテキスト消えるときと現れるとき半透明になりながら処理される。
ミックスインを使うと、オブジェクトを分割してライブラリのように利用することができる。
<div id="id14">
<input type="button" @click="ShowData" value="ShowData">
</div>
<script>
var myMixin = {
methods: {
ShowData: function() {
alert(this.myData);
}
}
}
var viei14 = new Vue({
el: '#id14',
data: {
myData: 'I live in Japan.'
},
mixins: [ myMixin ]
})
実行するとShowDataボタンが表示され、クリックするとI live in Japan.と表示される。ShowDataメソッドを持つmyMixinを定義している。