人気のJSフレームワーク「Vue.js」のコードを「jQuery」等と比べて書いてみた!
こんにちは。かみっちです。
最近「Vue.js」を学習し始めました。「JavaScript(普通のやつ。以下、プレーンなJavaScriptと記述)」や「jQuery」と比較して、記述がどんな感じで変わるのか、簡単なプログラムをつくって、比較してみようと思います。
こんなのは検索すればいくらでも出てきますが、学習したことをアウトプットすることが大事なのです!
そもそも「JavaScript」「jQuery」「Vue.js」って何やねん
それぞれをざっくり説明すると、以下のような感じです。
- JavaScript:ウェブページのHTMLを動的に変更できるプログラミング言語。
ボタンを押したら開くアコーディオンや自動で変わるスライド画像、ページスクロールによって出現する文字など、主にJavaScriptを使用して実装されている。 - jQuery:JavaScriptのライブラリ。中身はJavaScriptのプログラムの集合体。
プレーンなJavaScriptと比べると、短い記述で済んだり、ブラウザ間の差異も良い感じに動くようにしてくれる。 - Vue.js:JavaScriptフレームワーク。データに合わせてDOMを構築し、出力する。
「Vue.js」の解説が何とも説明しにくいのですが、後程コードをみたらなんとなく意味がわかると思います。
同じようなプログラム書いて比較してみましょ
簡単なサンプルプログラムを例に比較してみましょう。
たとえば、ドラえもんの映画を一覧で出力するページの制作依頼がきたとします。(藤子プロさん、ご依頼をお待ちしております)
// 各映画を配列に格納 const movieList = [ "のび太の恐竜", "のび太の宇宙開拓史", ~ 中略 ~ "のび太の新恐竜", "のび太の宇宙小戦争 2021" ];
映画を配列に格納しました。このデータを元に、「プレーンなJavaScript」「jQuery」「Vue.js」でそれぞれ書き比べてみます。
まずはプレーンなJavaScriptで記述。
サンプルプログラム1(プレーンなJavaScript)
<ul id="js-list01"> <!-- ここにJSで各映画名を出力する --> </ul>
// 出力先のIDを定数に格納 const js01_list = 'js-list01'; // 各データを<li>タグで囲って、配列に格納 const js01_output = movieList.map(function(v){ return '<li>' + v + '</li>' }); // join()で配列を文字列として連結し、HTMLで出力 document.getElementById(js01_list).innerHTML = js01_output.join('');
ややこしいことはしていないので、特に解説は不要かと思います。
配列を<li></li>で囲んで出力してるだけ。
お次は世間でオワコンなんて言われてるかわいそうなjQueryで記述してみましょう。
サンプルプログラム1(jQuery)
<ul id="jq-list01"> <!-- ここにJSで各映画名を出力する --> </ul>
// 出力先の要素を定数に格納 const jq01_list = $('#jq-list01'); // 各データを<li>タグで囲って、配列に格納 const jq01_output = movieList.map(function(v){ return '<li>' + v + '</li>' }); // 配列をHTMLで出力 jq01_list.append(jq01_output);
プレーンなJavaScriptとほぼ同じ感じで書けます。セレクタの指定に「document.getElementBy~」と書かず「$(セレクタ)」と書けばよいのでコードが見やすくなりますね。大好きですjQuery。だれだオワコンなって言った人は。まだまだ実務でも余裕で使います。
ただ、どちらもタグ自体の指定をJS内に記述しているため、「<li>にclassを追加してください」や「<li>ではなく<div>に変更してください」といった、HTML構造の変更指示があったときに、HTMLに記述されていない為、JSの該当箇所を探して書き換えないといけません。長いプログラムになると見つけるのが大変です。
ここまでが前座。これをVue.jsで書き直してみます。
サンプルプログラム1(Vue.js)
<div id="app01"> <ul> <li v-for="movie in movies">{{ movie }}</li> </ul> </div>
var app01 = new Vue({ el: '#app01', data: { movies: movieList } })
- {{ movie }}
Vue.jsだとJSの記述がすっきりしました。
コードを簡単に解説すると、以下になります。
el: '#app01'
Vue.jsで動かす要素の指定。
data: { movies: movieList }
Vue.jsで使用するデータを定義。
映画のリストを「movies」に格納。
<li v-for="movie in movies">{{ movie }}</li>
「movies」の要素分<li>を繰り返し出力。
その際、各要素を「movie」変数に入れる。(v-for="movie in movies")
「movie」変数を出力。({{ movie }})
ポイントは、先ほどのコードと異なり、JSの記述内容がHTML構造に依存せず、分離しているということです。これで「HTML構造を<div>に変えてくれ」とか「わしゃ<table>が好きなんや」みたいなことを言われてもHTMLのほうを変更するだけなのでラクチンです。やったね!
次は検索ボックスを追加してみましょう。
「”のび太と”を含む映画だけを抽出したいんや」という瞬間が、長い人生において訪れることもあるでしょう。
先ほどのプレーンなJavaScriptで記述したコードに、検索ボックスを追加してみます。
サンプルプログラム2(プレーンなJavaScript)
<p><input type="text" id="js-search" placeholder="ex.のび太と" value=""></p> <ul id="js-list02"> <!-- ここにJSで各映画名を出力する --> </ul>
const js02_list = 'js-list02'; const js02_search = 'js-search'; // リストを書き換える関数 function js02_outputHtml(){ // リストのHTMLを一旦空にする document.getElementById(js02_list).innerHTML = ''; // 検索ボックスの値を取得 const inputVal = document.getElementById(js02_search).value; // 検索ボックスの値と映画の文字列が部分一致したら出力用配列に追加 const js02_output = movieList.map(function(v){ if(v.indexOf(inputVal) !== -1){ return '<li>' + v + '</li>' } }); document.getElementById(js02_list).innerHTML = js02_output.join(''); } // 検索ボックスの値が変わったら関数を実行 document.getElementById(js02_search).addEventListener('keyup', function(){ js02_outputHtml(); }); js02_outputHtml();
入力した値を取得する処理と、取得した値を取捨選択して出力する処理が追加された為、長くなりましたね。いたしかたなし。
今度はjQueryで、検索ボックスを追加してみます。
サンプルプログラム2(jQuery)
<p><input type="text" id="jq-search" placeholder="ex.のび太と" value=""></p> <ul id="jq-list02"> <!-- ここにJSで各映画名を出力する --> </ul>
const jq02_list = $('#jq-list02'); const jq02_search = $('#jq-search'); // リストを書き換える関数 function jq02_outputHtml(){ // リストのHTMLを一旦空にする jq02_list.html(''); // 検索ボックスの値を取得 const inputVal = jq02_search.val(); // 検索ボックスの値と映画の文字列が部分一致したら出力用配列に追加 const jq02_output = movieList.map(function(v){ if(v.indexOf(inputVal) !== -1){ return '<li>' + v + '</li>' } }); jq02_list.append(jq02_output); } // 検索ボックスの値が変わったら関数を実行 jq02_search.on('change keyup',function(){ jq02_outputHtml(); }); jq02_outputHtml();
-
<!-- ここにJSで各映画名を出力する -->
少しだけ見やすくなりましたが、このレベルのプログラムだとやっている処理自体はたいしたことないので、記述量はそんなに変わらないですね。
Vue.jsで作ったほうも同様に検索ボックスを追加してみましょう。
サンプルプログラム2(Vue.js)
<div id="app02"> <p><input type="text" placeholder="ex.のび太と" v-model="vueSearch"></p> <ul> <li v-for="movie in getFilterOutput()">{{ movie }}</li> </ul> </div>
var app02 = new Vue({ el: '#app02', data: { movies: movieList, vueSearch: '' }, methods: { getFilterOutput: function(){ const searchVal = this.vueSearch; const filterData = this.movies.filter(function(v){ return v.indexOf(searchVal) !== -1; }); return filterData; } } })
- {{ movie }}
コードの簡単な解説をば。
<p><input type="text" placeholder="ex.のび太と" v-model="vueSearch"></p>
検索ボックスの値を「vueSearch」と連動させる。(v-model="vueSearch")
vueSearch: ''
「vueSearch」の初期値は空(検索ボックスの値が変わると、連動してこの値も変わる)。
methods: { getFilterOutput: function(){
「getFilterOutput」というメソッドを用意。
const filterData = this.movies.filter(function(v){
映画一覧をフィルタ処理して、配列に代入。
return v.indexOf(searchVal) !== -1;
検索ボックスの値と映画の文字列が部分一致した値だけ返り値にする。
return filterData;
フィルタ結果の配列「filterData」を返り値にする。
<li v-for="movie in getFilterOutput()">{{ movie }}</li>
「getFilterOutput()」の実行結果の要素分<li>を繰り返し出力。
その際、各要素を「movie」変数に入れる。(v-for="movie in getFilterOutput()")
「v-model」は、ビュー(inputのvalue)が更新されると、データ(vueSearchの値)も連動して変わる。逆もまたしかり。とても便利!これを双方向データバインディングと言います。
こういう処理が簡単な記述で実装できるので、今までチマチマjQueryなんかで書いてた人は、一度vue.jsにチャレンジしてみてはいかがでしょうか。書籍とかいろいろ出てますが、公式サイトがフル日本語でわかりやすいので、まずは「Hello Vue!」からはじめてみましょう!
以上、「のび太とロボット王国」以降まったく観てない、のぶ代世代の、かみっちでした!
サイドスリーではJavaScriptに自信のある方を強く募集しております。(JavaScriptに自信のない方も募集しております。)
まずはお話だけでも如何でしょうか。