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

はじめに

インストール方法

シンプルなアプリケーション

リソース

JSX

レガシーブラウザでの ES6+ の利用

アニメーション

テスト

例

サードパーティとの統合

パスの取り扱い

主要な概念

Virtual DOM ノード

コンポーネント

ライフサイクルメソッド

Key(キー)

自動再描画システム

その他

フレームワークの比較

v1.x からの移行

v0.2.x からの移行

API

このページの内容

v1.x からの移行 ​

v2.x は、ほぼすべての API において v1.x と互換性がありますが、いくつかの非互換な変更点があります。

vnode.state への代入 ​

v1.x では、vnode.state を自由に操作し、任意の値を代入できました。v2.x では、vnode.state への直接的な代入はエラーとなります。移行方法はケースバイケースで異なりますが、多くの場合、vnode.state への参照を vnode.state.foo に変更し、foo に適切な名前(例えば、カウンターの現在の値であれば count など)を選択するだけで済みます。

v1.x ​

javascript
var Counter = {
  oninit: function (vnode) {
    vnode.state = 0;
  },
  view: function (vnode) {
    return m('.counter', [
      m(
        'button',
        {
          onclick: function () {
            vnode.state--;
          },
        },
        '-'
      ),
      vnode.state,
      m(
        'button',
        {
          onclick: function () {
            vnode.state++;
          },
        },
        '+'
      ),
    ]);
  },
};

v2.x ​

javascript
var Counter = {
  oninit: function (vnode) {
    vnode.state.count = 0;
  },
  view: function (vnode) {
    return m('.counter', [
      m(
        'button',
        {
          onclick: function () {
            vnode.state.count--;
          },
        },
        '-'
      ),
      vnode.state.count,
      m(
        'button',
        {
          onclick: function () {
            vnode.state.count++;
          },
        },
        '+'
      ),
    ]);
  },
};

v1.0 が最初にリリースされた当時、クラスコンポーネントとクロージャコンポーネントは存在しなかったため、必要な情報を vnode.tag から取得していました。この実装の詳細が、そのような操作を可能にし、一部の開発者はそれに依存するようになりました。また、ドキュメントの一部でも、それが可能であることが示唆されていました。現在、状況は異なり、状態への参照が 2 つではなく 1 つになるため、実装の観点から管理が容易になります。

ルートアンカーの変更 ​

v1.x では、oncreate: m.route.link を使用し、リンクが変更される可能性がある場合には onupdate: m.route.link も使用していました。これらはそれぞれ、ルーティング可能な vnode のライフサイクルフックとして機能していました。v2.x では、m.route.Link コンポーネントを使用するようになりました。m("a", ...) 以外を使用していた場合は、selector: 属性でセレクタを指定できます。オプションは options: で指定できます。disabled: で無効化できます。また、href: (必須) を含むその他の属性はインラインで指定できます。selector: 自体には、m の最初の引数として有効な任意のセレクタを含めることができ、属性 [href=...] および [disabled] は、通常のオプションと同様にセレクタで指定できます。

v1.x ​

javascript
m('a', {
  href: '/path',
  oncreate: m.route.link,
});

m('button', {
  href: '/path',
  oncreate: m.route.link,
});

m('button.btn[href=/path]', {
  oncreate: m.route.link,
});

v2.x ​

javascript
m(m.route.Link, {
  href: '/path',
});

m(m.route.Link, {
  selector: 'button',
  href: '/path',
});

m(m.route.Link, {
  selector: 'button.btn[href=/path]',
});

m.request エラーの変更 ​

v1.x では、m.request は JSON 呼び出しからエラーを解析し、その結果として得られた解析済みのオブジェクトのプロパティをレスポンスに割り当てていました。したがって、ステータス 403 で本文が {"code": "backoff", "timeout": 1000} のレスポンスを受信した場合、エラーには err.code = "backoff" と err.timeout = 1000 という 2 つのプロパティが追加されていました。

v2.x では、レスポンスは代わりに結果の response プロパティに割り当てられ、code プロパティには結果のステータスコードが含まれます。したがって、ステータス 403 で {"code": "backoff", "timeout": 1000} の本文を含むレスポンスを受信した場合、エラーには err.response = {code: "backoff", timeout: 1000} と err.code = 403 の 2 つのプロパティが割り当てられます。

m.withAttr の削除 ​

v1.x では、イベントリスナーは oninput: m.withAttr("value", func) のように使用できました。v2.x では、イベントのターゲットから直接値を読み取るだけです。これはストリームとうまく連携しましたが、m.withAttr("value", stream) のイディオムは m.withAttr("value", prop) ほど一般的ではなかったため、m.withAttr はその有用性を大きく損ない、削除されることになりました。

v1.x ​

