1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Mithril.js Router の応用 - レイアウト、複数コンポーネントを考えた 実用編

Last updated at Posted at 2020-06-17

Mithril.js Router の応用 - レイアウト、複数コンポーネントを考えた 実用編

例えば http://localhost/page1というURLへのアクセスは Page1Component を表示して、http://localhost/page2Page2Component を表示したい場合です。

もし、1つの URL が1つのコンポーネントだけで構成されているなら、Mithril.js では、オフィシャルのドキュメントにも書かれている通り簡単です。
ですが、もし1つのURL が1つ以上のコンポーネントで構成されて、共通箇所が有る場合、例えばメニュー等がふくまれコンポーネントが入り組んでいる場合は、作成にコツがいります。

基本 : 1つのURLが1つのコンポーネント

おさらい。これは以下の通りで、特に説明の必要もないと思います。

m.route(document.body, '/page1', {
	'/page1' : Page1Component,
	'/page2' : Page2Component,
}

http://localhost/page1 から http://localhost/page2 へ切り替わるときには、<Page1Component> の DOM は削除され、<Page2Component> の DOMが作成されます。特に何も問題となることは無いはずです。

1つのURLが2つ以上のコンポーネントで、共通箇所が有る場合

この場合は注意が必要です。

http://localhost/page1 から http://localhost/page2 へ切り替わるときには、<Page1Component> の DOM は削除され、<Page2Component> の DOMが新しく作成されるのは良いとして、
問題は、共通箇所である <MenuComponent> の DOM が削除されて、再びDOMが再作成されると厄介な問題が発生します。

具体的には <MenuComponent> に使うようなものですから、クリックしたときにCSSアニメーションなどをつけたり、ログインユーザーなどの変数を持っていたりする場合は少なくありません。もしDOM が削除、再作成されるようなことがあれば、CSSアニメーションが途切れたり、画面のチラつきなど、なにかと問題が発生するのです。これは良くは有りません。

これらを防止するために Mithril Router では RouteResolver というものが用意されています。
この RouteResolverを使えば、同じコンポーネントのDOMを 削除、再生成 されることを防げます。

class LayoutComponent {

	public view(vnode){
		return (
			<div>
				<div class="menu">
					<MenuComponent />
				</div>
				<div class="main">
					{ vnode.children }
				</div>
			</div>
		);
	}
}

class Page1Component {
	// .....
}

class Page2Component {
	// .....
}

const handleOnmatch = ()=>{
	window.requestAnimationFrame(()=>{
		window.scrollTo(0, 0);	// ページ切り替え時 スクロールバーを上部へスクロール
	});
	return;
};


m.route(document.body, '/page1', {
	'/page1' :  {
		onmatch: handleOnmatch,
		render: ()=>{ return <LayoutComponent><Page1Component /></LayoutComponent>; }
	} ,
	'/page2' :  {
		onmatch: handleOnmatch,
		render: ()=>{ return <LayoutComponent><Page2Component /></LayoutComponent>; }
	} ,
}

実際のコードを書く場合には、コンポーネントを1つにまとめる <LayoutComponent> 等のコンポネントで囲っておくのが良いでしょう。

他にも、ページが切り替わった時にブラウザは上部へスクロールするのがブラウザの一般的な動作です。onmatch でページ切り替え時 スクロールバーを上部へスクロールするようにしています。これで、ずいんぶん印象が違ってきますので、入れておくのが良いとは思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?