はじめに
NativeScript(NativeScript-Vue) で ボトムタブバーによるナビゲーションを行う方法。
TL;DR
目次
- はじめに
- TL;DR
- 環境・条件
- 詳細
- TabView による実装
- 実装サンプル
- 表示イメージ
- 簡単な解説など
- BottomNavigation による実装
- 実装サンプル
- 表示イメージ
- 簡単な解説など
- まとめ
- 参考文献
環境・条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| $ sw_vers ProductName: Mac OS X ProductVersion: 10.15.3 BuildVersion: 19D76
$ node -v v12.7.0
$ npm -v 6.10.3
$ tns --version 6.4.0
$ grep -C1 version package.json "tns-ios": { "version": "6.4.1" }, "tns-android": { "version": "6.4.1" }
$ tns plugin Dependencies: ┌──────────────────────────────┬─────────┐ │ Plugin │ Version │ │ @nativescript/theme │ ^2.2.1 │ │ @vue/devtools │ ^5.0.6 │ │ nativescript-socketio │ ^3.2.1 │ │ nativescript-toasty │ ^1.3.0 │ │ nativescript-vue │ ^2.4.0 │ │ nativescript-vue-devtools │ ^1.2.0 │ │ tns-core-modules │ ^6.0.0 │ │ vue-router │ ^3.1.5 │ └──────────────────────────────┴─────────┘ Dev Dependencies: ┌────────────────────────────────────┬─────────┐ │ Plugin │ Version │ │ @babel/core │ ^7.0.0 │ │ @babel/preset-env │ ^7.0.0 │ │ babel-loader │ ^8.0.2 │ │ nativescript-dev-webpack │ ^1.0.0 │ │ nativescript-vue-template-compiler │ ^2.0.0 │ │ nativescript-worker-loader │ ~0.9.0 │ │ node-sass │ ^4.9.2 │ │ vue-loader │ ^15.4.0 │ └────────────────────────────────────┴─────────┘
|
- iPhone 11 Pro: iOS 13.3
- Android HUAWEI nova lite 2: Android 9 (ビルド 9.1.0.160)
詳細
TabView
、もしくは BottomNavigation
で実装可能。
リポジトリ: 17number/nativescript-vue-tutorial
参考コミット:
TabView による実装
実装サンプル
TabView
を使う場合のサンプルコード。
参考コミット: @24cde8b
Android は androidTabsPosition="bottom"
を指定する(指定なしだとトップに配置されるので注意)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <template> <Page> <ActionBar :title="title"> <NavigationButton text="Back" android.systemIcon="ic_menu_back" @tap="back"/> </ActionBar> <TabView :selectedIndex="selectedIndex" @selectedIndexChange="onIndexChange" androidTabsPosition="bottom"> <TabViewItem title="Tab 1"> <FirstTab/> </TabViewItem> <TabViewItem title="Tab 2"> <SecondTab/> </TabViewItem> <TabViewItem title="Tab 3"> <ThirdTab/> </TabViewItem> </TabView> </Page> </template>
<script > import FirstTab from '@/tabs/FirstTab.vue' import SecondTab from '@/tabs/SecondTab.vue' import ThirdTab from '@/tabs/ThirdTab.vue'
export default { components: { FirstTab, SecondTab, ThirdTab, }, data() { return { selectedIndex: 0, title: 'Tab sample', }; }, methods: { back() { this.$navigateBack({ transitionAndroid: { name: 'slide '}, }); }, onIndexChange(args) { this.selectedIndex = args.value; this.title = `Tab sample - ${this.selectedIndex + 1}`; }, }, } </script>
|
コンテンツ部分。今回は別ファイルにしているが、↑ の TabViewItem
内に直接記述していっても可。
※ファイル分割や配置はまだよくわかってない。(app/tabs
or app/pages/tabs
or app/components/tabs
のどこが良いのか…)
1 2 3 4 5 6 7 8 9 10
| <template> <StackLayout> <Label text="1st tab content" textWrap="true" /> </StackLayout> </template>
<script > export default {} </script>
|
表示イメージ
iOS
Android
Android(androidTabsPosition="bottom"
無し)
簡単な解説など
args.value
に選択したタブの index
, args.oldValue
に前のタブの index
が設定されている。
1 2 3 4 5 6 7 8 9 10
| export default { ... methods: { ... onIndexChange(args) { this.selectedIndex = args.value; ... }, }, }
|
以下のように TabViewItem
の下で ActionBar
を指定するようなことはできない。タブごとに変更したい場合はイベントハンドラの中で処理する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <TabViewItem title="Tab 1"> <ActionBar title="Tab 1 selected"> <Label text="Content for Tab 1" /> </TabViewItem>
<script> export default { ... methods: { ... onIndexChange(args) { this.title = `Tab ${this.selectedIndex + 1} selected`; ... }, }, } </script>
|
アイコンを設定したい場合は以下のように iconSource
で設定する。
1 2 3
| <TabViewItem title="Tab 1" iconSource="~/images/icon.png"> <Label text="Content for Tab 1" /> </TabViewItem>
|
色変更は tabTextColor
, tabBackgroundColor
, tabBackgroundColor
などで可能、詳細は Styling - TabView - NativeScript Docs や Class TabView | NativeScript を参照
BottomNavigation による実装
NatvieScript-Vue のドキュメントには記載がないが、BottomNavigation
でも実現可能。
実装サンプル
参考コミット: @33ef36e
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| <template> <Page> <ActionBar :title="title"> <NavigationButton text="Back" android.systemIcon="ic_menu_back" @tap="back" /> </ActionBar> <BottomNavigation :selectedIndex="selectedIndex" @selectedIndexChanged="onIndexChange"> <TabStrip> <TabStripItem> <Label text="Home"/> <Image src="font://"/> </TabStripItem>
<TabStripItem class="special"> <Label text="Account"/> <Image src="font://"/> </TabStripItem>
<TabStripItem title="Search" iconSource="font://"/> </TabStrip>
<TabContentItem> <FirstTab /> </TabContentItem> <TabContentItem> <SecondTab /> </TabContentItem> <TabContentItem> <ThirdTab /> </TabContentItem> </BottomNavigation> </Page> </template>
<script > import FirstTab from '@/tabs/FirstTab.vue' import SecondTab from '@/tabs/SecondTab.vue' import ThirdTab from '@/tabs/ThirdTab.vue'
export default { components: { FirstTab, SecondTab, ThirdTab, }, data() { return { selectedIndex: 0, title: 'Tab sample', }; }, methods: { back() { this.$navigateBack({ transitionAndroid: { name: 'slide '}, }); }, onIndexChange(args) { this.selectedIndex = args.newIndex; this.title = `Tab sample - ${this.selectedIndex + 1}`; }, }, } </script>
|
表示イメージ
微妙に見た目が異なるが、CSS でどうにでも変更できると思われる。
iOS
Android
簡単な解説など
args.newIndex
に現在のタブの index
, args.oldIndex
に前のタブの index
が設定されている。
1 2 3 4
| onIndexChange(args) { this.selectedIndex = args.newIndex; ... },
|
ActionBar
については TabView
と同様、必要に応じてイベントハンドラ内で変更する。
BottomNavigation
の場合、メニュー部分とコンテンツ部分は別々に記載する。
メニュー部分は TabStrip
内に TabStripItem
で定義。
1 2 3 4 5 6 7 8 9 10
| <TabStrip> <TabStripItem> <Label text="tab 1"/> <Image src="..."/> </TabStripItem> <TabStripItem> <Label text="tab 2"/> <Image src="..."/> </TabStripItem> </TabStrip>
|
上記はショートハンドで以下のようにも書ける。
1 2 3 4
| <TabStrip> <TabStripItem title="tab 1" iconSource="..."/> <TabStripItem title="tab 2" iconSource="..."/> </TabStrip>
|
コンテンツは TabContentItem
で定義。
1 2 3 4 5 6
| <TabContentItem> <Label text="content 1" /> </TabContentItem> <TabContentItem> <Label text="content 2" /> </TabContentItem>
|
その他詳細は BottomNavigation - NativeScript Docs や Class BottomNavigation | NativeScript を参照
まとめ
参考文献
関連記事