Skip to content
Mithril.js 2
Main Navigation ガイドAPI

日本語

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
한국어
Italiano
Polski
Türkçe
čeština
magyar

日本語

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
한국어
Italiano
Polski
Türkçe
čeština
magyar

外観

Sidebar Navigation

API

コア API

m(selector, attributes, children)

render(element, vnodes)

mount(root, component)

route(root, defaultRoute, routes)

request(options)

parseQueryString(string)

buildQueryString(object)

buildPathname(object)

parsePathname(文字列型)

trust(html)

fragment(attrs, children)

redraw()

censor(object, extra)

オプション API

stream()

ガイド

このページの内容

m(selector, attributes, children) ​

Description ​

Mithril.js のビューにおける HTML 要素を表現します。

javascript
m('div.foo', { style: { color: 'red' } }, 'hello');
// renders to this HTML:
// <div class="foo" style="color: red">hello</div>

Babel を使用して、同等の hyperscript 呼び出しに変換する JSX と呼ばれる HTML のような構文を使用することもできます。これは上記と同等です。

jsx
<div class="foo" style="color: red">
  hello
</div>

Signature ​

vnode = m(selector, attrs, children)

ArgumentTypeRequiredDescription
selectorString|Object|FunctionYesCSS セレクターまたは コンポーネントです。
attrsObjectNoHTML 属性または要素プロパティ
childrenArray<Vnode>|String|Number|BooleanNo子 vnode。スプレッド引数として記述可能です。
returnsVnodevnode

署名の読み方

How it works ​

Mithril.js は、JavaScript 構文を使用して任意の HTML 構造を表現できる hyperscript 関数 m() を提供します。これは、selector 文字列 (必須)、attrs オブジェクト (オプション)、および children 配列 (オプション) を受け取ります。

javascript
m('div', { id: 'box' }, 'hello');

// renders to this HTML:
// <div id="box">hello</div>

m() 関数は、実際には DOM 要素を返しません。代わりに、作成される DOM 要素を表す JavaScript オブジェクトである 仮想 DOM ノード、すなわち vnode を返します。

javascript
// a vnode
var vnode = {
  tag: 'div',
  attrs: { id: 'box' },
  children: [
    /*...*/
  ],
};

vnode を実際の DOM 要素に変換するには、m.render() 関数を使用します。

javascript
m.render(document.body, m('br')); // puts a <br> in <body>

m.render() を複数回呼び出しても、DOM ツリーが毎回最初から再作成されるわけではありません。代わりに、各呼び出しは、呼び出しに渡された仮想 DOM ツリーを反映するために必要な場合にのみ、DOM ツリーに変更を加えます。DOM を最初から再作成するのは非常にコストがかかり、入力フォーカスの喪失などの問題が発生するため、この動作は推奨されます。対照的に、必要な場合にのみ DOM を更新する方がはるかに高速であり、複数のユーザーストーリーを処理する複雑な UI を維持しやすくなります。

Flexibility ​

m() 関数は、_ポリモーフィック_であり、_可変引数_です。つまり、入力パラメータとして期待されるものに非常に柔軟に対応できます。

javascript
// simple tag
m('div'); // <div></div>

// attributes and children are optional
m('a', { id: 'b' }); // <a id="b"></a>
m('span', 'hello'); // <span>hello</span>

// tag with child nodes
m('ul', [
  // <ul>
  m('li', 'hello'), //   <li>hello</li>
  m('li', 'world'), //   <li>world</li>
]); // </ul>

// array is optional
m(
  'ul', // <ul>
  m('li', 'hello'), //   <li>hello</li>
  m('li', 'world') //   <li>world</li>
); // </ul>

CSS selectors ​

m() の最初の引数には、HTML 要素を記述できる任意の CSS セレクターを指定できます。# (id)、. (class)、および [] (属性) 構文の有効な CSS の組み合わせを受け入れます。

javascript
m('div#hello');
// <div id="hello"></div>

m('section.container');
// <section class="container"></section>

m('input[type=text][placeholder=Name]');
// <input type="text" placeholder="Name" />

m("a#exit.external[href='https://example.com']", 'Leave');
// <a id="exit" class="external" href="https://example.com">Leave</a>

