はじめに
「ネイティブアプリっぽい見た目のWebアプリを作りたいけれど、iOSとAndroidでUIの流儀が違いすぎて、CSSを書くだけで一日が終わってしまう」——モバイル向けのWebアプリやPWAを作ったことがある方なら、一度はこの壁にぶつかったことがあるのではないでしょうか。
Framework7は、この悩みをまるごと解決してくれるUIフレームワークです。ナビバーやツールバー、ダイアログ、ポップアップといったモバイルアプリに欠かせないコンポーネント一式を、iOSテーマとMD(Android)テーマの両対応で最初から用意してくれます。しかも素のJavaScriptだけでなく、React・Vueのコンポーネントとしても同じUIを呼び出せるのが大きな特徴です。
とはいえ、読むより触った方が早いと思います。ダイアログやポップアップが実際にどう動くか、先に挙動を見たい方はこちらからどうぞ。
Framework7とは
Framework7は、iOS・Android・デスクトップ向けのアプリを「ネイティブライクな見た目」で作れる、オープンソースのUIフレームワークです。HTML・CSS・JavaScriptだけで動く「Core版」に加え、React・Vue向けのコンポーネントパッケージも公式に提供されており、Cordova/CapacitorやElectronと組み合わせてアプリストアに配布することもできます。
主な特徴
- 豊富なモバイルUIコンポーネント - ナビバー、ツールバー、リストビュー、ポップアップ、ダイアログ、タブなど、モバイルアプリに必要な部品がひと通り揃っています
- iOS / MD(Android)テーマの自動切り替え -
theme: 'auto'を指定するだけで、動作しているOSに合わせたルック&フィールに切り替わります - Core・React・Vueの3系統に対応 - 同じコンポーネント群を、素のJavaScript・React・Vueのいずれのプロジェクトでも同じ感覚で呼び出せます
- PWA・Cordova・Capacitor・Electron対応 - Webアプリとしてだけでなく、そのままネイティブアプリの器に載せて配布できます
インストール
npmから直接インストールするか、専用のCLIでプロジェクトを作成できます。
# Core(素のJavaScript)版
npm install framework7
# React向けコンポーネント
npm install framework7 framework7-react
# Vue向けコンポーネント
npm install framework7 framework7-vue
# プロジェクトをまとめて作りたい場合
npm install -g framework7-cli
framework7 create
Framework7のサンプルを動かす
Framework7でまず体験してほしいのが、app.dialog と app.popup のAPIです。「Alertを開く」を押すとネイティブ風のアラートダイアログが、「Popupを開く」を押すと画面下からポップアップが表示されます。以下がその要点を抜き出したコードです。
import Framework7 from 'framework7/bundle'
const app = new Framework7({ el: '#app', theme: 'auto' })
app.dialog.alert('Framework7のalertダイアログです', 'お知らせ')
app.dialog.confirm('本当に実行しますか?', () => {
console.log('OK')
}, () => {
console.log('キャンセル')
})
app.popup.open('#my-popup')
実際に動かせるものが下です。「Confirmを開く」ではOK/キャンセルどちらを押したかが画面に反映されます。
app.dialog.confirm() の第2引数がOK時、第3引数がキャンセル時のコールバックです。app.dialog.alert('本文', 'タイトル') のようにタイトルを差し替えたり、app.popup.open() の対象セレクタを別のポップアップに変えたりすると、挙動がその場で変わるので試してみてください。
基本的な使い方
Framework7のCore版は、class="view" > class="page" という決まったDOM構造の中に new Framework7() を渡すだけで動き始めます。ナビバーやページコンテンツもすべてCSSクラスで表現するのが特徴です。
<div id="app">
<div class="view view-main">
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="title">My App</div>
</div>
</div>
<div class="page-content">
<div class="block">Hello Framework7!</div>
</div>
</div>
</div>
</div>
import Framework7 from 'framework7/bundle'
import 'framework7/css/bundle'
const app = new Framework7({
el: '#app',
name: 'My App',
theme: 'auto', // iOSならiOSテーマ、AndroidならMDテーマに自動切り替え
})
el で指定した要素の中身をFramework7が解析し、.navbar や .page-content といったクラスをもとにレイアウトを組み立てます。ビルド不要のプロトタイピングであればCDN版の framework7-bundle.min.js / .css を <script> <link> で読み込むだけでも同じように動きます。
実践的なユースケース
Framework7のもう一つの強みは、同じUIコンポーネント群をCore・React・Vueのどれで書いても迷わないことです。プロジェクトの技術スタックに合わせて選び方が変わるので、それぞれのパターンを見てみましょう。
Core(素のJavaScript)でタブ切り替え画面を作る
ビルド環境を用意せず、素のJavaScriptだけでモバイルアプリらしい画面遷移を作りたいときのパターンです。.tab-link と .tabs / .tab というクラスを対応させるだけで、JavaScript側のコードを書かずにタブ切り替えが実現できます。
<div class="toolbar tabbar-labels">
<div class="toolbar-inner">
<a href="#tab-home" class="tab-link tab-link-active">Home</a>
<a href="#tab-settings" class="tab-link">Settings</a>
</div>
</div>
<div class="tabs">
<div class="tab tab-active" id="tab-home">Homeタブの内容</div>
<div class="tab" id="tab-settings">Settingsタブの内容</div>
</div>
タブを増やしたい場合は、.tab-link に href="#tab-xxx" を追加し、対応する .tab 要素の id を揃えるだけです。JavaScript側の初期化コードは一切変更せずに済みます。
framework7-reactでReactコンポーネントとして組み込む
すでにReactでアプリを作っていて、UI部分だけFramework7に任せたいケースです。framework7-react パッケージが提供する <App> <View> <Page> <List> <Toggle> などのコンポーネントを、通常のReactコンポーネントと同じ感覚で組み合わせられます。
import { App, View, Page, Navbar, List, ListItem, Toggle } from 'framework7-react'
function MyApp() {
const [checked, setChecked] = useState(true)
return (
<App theme="auto">
<View main>
<Page>
<Navbar title="設定" />
<List>
<ListItem title="通知を受け取る">
<Toggle slot="after" checked={checked}
onToggleChange={() => setChecked(!checked)} />
</ListItem>
</List>
</Page>
</View>
</App>
)
}
<Toggle> の checked propとReactの useState を組み合わせているので、トグルを押すたびに下の「状態」表示がON/OFFで切り替わります。同じ要領で <Range> や <Checkbox> なども通常のReactコンポーネントとして扱えます。
framework7-vueでVueコンポーネントとして組み込む
Vueプロジェクトの場合は framework7-vue を使い、<f7-app> <f7-range> のようなケバブケースのタグで同じUIを呼び出せます。Vueらしく v-model:value で双方向バインディングできるのが特徴です。
<template>
<f7-app :params="{ theme: 'auto' }">
<f7-view main>
<f7-page>
<f7-navbar title="音量設定" />
<f7-range :min="0" :max="100" :step="1"
v-model:value="volume" :label="true" />
<p>音量: {{ volume }}</p>
</f7-page>
</f7-view>
</f7-app>
</template>
スライダーのノブをドラッグすると f7-range の v-model:value を通じて volume がリアルタイムに更新され、その下の表示にそのまま反映されます。min / max / step を変えれば、音量以外にも数量選択や評価スコアなど、さまざまな用途に流用できます。
まとめ
Framework7を使うと、ナビバーやダイアログ、ポップアップ、タブ切り替えといったモバイルアプリの定番UIを、CSSをゼロから書くことなく組み立てられます。何よりの強みは、同じコンポーネント資産をCore・React・Vueのいずれからでも呼び出せる点で、チームの技術スタックが変わってもUI設計をそのまま持ち越せます。PWAとして公開するのはもちろん、CordovaやCapacitorでそのままアプリストアに載せることもできるので、まずは今回のサンプルを手元で書き換えて、theme や各コンポーネントのpropsを触ってみてください。