javascript
var value = '';

// In your view
m('input[type=text]', {
  value: value(),
  oninput: m.withAttr('value', function (v) {
    value = v;
  }),
});

// OR

var value = m.stream('');

// In your view
m('input[type=text]', {
  value: value(),
  oninput: m.withAttr('value', value),
});

v2.x ​

javascript
var value = '';

// In your view
m('input[type=text]', {
  value: value,
  oninput: function (ev) {
    value = ev.target.value;
  },
});

// OR

var value = m.stream('');

// In your view
m('input[type=text]', {
  value: value(),
  oninput: function (ev) {
    value(ev.target.value);
  },
});

m.route.prefix ​

v1.x では、m.route.prefix は m.route.prefix(prefix) を介して呼び出される関数でした。現在は、m.route.prefix = prefix を介して設定するプロパティです。

v1.x ​

javascript
m.route.prefix('/root');

v2.x ​

javascript
m.route.prefix = '/root';

m.request/m.jsonp の params と body ​

data と useBody は、URL に補間され、リクエストに追加されるクエリパラメータである params と、基になる XHR で送信される本文である body にリファクタリングされました。これにより、送信される実際のリクエストをより詳細に制御できるようになり、POST リクエストでクエリパラメータを補間したり、本文付きの GET リクエストを作成したりすることが可能になります。

m.jsonp には意味のある「body」がないため、params のみを使用します。したがって、data を params に名前変更するだけで、そのメソッドには十分です。

v1.x ​

javascript
m.request('https://example.com/api/user/:id', {
  method: 'GET',
  data: { id: user.id },
});

m.request('https://example.com/api/user/create', {
  method: 'POST',
  data: userData,
});

v2.x ​

javascript
m.request('https://example.com/api/user/:id', {
  method: 'GET',
  params: { id: user.id },
});

m.request('https://example.com/api/user/create', {
  method: 'POST',
  body: userData,
});

パステンプレート ​

v1.x では、3 つの別々のパステンプレート構文がありましたが、それらは似ていたものの、2 つの別々に設計された構文と 3 つの異なる実装がありました。これはかなりアドホックな方法で定義されており、パラメータは一般的にエスケープされていませんでした。現在、すべてが :key の場合はエンコードされ、:key... の場合は raw になります。予期せぬエンコードが発生する場合は、:path... を使用してください。非常にシンプルです。

具体的には、各メソッドにどのように影響するかを次に示します。

m.request と m.jsonp の URL、m.route.set のパス ​

v2.x のパスコンポーネントは、補間時に自動的にエスケープされます。m.route.set("/user/:name/photos/:id", {name: user.name, id: user.id}) を呼び出すとします。以前は、user が {name: "a/b", id: "c/d"} の場合、これはルートを /user/a/b/photos/c/d に設定していましたが、現在は /user/a%2Fb/photos/c%2Fd に設定します。キーをエスケープせずに意図的に補間する場合は、代わりに :key... を使用します。

v2.x のキーには、. または - のインスタンスを含めることはできません。v1.x では、/ 以外のものを含めることができました。

/api/search?q=:query のようなインラインクエリ文字列の補間は、v2.x では実行されません。代わりに、適切なキー名を使用して params を介して渡してください。クエリ文字列で直接指定するのではなく。

m.route のルートパターン ​

:key... 形式のパスキーは、v1.x では URL デコードされたものを返していましたが、v2.x では raw URL を返します。

以前は、:key.md のようなものが誤って受け入れられ、結果のパラメータの値が keymd: "..." に設定されていました。これは当てはまらなくなったため、.md は名前ではなく、パターンの一部として扱われます。

ライフサイクルフックの呼び出し順序 ​

v1.x では、コンポーネント vnode の属性ライフサイクルフックは、すべての場合においてコンポーネント自身のライフサイクルフックの前に呼び出されていました。v2.x では、これは onbeforeupdate の場合にのみ当てはまります。したがって、必要に応じてコードを調整してください。

v1.x ​

javascript
var Comp = {
  oncreate: function () {
    console.log('Component oncreate');
  },
  view: function () {
    return m('div');
  },
};

m.mount(document.body, {
  view: function () {
    return m(Comp, {
      oncreate: function () {
        console.log('Attrs oncreate');
      },
    });
  },
});

// ログ:
// Attrs oncreate
// Component oncreate

v2.x ​

javascript
var Comp = {
  oncreate: function () {
    console.log('Component oncreate');
  },
  view: function () {
    return m('div');
  },
};

m.mount(document.body, {
  view: function () {
    return m(Comp, {
      oncreate: function () {
        console.log('Attrs oncreate');
      },
    });
  },
});

// ログ:
// Component oncreate
// Attrs oncreate

m.redraw の同期性 ​