タグ名を省略すると、Mithril.js は div タグと見なします。

javascript
m('.box.box-bordered'); // <div class="box box-bordered"></div>

通常、静的属性(つまり、値が変化しない属性)には CSS セレクターを使用し、動的な属性値には属性オブジェクトを渡すことをお勧めします。

javascript
var currentURL = '/';

m(
  'a.link[href=/]',
  {
    class: currentURL === '/' ? 'selected' : '',
  },
  'Home'
);

// renders to this HTML:
// <a href="/" class="link selected">Home</a>

Attributes passed as the second argument ​

属性、プロパティ、イベント、およびライフサイクルフックは、2 番目のオプション引数として渡すことができます(詳細については、次のセクションを参照)。

JS
m("button", {
  class: "my-button",
  onclick: function() {/* ... */},
  oncreate: function() {/* ... */}
})

このような属性の値が null または undefined の場合、その属性は存在しないものとして扱われます。

m() の最初と 2 番目の引数の両方にクラス名がある場合、予想どおりにそれらがマージされます。2 番目の引数のクラスの値が null または undefined の場合、無視されます。

別の属性が最初と 2 番目の引数の両方に存在する場合、2 番目の引数が null または undefined であっても優先されます。

DOM attributes ​

Mithril.js は、JavaScript API と DOM API (setAttribute) の両方を使用して属性を解決します。つまり、両方の構文を使用して属性を参照できます。

例えば、JavaScript API では、readonly 属性は element.readOnly と呼ばれます(大文字表記に注意してください)。Mithril.js では、次のすべてがサポートされています。

javascript
m('input', { readonly: true }); // lowercase
m('input', { readOnly: true }); // uppercase
m('input[readonly]');
m('input[readOnly]');

これにはカスタム要素も含まれています。たとえば、Mithril.js 内で A-Frame を問題なく使用できます。

javascript
m('a-scene', [
  m('a-box', {
    position: '-1 0.5 -3',
    rotation: '0 45 0',
    color: '#4CC3D9',
  }),

  m('a-sphere', {
    position: '0 1.25 -5',
    radius: '1.25',
    color: '#EF2D5E',
  }),

  m('a-cylinder', {
    position: '1 0.75 -3',
    radius: '0.5',
    height: '1.5',
    color: '#FFC65D',
  }),

  m('a-plane', {
    position: '0 0 -4',
    rotation: '-90 0 0',
    width: '4',
    height: '4',
    color: '#7BC8A4',
  }),

  m('a-sky', {
    color: '#ECECEC',
  }),
]);

カスタム要素の場合、プロパティがオブジェクト、数値、またはその他の非文字列値である場合に備えて、プロパティを自動的に文字列化しません。したがって、elem.whitelist 配列の getter/setter プロパティを持つカスタム要素 my-special-element があると仮定すると、これを行うことができ、期待どおりに動作します。

javascript
m('my-special-element', {
  whitelist: [
    'https://example.com',
    'https://neverssl.com',
    'https://google.com',
  ],
});

これらの要素にクラスまたは ID がある場合、短縮形は期待どおりに機能します。別の A-Frame の例を挙げると:

javascript
// These two are equivalent
m('a-entity#player');
m('a-entity', { id: 'player' });

ライフサイクル属性、onevent ハンドラー、key、class、style などのマジックセマンティクスを持つすべてのプロパティは、通常の HTML 要素の場合と同じように扱われることに注意してください。

Style attribute ​

Mithril.js は、文字列とオブジェクトの両方を有効な style 値としてサポートしています。つまり、次のすべてがサポートされています。

javascript
m('div', { style: 'background:red;' });
m('div', { style: { background: 'red' } });
m('div[style=background:red]');

style に文字列を使用すると、値が変更された CSS ルールだけでなく、要素内のすべてのインラインスタイルが再描画時に上書きされます。

ハイフンで区切られた CSS プロパティ名 (例: background-color) と、キャメルケースの DOM style プロパティ名 (例: backgroundColor) の両方を使用できます。ブラウザがサポートしている場合は、CSS カスタムプロパティ を定義することもできます。

Mithril.js は、数値に単位を追加することはありません。単に文字列化するだけです。

Events ​

