Vue.jsでデータをツリー構造で表示させて子ノードを隠したり表示させたりする
前回のブログで、Vue.jsでデータをツリー構造で表示させる方法を紹介しました。
今回は、こいつの子ノードを隠して表示させて、親ノードをクリックしたら現れるようにしたいと思います。
[ad#top-1]
まずは完成形
初期画面は以下のような表示になります。
以下のように項目をクリックすると、それぞれの子ノードが現れます。
更にもう一度項目をクリックすると子ノードが隠れます。
まあ、よくある一般的なツリービューの動きと同じですね。
解説
データ構造は前回と変わりありません。
data: { folders: [ { name: '検索', pages: [{name: 'Google'}, {name: 'Yahoo!'}, {name: 'goo!'}] }, { name: 'SNS', pages: [{name: 'Facebook'}, {name: 'Twitter'}, {name: 'Google+'}, {name: 'mixi'}] }, { name: 'Shpping', pages: [{name: 'Amazon'}, {name: 'ヤフオク'}, {name: 'ebay'}, {name: '楽天'}] } ] },
HTMLの方ですが、すべてdiv要素にしたという他に、2点違いがあります。
1つ目は親ノードに@click=”toggle(folder.name)”という部分を入れています。これはHTMLのonclickと同じで、クリックしたらJavaScriptのtoggle関数をコールすることを意味しています。引数にフォルダ名を渡しています。
<span @click="toggle(folder.name)" style="cursor: pointer;">+ {{ folder.name }}</span>
次に、隠したり表示させたりするので、各子ノードを特定するためにそれぞれidを割り当てる必要があります。また、子ノードをあらかじめ隠しておく必要があります。
子ノードを以下のdivタグで括ります。
<div v-show="false" :id="folder.name">
最後にtoggle関数ですが、Vue.jsではイベント処理をmethods内に書きます。渡されたIDが隠れていれば表示、表示されていれば隠す、という処理を行っています。
methods: { toggle: function (idname) { if( document.getElementById(idname).style.display == "none" ){ document.getElementById(idname).style.display = "inline"; }else{ document.getElementById(idname).style.display = "none"; } }, }
全体のソースコード
こちらが全体のソースコードです。コピペしてブラウザで開けば冒頭の動きとなります。
<!DOCTYPE html> <html> <head> <title>Test</title> <style type="text/css"> body{ font-family: 'Meiryo UI'; font-size: 14pt; margin-top: 20px; margin-left: 30px; } </style> </head> <body> <div id="example-3"> <div v-for="folder in folders"> <span @click="toggle(folder.name)" style="cursor: pointer;">+ {{ folder.name }}</span> <div v-show="false" :id="folder.name"> <div v-for="page in folder.pages" style="margin-left: 20px;"> <span> - {{ page.name }}</span> </div> </div> </div> </div> </body> <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/2.2.0/vue.js"></script> <script> var example3 = new Vue({ el: '#example-3', data: { folders: [ { name: '検索', pages: [{name: 'Google'}, {name: 'Yahoo!'}, {name: 'goo!'}] }, { name: 'SNS', pages: [{name: 'Facebook'}, {name: 'Twitter'}, {name: 'Google+'}, {name: 'mixi'}] }, { name: 'Shpping', pages: [{name: 'Amazon'}, {name: 'ヤフオク'}, {name: 'ebay'}, {name: '楽天'}] } ] }, methods: { toggle: function (idname) { if( document.getElementById(idname).style.display == "none" ){ document.getElementById(idname).style.display = "inline"; }else{ document.getElementById(idname).style.display = "none"; } }, } }) </script> </html>
.
[ad#ad-1]
スポンサーリンク