はじめに
MonacaとOnsenUIではVue.jsが使えますが、実際に使用した際にはいくつか立ちはだかる壁があります
そのひとつが、 v-ons-tabbar
のタブボタンに設定できるアイコンが FontAwesome のものしか扱えない、という問題(?)です
本稿ではその問題を解決してみます
前提
- Monaca LocalKitを使用します。(執筆時のバージョンは3.4.0でした)
- この記事では、Monaca Localkitから選択できるテンプレートのうち、以下を使用しています
- カテゴリ: OnsenUI and Vue.js
- テンプレート: Onsen UI V2 Vue Tabbar
- 一応、
v-ons-tabbar
とv-ons-navigator
を複合的に使用しているアプリでも動作することを確認しておりますが、実装によっては上手く動かないかもしれません
目標
- Monaca + OnsenUI + Vue.js で自作のアイコンをタブボタンに表示できるようにする
1. v-ons-tabbar
の data
からicon
と label
を削除する
既存の icon
と を削除しますlabel
理由はそれぞれ次の通りです
-
icon
パラメータでは自作の画像を設定することができない為 -
icon
が無い状態でlabel
が定義されている場合、タブのボタン一面がlabel
で指定した文字列いっぱいになってしまう為 (下記画像のようになります)- (2020/01/31追記:
label
の定義を削除すると、ツールバーに表示されているタイトルまで消えてしまいますので、削除してはなりません (別の方法でタブバーからラベルはご退場願う方法を追記しております))
- (2020/01/31追記:
サンプルコード
data() {
return {
activeIndex: 0,
tabs: [
{
// この icon と label を削除します (ここではコメントアウトで対応します)
//icon: this.md() ? null : 'ion-home',
label: 'Home',
page: homePage
},
{
//icon: this.md() ? null : 'ion-ios-bell',
label: 'News',
page: newsPage,
badge: 7
},
{
//icon: this.md() ? null : 'ion-ios-settings',
label: 'Settings',
page: settingsPage
}
]
};
},
2. Vue.jsのオブジェクトに mounted()
を追加し、その中で画像を表示するHTMLを追加する
続いて、javascript部分を記述していきます
Vueのライフサイクルから考えて、実際のビューを操作できるのは mounted()
のタイミングですので、このタイミングで操作します
具体的には、 ons-tabbar__footer
の中の孫要素にidをつけたdivを突っ込むという方法になります
document.querySelector(".ons-tabbar__footer").childNodes[0]
という記述がありますが、この要素数がタブボタンのindexになっており、左から0, 1, 2とindexが増えるごとに右のボタンが指定されます。
setTimeout()
していますが、これによって、実際に追加するタイミングをずらしています
本当はあまりよくない方法ですので、良い対応方法をご存じの方いらっしゃいましたらご教示くださいませ
サンプルコード
mounted() {
setTimeout(() => {
const btnHomeImg = document.createElement("div");
btnHomeImg.id = 'tabbtn_home';
document.querySelector(".ons-tabbar__footer").childNodes[0].lastChild.appendChild(btnHomeImg);
const btnNewsImg = document.createElement("div");
btnNewsImg.id = 'tabbtn_news';
document.querySelector(".ons-tabbar__footer").childNodes[1].lastChild.appendChild(btnNewsImg);
const btnSettingImg = document.createElement("div");
btnSettingImg.id = 'tabbtn_setting';
document.querySelector(".ons-tabbar__footer").childNodes[2].lastChild.appendChild(btnSettingImg);
}, 200)
},
components: { homePage, settingsPage, newsPage }
}
3. スタイルシートでタブで表示するアイコンを指定する
最後に、スタイルシートで先ほど作成したidつきの <div>
タグにスタイルを設定していきます
このタイミングで、タブバーの色を変更できます
また、バッチを使用している場合、下記記載のようなスタイル指定を行わないと、タブボタンに指定した画像が表示されなくなります
サンプルコード
(2020/01/31追記: 上記の手順でタブバーにラベルが表示されるようになりましたので、タブバーにラベルを表示しないスタイルを追加しました)
/*
*タブバーの背景色 => アプリのイメージに合わせて適宜変更します
*/
.tabbar.ons-tabbar__footer.ons-swiper-tabbar {
background: tan;
}
/*
* タブバーでバッチを使用している場合、この指定が必要です。
* バッチの上下の位置は top の値で変更できます (小さいほど上に移動)
*/
.tabbar__badge.notification {
position: absolute;
top: 20%;
}
/*
* タブバーからそれぞれラベルを削除する方法になります
* display: none; で表示されなくなります
*/
.tabbar__label {
display: none;
}
/*
* ホーム画面のタブボタンの指定です
*/
# tabbtn_home {
background-image: url(img/summer_uminoie.png);
background-size: contain;
background-repeat: no-repeat;
background-position: center;
margin: 6% 0;
height: 55%;
}
/*
* ニュース画面のタブボタンの指定です
*/
# tabbtn_news {
background-image: url(img/shinbun_girl.png);
background-size: contain;
background-repeat: no-repeat;
background-position: center;
margin: 6% 0;
height: 55%;
}
/*
* 設定画面のタブボタンの指定です
*/
# tabbtn_setting {
background-image: url(img/haguruma.png);
background-size: contain;
background-repeat: no-repeat;
background-position: center;
margin: 6% 0;
height: 55%;
}
完成
これで自作の画像 (今回はいらすとや様から拝借致しました、いつもありがとうございます) を指定できました
現状、OnsenUI + Vue.jsの場合、タブバーのアイコンを自作画像に変更するにはこの方法しかありません
このあたりが使いやすくなってくれるとありがたいですね。。。