Mithril.js は、touchstart など、仕様で on${event} プロパティが定義されていないイベントを含む、すべての DOM イベントのイベントハンドラーバインディングをサポートしています。

javascript
function doSomething(e) {
  console.log(e);
}

m('div', { onclick: doSomething });

Mithril.js は、関数と EventListener オブジェクトを受け入れます。したがって、これも機能します。

javascript
var clickListener = {
  handleEvent: function (e) {
    console.log(e);
  },
};

m('div', { onclick: clickListener });

デフォルトでは、hyperscript でアタッチされたイベントが発生すると、イベントコールバックが返された後、Mithril.js の自動再描画がトリガーされます(m.render を直接使用するのではなく、m.mount または m.route を使用している場合)。e.redraw = false を設定することで、単一のイベントに対してのみ自動再描画を無効にできます。

javascript
m('div', {
  onclick: function (e) {
    // Prevent auto-redraw
    e.redraw = false;
  },
});

Properties ​

Mithril.js は、<select> の selectedIndex や value プロパティなど、プロパティを通じてアクセスできる DOM 機能をサポートしています。

javascript
m('select', { selectedIndex: 0 }, [
  m('option', 'Option A'),
  m('option', 'Option B'),
]);

Components ​

コンポーネントを使用すると、ロジックをユニットにカプセル化し、要素のように扱うことができます。これらは、大規模でスケーラブルなアプリケーションを作成するための基盤となります。

コンポーネントは、view メソッドを含む任意の JavaScript オブジェクトです。コンポーネントを使用するには、CSS セレクター文字列を渡す代わりに、コンポーネントを m() の最初の引数として渡します。以下の例に示すように、属性と子を定義して、コンポーネントに引数を渡すことができます。

javascript
// define a component
var Greeter = {
  view: function (vnode) {
    return m('div', vnode.attrs, ['Hello ', vnode.children]);
  },
};

// consume it
m(Greeter, { style: 'color:red;' }, 'world');

// renders to this HTML:
// <div style="color:red;">Hello world</div>

コンポーネントの詳細については、コンポーネントのページ を参照してください。

Lifecycle methods ​

Vnode とコンポーネントは、ライフサイクルメソッド(別名 hooks)を持つことができます。これらは、DOM 要素のライフサイクル中のさまざまな時点で呼び出されます。Mithril.js でサポートされているライフサイクルメソッドは、oninit、oncreate、onupdate、onbeforeremove、onremove、および onbeforeupdate です。

ライフサイクルメソッドは、DOM イベントハンドラーと同じ方法で定義されますが、Event オブジェクトの代わりに vnode を引数として受け取ります。

javascript
function initialize(vnode) {
  console.log(vnode);
}

m('div', { oninit: initialize });
HookDescription
oninit(vnode)vnode が実際の DOM 要素にレンダリングされる前に実行されます。
oncreate(vnode)vnode が DOM に追加された後に実行されます。
onupdate(vnode)DOM 要素がドキュメントにアタッチされている間、再描画が発生するたびに実行されます。
onbeforeremove(vnode)DOM 要素がドキュメントから削除される前に実行されます。Promise が返された場合、Mithril.js は Promise が完了した後にのみ DOM 要素をデタッチします。このメソッドは、親 DOM 要素からデタッチされた要素でのみトリガーされ、その子要素ではトリガーされません。
onremove(vnode)DOM 要素がドキュメントから削除される前に実行されます。onbeforeremove フックが定義されている場合、onremove は done が呼び出された後に呼び出されます。このメソッドは、親要素からデタッチされた要素と、そのすべての子要素でトリガーされます。
onbeforeupdate(vnode, old)onupdate の前に実行され、false を返すと、要素とそのすべての子要素の差分処理が防止されます。

ライフサイクルメソッドの詳細については、ライフサイクルメソッドのページ を参照してください。

Keys ​

リスト内の Vnode は、key と呼ばれる特別な属性を持つことができます。これは、vnode リストを生成するモデルデータが変更されたときに、DOM 要素の ID を管理するために使用できます。

通常、key は、データ配列内のオブジェクトの一意な識別子フィールドであるべきです。

javascript
var users = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Mary' },
];