v2.x の m.redraw() は常に非同期的に動作します。現在リドローが実行中でない場合に限り、m.redraw.sync() を使用して同期的な再描画を明示的に要求できます。

セレクター属性の優先順位 ​

v1.x では、セレクター属性は属性オブジェクトで指定された属性よりも優先されていました。たとえば、m("[a=b]", {a: "c"}).attrs は {a: "b"} を返しました。

v2.x では、属性オブジェクトで指定された属性が、セレクター属性よりも優先されます。たとえば、m("[a=b]", {a: "c"}).attrs は {a: "c"} を返します。

技術的には、これは v0.2.x の動作に戻ったことに注意してください。

子の正規化 ​

v1.x では、コンポーネント vnode の子は、他の vnode と同様に正規化されていました。v2.x では、これはもう当てはまらないため、それに応じて計画する必要があります。これは、レンダリング時に行われる正規化には影響しません。

m.request ヘッダー ​

v1.x では、これらの 2 つのヘッダーをすべての非 GET リクエストに設定していましたが、useBody が true (デフォルト) に設定され、リストされている他の条件が満たされている場合にのみ設定されていました。

  • JSON 本文を含むリクエストの場合は Content-Type: application/json; charset=utf-8
  • JSON レスポンスを期待するリクエストの場合は Accept: application/json, text/*

v2.x では、Mithril.js は、JSON 本文を含むすべてのリクエストに対して最初のヘッダーを設定します。これは != null の場合に適用され、それ以外の場合はデフォルトで省略されます。また、これは、GET リクエストを含む、どのメソッドが選択されているかに関係なく行われます。

2 つのヘッダーのうち最初のヘッダーである Content-Type は、指定されたコンテンツタイプが CORS セーフリストリクエストヘッダーではないため、CORS プリフライトリクエストをトリガーし、サーバーで CORS がどのように構成されているかに応じて、新しいエラーが発生する可能性があります。この問題が発生した場合は、headers: {"Content-Type": "text/plain"} を指定して、該当するヘッダーを上書きする必要が生じる可能性があります。(Accept ヘッダーは何もトリガーしないため、上書きする必要はありません。)

Fetch 仕様で CORS プリフライトチェックを回避できるコンテンツタイプは、application/x-www-form-urlencoded、multipart/form-data、および text/plain のみです。それ以外は許可されておらず、意図的に JSON を許可していません。

ルートのハッシュ文字列のクエリパラメータ ​

v1.x では、クエリ文字列とハッシュ文字列の両方でルートのクエリパラメータを指定できました。したがって、m.route.set("/route?foo=1&bar=2")、m.route.set("/route?foo=1#bar=2")、および m.route.set("/route#foo=1&bar=2") はすべて同等であり、それらから抽出された属性は {foo: "1", bar: "2"} になっていました。

v2.x では、ハッシュ文字列の内容は無視されますが、保持されるようになりました。したがって、それぞれから抽出された属性は次のようになります。

  • m.route.set("/route?foo=1&bar=2") → {foo: "1", bar: "2"}
  • m.route.set("/route?foo=1#bar=2") → {foo: "1"}
  • m.route.set("/route#foo=1&bar=2") → {}

これを行う理由は、https://example.com/#!/route#key のような URL が、URL 仕様 では技術的に無効であり、それに先行する RFC でも無効であったためです。そして、HTML 仕様の癖によってのみ許可されています。(HTML 仕様は、仕様に従う場合は、最初から ID とロケーションフラグメントが有効な URL フラグメントである必要がありました。)

つまり、無効な URL の使用はやめましょう!

key ​

v1.x では、key 付きの vnode と key なしの vnode を自由に混在させることができました。最初のノードに key がある場合、key 付きの差分が実行され、すべての要素に key があると想定し、穴を無視するだけでした。それ以外の場合は、反復的な差分が実行され、ノードに key がある場合、タグなどがチェックされるのと同時に変更されていないことが確認されていました。

v2.x では、フラグメントと要素の両方の子リストは、すべて key 付きであるか、すべて key なしである必要があります。穴も、このチェックの目的では key なしと見なされます - 無視されなくなりました。

この問題を回避するには、[m("div", {key: whatever})] のように、単一の vnode を含むフラグメントというイディオムを使用してください。

m.version の削除 ​

一般的にはほとんど役に立たず、いつでも自分で追加することができます。利用可能な機能を把握するには、機能検出を優先する必要があります。また、v2.x API は、これをより適切に実現するように設計されています。

Pager
前のページフレームワークの比較
次のページv0.2.x からの移行

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

Copyright (c) 2024 Mithril Contributors

https://mithril.js.org/migration-v1x.html

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

Copyright (c) 2024 Mithril Contributors