function userInputs(users) {
  return users.map(function (u) {
    return m('input', { key: u.id }, u.name);
  });
}

m.render(document.body, userInputs(users));

キーを持つということは、users 配列がシャッフルされ、ビューが再レンダリングされた際に、入力が全く同じ順序でシャッフルされ、正しいフォーカスと DOM 状態が維持されることを意味します。

key の詳細については、key のページ を参照してください。

SVG and MathML ​

Mithril.js は SVG を完全にサポートしています。Xlink もサポートされていますが、Mithril.js の v1.0 より前のバージョンとは異なり、名前空間を明示的に定義する必要があります。

javascript
m('svg', [m("image[xlink:href='image.gif']")]);

MathML も完全にサポートされています。

Making templates dynamic ​

ネストされた vnode は単なるプレーンな JavaScript 式であるため、JavaScript の機能を使用してそれらを操作できます。

Dynamic text ​

javascript
var user = { name: 'John' };

m('.name', user.name); // <div class="name">John</div>

Loops ​

map などの Array メソッドを使用して、データのリストを反復処理します。

javascript
var users = [{ name: 'John' }, { name: 'Mary' }];

m(
  'ul',
  users.map(function (u) {
    // <ul>
    return m('li', u.name); //   <li>John</li>
    //   <li>Mary</li>
  })
); // </ul>

// ES6+:
// m("ul", users.map(u =>
//   m("li", u.name)
// ))

Conditionals ​

三項演算子を使用して、ビューにコンテンツを条件付きで設定します。

javascript
var isError = false;

m('div', isError ? 'An error occurred' : 'Saved'); // <div>Saved</div>

JavaScript 式内で if や for などの JavaScript ステートメントを使用することはできません。これらのステートメントを完全に使用しないようにし、代わりに上記の構成のみを使用して、テンプレートの構造を線形かつ宣言的に保つことをお勧めします。

Converting HTML ​

Mithril.js では、整形式 HTML は有効な JSX です。コピー&ペースト以外にほとんど手間はかかりません。

hyperscript を使用する場合は、コードを実行する前に HTML を hyperscript 構文に変換する必要があります。これを容易にするために、HTML-to-Mithril-template converter を使用できます。

Avoid Anti-patterns ​

Mithril.js は柔軟性がありますが、一部のコードパターンは推奨されません。

Avoid dynamic selectors ​

DOM 要素が異なれば属性も異なり、多くの場合、動作も異なります。セレクターを動的にすると、コンポーネントの実装の詳細がユニット外に漏洩する可能性があります。

javascript
// AVOID
var BadInput = {
  view: function (vnode) {
    return m('div', [m('label'), m(vnode.attrs.type||'input')]);
  },
};

セレクターを動的にする代わりに、有効な可能性を明示的にコーディングするか、可変部分をリファクタリングすることを推奨します。

javascript
// PREFER explicit code
var BetterInput = {
  view: function (vnode) {
    return m('div', [m('label', vnode.attrs.title), m('input')]);
  },
};
var BetterSelect = {
  view: function (vnode) {
    return m('div', [m('label', vnode.attrs.title), m('select')]);
  },
};

// PREFER refactor variability out
var BetterLabeledComponent = {
  view: function (vnode) {
    return m('div', [m('label', vnode.attrs.title), vnode.children]);
  },
};

Avoid creating vnodes outside views ​

再描画時に、前回のレンダリング時の vnode と厳密に等しい vnode が検出されると、スキップされ、そのコンテンツは更新されません。これはパフォーマンスの最適化の機会のように思えるかもしれませんが、そのノードツリーの動的な変更を防ぐため、避ける必要があります。これにより、再描画でトリガーに失敗するダウンストリームのライフサイクルメソッドなどの副作用が発生します。この意味で、Mithril.js vnode は不変です。新しい vnode は古い vnode と比較されます。vnode への変更は永続化されません。

コンポーネントのドキュメントには、このアンチパターンの詳細と例 が含まれています。

Pager
前のページAPI
次のページrender(element, vnodes)

MITライセンス の下で公開されています。

Copyright (c) 2024 Mithril Contributors

https://mithril.js.org/hyperscript.html

MITライセンス の下で公開されています。

Copyright (c) 2024 Mithril Contributors