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

Начало работы

Установка Mithril.js

Простое приложение

Ресурсы

JSX

ES6+ в старых браузерах

Анимации

Тестирование

Примеры

Интеграция со сторонними библиотеками

Обработка путей

Ключевые концепции

Виртуальные DOM-узлы

Компоненты

Методы жизненного цикла

Ключи

Автоматическая перерисовка

Разное

Сравнение фреймворков

Переход с v1.x

Переход с v0.2.x

API

Содержание страницы

Переход с v0.2.x ​

v1.x и v2.x в значительной степени совместимы с API v0.2.x, однако существуют некоторые несовместимые изменения. Переход на v2.x практически идентичен переходу на v1.x, поэтому приведённые ниже замечания в основном относятся к обеим версиям.

Если вы планируете миграцию, рассмотрите возможность использования инструмента mithril-codemods для автоматизации наиболее простых преобразований.

m.prop удалён ​

В v2.x m.prop() был заменён более мощной микробиблиотекой потоков, но он больше не входит в ядро Mithril.js. Информацию об использовании модуля Streams можно найти в документации.

v0.2.x ​

javascript
var m = require('mithril');

var num = m.prop(1);

v2.x ​

javascript
var m = require('mithril');
var prop = require('mithril/stream');

var num = prop(1);
var doubled = num.map(function (n) {
  return n * 2;
});

m.component удалён ​

В v0.2.x компоненты можно было создавать с помощью m(Component) или m.component(Component). В v2.x поддерживается только m(Component).

v0.2.x ​

javascript
// Эти записи эквивалентны
m.component(Component);
m(Component);

v2.x ​

javascript
m(Component);

m.withAttr удалён ​

В v0.2.x обработчики событий могли использовать oninput: m.withAttr("value", func) и аналогичные конструкции. В v2.x рекомендуется считывать значения непосредственно из свойства target объекта события. Это хорошо сочеталось с m.prop, но поскольку он был удалён в пользу внешнего решения, а в v1.x не наблюдалось широкого и идиоматичного использования потоков, m.withAttr потерял большую часть своей полезности.

v0.2.x ​

javascript
var value = m.prop('');

// В вашем представлении
m('input[type=text]', {
  value: value(),
  oninput: m.withAttr('value', value),
});

v2.x ​

javascript
var value = '';

// В вашем представлении
m('input[type=text]', {
  value: value,
  oninput: function (ev) {
    value = ev.target.value;
  },
});

m.version удалён ​

Этот метод редко использовался, и вы всегда можете добавить его самостоятельно. Для определения доступности тех или иных функций рекомендуется использовать обнаружение возможностей (feature detection). API v2.x спроектирован таким образом, чтобы это облегчить.

Функция config ​

В v0.2.x Mithril.js предоставлял один метод жизненного цикла, config. v2.x предоставляет гораздо более детальный контроль над жизненным циклом vnode-элементов.

v0.2.x ​

javascript
m('div', {
  config: function (element, isInitialized) {
    // Запускается при каждой перерисовке
    // isInitialized - это логическое значение, показывающее, был ли узел добавлен в DOM
  },
});

v2.x ​

Больше информации об этих новых методах доступно в lifecycle-methods.md.

javascript
m('div', {
  // Вызывается до создания DOM-узла
  oninit: function (vnode) {
    /*...*/
  },
  // Вызывается после создания DOM-узла
  oncreate: function (vnode) {
    /*...*/
  },
  // Вызывается перед обновлением узла, возвращает false для отмены обновления
  onbeforeupdate: function (vnode, old) {
    /*...*/
  },
  // Вызывается после обновления узла
  onupdate: function (vnode) {
    /*...*/
  },
  // Вызывается перед удалением узла, возвращает Promise, который разрешается, когда
  // узел готов к удалению из DOM
  onbeforeremove: function (vnode) {
    /*...*/
  },
  // Вызывается перед удалением узла, но после того, как onbeforeremove вызывает done()
  onremove: function (vnode) {
    /*...*/
  },
});

Если доступен, DOM-элемент vnode можно получить через vnode.dom.

Изменения в поведении перерисовки ​

Механизм рендеринга Mithril.js по-прежнему основан на полуавтоматических глобальных перерисовках, однако некоторые API и принципы работы были изменены:

Больше нет блокировок перерисовки ​

В v0.2.x Mithril.js допускал «блокировки перерисовки», которые временно предотвращали выполнение логики перерисовки: по умолчанию m.request блокировал цикл перерисовки во время выполнения и разблокировал его, когда все ожидающие запросы были завершены. Аналогичное поведение можно было вызвать вручную с помощью m.startComputation() и m.endComputation(). Эти API и связанное с ними поведение были удалены в v2.x без замены. Блокировка перерисовки может приводить к ошибкам в пользовательском интерфейсе, поскольку проблемы в одной части приложения не должны препятствовать обновлению других частей представления, отражающих изменения.

Отмена перерисовки из обработчиков событий ​

m.mount() и m.route() по-прежнему автоматически запускают перерисовку после выполнения обработчика DOM-события. Отмена этих перерисовок из ваших обработчиков событий теперь выполняется путём установки свойства redraw переданного объекта события в значение false.

v0.2.x ​

javascript
m('div', {
  onclick: function (e) {
    m.redraw.strategy('none');
  },
});

v2.x ​

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

Синхронная перерисовка изменена ​

В v0.2.x можно было принудительно выполнить немедленную перерисовку Mithril.js, передав значение true в функцию m.redraw(). В v2.x эта функциональность была разделена на два разных метода для большей ясности.

v0.2.x ​

javascript
m.redraw(true); // выполняет синхронную перерисовку немедленно

v2.x ​

javascript
m.redraw(); // планирует перерисовку на следующий кадр requestAnimationFrame
m.redraw.sync(); // немедленно вызывает перерисовку и ждет ее завершения

m.startComputation/m.endComputation удалены ​

Они считаются антипаттернами и имеют ряд проблемных крайних случаев, поэтому они были удалены без замены в v2.x.

Функция controller компонента ​

В v2.x свойство controller в компонентах упразднено. Вместо него следует использовать oninit.

v0.2.x ​

javascript
m.mount(document.body, {
  controller: function () {
    var ctrl = this;

    ctrl.fooga = 1;
  },

  view: function (ctrl) {
    return m('p', ctrl.fooga);
  },
});

v2.x ​

javascript
m.mount(document.body, {
  oninit: function (vnode) {
    vnode.state.fooga = 1;
  },

  view: function (vnode) {
    return m('p', vnode.state.fooga);
  },
});

// ИЛИ

m.mount(document.body, {
  // this привязан к vnode.state по умолчанию
  oninit: function (vnode) {
    this.fooga = 1;
  },

  view: function (vnode) {
    return m('p', this.fooga);
  },
});

Аргументы компонента ​

В v2.x аргументы компонента должны передаваться в виде объекта. Простые типы данных, такие как String, Number или Boolean, будут интерпретированы как текстовые дочерние элементы. Доступ к аргументам внутри компонента осуществляется путём их чтения из объекта vnode.attrs.

v0.2.x ​

javascript
var Component = {
  controller: function (options) {
    // options.fooga === 1
  },

  view: function (ctrl, options) {
    // options.fooga === 1
  },
};

m('div', m.component(Component, { fooga: 1 }));

v2.x ​

javascript
var Component = {
  oninit: function (vnode) {
    // vnode.attrs.fooga === 1
  },

  view: function (vnode) {
    // vnode.attrs.fooga === 1
  },
};

m('div', m(Component, { fooga: 1 }));

Дочерние элементы vnode компонента ​

В v0.2.x дочерние элементы vnode компонента не были нормализованы, а просто передавались в качестве дополнительных аргументов, и они также не были сглажены. Внутри это работало путём возврата частично применённого компонента, который сравнивался с предыдущим состоянием на основе факта частичного применения. В v2.x дочерние элементы vnode компонента передаются через vnode.children как разрешённый массив дочерних элементов, но, как и в v0.2.x, отдельные дочерние элементы не нормализуются, и массив дочерних элементов не выравнивается.

v0.2.x ​

javascript
var Component = {
  controller: function (value, renderProp) {
    // value === "value"
    // typeof renderProp === "function"
  },

  view: function (ctrl, value, renderProp) {
    // value === "value"
    // typeof renderProp === "function"
  },
};

m(
  'div',
  m.component(Component, 'value', function (key) {
    return 'child';
  })
);

v2.x ​

javascript
var Component = {
  oninit: function (vnode) {
    // vnode.children[0] === "value"
    // typeof vnode.children[1] === "function"
  },

  view: function (vnode) {
    // vnode.children[0] === "value"
    // typeof vnode.children[1] === "function"
  },
};

m(
  'div',
  m(Component, 'value', function (key) {
    return 'child';
  })
);

Дочерние элементы DOM vnode ​

В v0.2.x дочерние элементы DOM-узлов представлялись буквально, без какой-либо нормализации, за исключением использования дочерних элементов напрямую, если присутствует только один дочерний массив. Он возвращал структуру, больше похожую на эту, со строками, представленными буквально.

javascript
m("div", "value", ["nested"])

// Становится:
{
	tag: "div",
	attrs: {},
	children: [
		"value",
		["nested"],
	]
}

В v2.x дочерние элементы DOM vnode нормализуются в объекты с единообразной структурой.

javascript
m("div", "value", ["nested"])

// Становится примерно:
{
	tag: "div",
	attrs: null,
	children: [
		{tag: "#", children: "value"},
		{tag: "[", children: [
			{tag: "#", children: "nested"},
		]},
	]
}

Если в DOM vnode присутствует только один текстовый дочерний элемент, вместо этого он устанавливает для свойства text это значение.

javascript
m("div", "value")

// Становится примерно:
{
	tag: "div",
	attrs: null,
	text: "",
	children: undefined,
}

См. документацию по vnode для получения более подробной информации о структуре vnode v2.x и о том, как всё нормализуется.

Большинство свойств vnode v2.x здесь опущены для краткости.

Ключи ​

В v0.2.x вы могли свободно смешивать vnode с ключами и без них.

В v2.x списки дочерних элементов как фрагментов, так и элементов должны быть либо все с ключами, либо все без ключей. Пустые элементы также считаются элементами без ключа и теперь учитываются при проверке.

Если вам нужно обойти это ограничение, используйте шаблон фрагмента, содержащего один vnode, например [m("div", {key: whatever})].

Параметры view() ​

В v0.2.x функциям представления передавалась ссылка на экземпляр controller и (необязательно) любые параметры, переданные компоненту. В v2.x им передаётся только объект vnode, аналогично функции oninit.

v0.2.x ​

javascript
m.mount(document.body, {
  controller: function () {},

  view: function (ctrl, options) {
    // ...
  },
});

v2.x ​

javascript
m.mount(document.body, {
  oninit: function (vnode) {
    // ...
  },

  view: function (vnode) {
    // Используйте vnode.state вместо ctrl
    // Используйте vnode.attrs вместо options
  },
});

Передача компонентов в m() ​

В v0.2.x вы могли передавать компоненты в качестве второго аргумента m() без какой-либо необходимой обёртки. В v2.x для обеспечения единообразия компоненты всегда должны быть обёрнуты в вызов m().

v0.2.x ​

javascript
m('div', Component);

v2.x ​

javascript
m('div', m(Component));

Передача vnode в m.mount() и m.route() ​

В v0.2.x m.mount(element, component) разрешал передавать vnode в качестве второго аргумента вместо компонентов (даже если это не было задокументировано). Аналогично, m.route(element, defaultRoute, routes) принимал vnode в качестве значений в объекте routes.

В v2.x в обоих случаях ожидается передача именно компонентов.

v0.2.x ​

javascript
m.mount(element, m('i', 'hello'));
m.mount(element, m(Component, attrs));

m.route(element, '/', {
  '/': m('b', 'bye'),
});

v2.x ​

javascript
m.mount(element, {
  view: function () {
    return m('i', 'hello');
  },
});
m.mount(element, {
  view: function () {
    return m(Component, attrs);
  },
});

m.route(element, '/', {
  '/': {
    view: function () {
      return m('b', 'bye');
    },
  },
});

m.route.mode ​

В версии v1.x это заменено на m.route.prefix = prefix, где prefix — любой префикс. Если он начинается с #, используется хеш-режим, ? — режим поиска, а любой другой символ (или пустая строка) — режим пути. Поддерживаются и комбинации, например, m.route.prefix = "/path/#!" или ?#.

По умолчанию теперь используется префикс #! (hashbang) вместо просто #. Если вы использовали поведение по умолчанию и хотите сохранить существующие URL-адреса, укажите m.route.prefix = "#" перед инициализацией маршрутов.

v0.2.x ​

javascript
m.route.mode = 'hash';
m.route.mode = 'pathname';
m.route.mode = 'search';

v2.x ​

javascript
// Прямые соответствия
m.route.prefix = '#';
m.route.prefix = '';
m.route.prefix = '?';

m.route() и якорные теги ​

Обработка маршрутизируемых ссылок теперь использует специальный встроенный компонент вместо атрибута config. Если вы использовали config: m.route на <button> и подобных элементах, укажите имя этого тега, используя атрибут selector: "button".

v0.2.x ​

javascript
// При нажатии на эту ссылку будет загружен маршрут "/path" вместо перехода по ссылке
m('a', {
  href: '/path',
  config: m.route,
});

v2.x ​

javascript
// При нажатии на эту ссылку будет загружен маршрут "/path" вместо перехода по ссылке
m(m.route.Link, {
  href: '/path',
});

Шаблоны путей ​

В v1.x существовало три отдельных синтаксиса шаблонов путей, которые, хотя и были похожи, имели 2 отдельных разработанных синтаксиса и 3 разные реализации. Это было довольно произвольно, и параметры обычно не экранировались. Теперь все либо кодируется, если это :key, либо остается без изменений, если это :key.... Если что-то неожиданно кодируется, используйте :key.... Все просто.

Вот как это влияет на каждый метод:

URL-адреса m.request ​

Компоненты пути в v2.x экранируются автоматически при интерполяции и считывают свои значения из params. В v0.2.x m.request({url: "/user/:name/photos/:id", data: {name: "a/b", id: "c/d"}}) отправлял бы запрос с URL-адресом /user/a%2Fb/photos/c/d. В v2.x соответствующий m.request({url: "/user/:name/photos/:id", params: {name: "a/b", id: "c/d"}}) отправит запрос на /user/a%2Fb/photos/c%2Fd. Если вы намеренно хотите интерполировать ключ без экранирования, используйте :key....

Интерполяции во встроенных строках запроса, например, в /api/search?q=:query, не выполняются в v2.x. Передавайте их через params с соответствующими именами ключей вместо указания в строке запроса.

Обратите внимание, что это также относится к m.jsonp. При переходе с m.request + dataType: "jsonp" на m.jsonp вам также необходимо помнить об этом.

Пути m.route(route, params, shouldReplaceHistoryEntry) ​

Теперь они допускают интерполяции и работают идентично m.request.

Шаблоны маршрутов m.route ​

Ключи пути вида :key... возвращают URL-адрес, декодированный в v1.x, но возвращают необработанный URL-адрес в v2.x.

Ранее, такие конструкции, как :key.md, ошибочно принимались, при этом значение результирующего параметра устанавливалось в keymd: "...". Это больше не так - .md теперь является частью шаблона, а не имени параметра.

Чтение/запись текущего маршрута ​

В v0.2.x все взаимодействия с текущим маршрутом осуществлялись через m.route(). В v2.x это разделено на две функции.

v0.2.x ​

javascript
// Получение текущего маршрута
m.route();

// Установка нового маршрута
m.route('/other/route');

v2.x ​

javascript
// Получение текущего маршрута
m.route.get();

// Установка нового маршрута
m.route.set('/other/route');

Доступ к параметрам маршрута ​

В v0.2.x чтение параметров маршрута полностью осуществлялось через m.route.param(). Этот API по-прежнему доступен в v2.x, и, кроме того, любые параметры маршрута передаются в виде свойств в объекте attrs на виртуальном узле.

v0.2.x ​

javascript
m.route(document.body, '/booga', {
  '/:attr': {
    controller: function () {
      m.route.param('attr'); // "booga"
    },
    view: function () {
      m.route.param('attr'); // "booga"
    },
  },
});

v2.x ​

javascript
m.route(document.body, '/booga', {
  '/:attr': {
    oninit: function (vnode) {
      vnode.attrs.attr; // "booga"
      m.route.param('attr'); // "booga"
    },
    view: function (vnode) {
      vnode.attrs.attr; // "booga"
      m.route.param('attr'); // "booga"
    },
  },
});

Создание/Разбор строк запроса ​

v0.2.x использовал методы, связанные с m.route, m.route.buildQueryString() и m.route.parseQueryString(). В v2.x они разделены и перемещены в корень m.

v0.2.x ​

javascript
var qs = m.route.buildQueryString({ a: 1 });

var obj = m.route.parseQueryString('a=1');

v2.x ​

javascript
var qs = m.buildQueryString({ a: 1 });

var obj = m.parseQueryString('a=1');

Кроме того, в v2.x {key: undefined} сериализуется как key=undefined с помощью m.buildQueryString и методов, которые его используют, например, m.request. В v0.2.x ключ был опущен, и это перешло в m.request. Если вы ранее полагались на это, измените свой код, чтобы полностью опустить ключи из объекта. Если вам необходимо сохранить поведение v0.2.x, и вы не можете легко удалить ключи со значением undefined, используйте простую утилиту для удаления таких ключей из объекта.

javascript
// Вызывайте всякий раз, когда вам нужно опустить параметры `undefined` из объекта.
function omitUndefineds(object) {
  var result = {};

  for (var key in object) {
    if ({}.hasOwnProperty.call(object, key)) {
      var value = object[key];
      if (Array.isArray(value)) {
        result[key] = value.map(omitUndefineds);
      } else if (value != null && typeof value === 'object') {
        result[key] = omitUndefineds(value);
      } else if (value !== undefined) {
        result[key] = value;
      }
    }
  }

  return result;
}

Предотвращение размонтирования ​

Теперь невозможно предотвратить размонтирование с помощью e.preventDefault() в onunload. Вместо этого вы должны явно вызвать m.route.set, когда будут выполнены ожидаемые условия.

v0.2.x ​

javascript
var Component = {
  controller: function () {
    this.onunload = function (e) {
      if (condition) e.preventDefault();
    };
  },
  view: function () {
    return m('a[href=/]', { config: m.route });
  },
};

v2.x ​

javascript
var Component = {
  view: function () {
    return m('a', {
      onclick: function () {
        if (!condition) m.route.set('/');
      },
    });
  },
};

Запуск кода при удалении компонента ​

Компоненты больше не вызывают this.onunload, когда они удаляются. Теперь они используют стандартизированный хук жизненного цикла onremove.

v0.2.x ​

javascript
var Component = {
  controller: function () {
    this.onunload = function (e) {
      // ...
    };
  },
  view: function () {
    // ...
  },
};

v2.x ​

javascript
var Component = {
	onremove: function() {
		// ...
	}
	view: function() {
		// ...
	}
}

m.request ​

Промисы, возвращаемые m.request, больше не являются геттер-сеттерами m.prop. Кроме того, initialValue, unwrapSuccess и unwrapError больше не являются поддерживаемыми опциями.

Запросы больше не имеют семантики m.startComputation/m.endComputation. Вместо этого перерисовки всегда запускаются при завершении цепочки промисов запроса (если не установлено background: true).

Параметр data теперь разделен на params — параметры запроса, интерполированные в URL-адрес и добавленные к запросу, и body — тело для отправки в базовом XHR.

В v0.2.x вы использовали бы dataType: "jsonp" для инициирования JSONP-запроса. В v2.x теперь вы используете m.jsonp, который имеет в основном тот же API, что и m.request, без частей, связанных с XHR.

v0.2.x ​

javascript
var data = m.request({
  method: 'GET',
  url: 'https://api.github.com/',
  initialValue: [],
});

setTimeout(function () {
  console.log(data());
}, 1000);

m.request({
  method: 'POST',
  url: 'https://api.github.com/',
  data: someJson,
});

v2.x ​

javascript
var data = [];
m.request({
  method: 'GET',
  url: 'https://api.github.com/',
}).then(function (responseBody) {
  data = responseBody;
});

setTimeout(function () {
  console.log(data); // note: not a getter-setter
}, 1000);

m.request({
  method: 'POST',
  url: 'https://api.github.com/',
  body: someJson,
});

// ИЛИ

var data = [];
m.request('https://api.github.com/').then(function (responseBody) {
  data = responseBody;
});

setTimeout(function () {
  console.log(data); // note: not a getter-setter
}, 1000);

m.request('https://api.github.com/', {
  method: 'POST',
  body: someJson,
});

Кроме того, если опция extract передана в m.request, возвращаемое значение предоставленной функции будет использоваться непосредственно для разрешения промиса запроса, а обратный вызов deserialize игнорируется.

Заголовки m.request ​

В v0.2.x Mithril.js не устанавливал заголовков по умолчанию в запросах. Теперь он устанавливает до 2 заголовков:

  • Content-Type: application/json; charset=utf-8 для запросов с телами JSON, которые != null
  • Accept: application/json, text/* для запросов, ожидающих ответы JSON

Заголовок Content-Type вызовет предварительную выборку CORS, так как он не входит в список CORS-safelisted request header из-за указанного типа контента. Это может привести к новым ошибкам в зависимости от конфигурации CORS на вашем сервере. Если у вас возникнут проблемы с этим, вам может потребоваться переопределить этот заголовок, передав headers: {"Content-Type": "text/plain"}. (Заголовок Accept ничего не вызывает, поэтому вам не нужно его переопределять.)

Единственные типы контента, которые спецификация Fetch позволяет избежать проверок предварительной выборки CORS, — это application/x-www-form-urlencoded, multipart/form-data и text/plain. Он не разрешает ничего другого и намеренно запрещает JSON.

m.deferred удален ​

v0.2.x использовал свой собственный пользовательский объект асинхронного контракта, представленный как m.deferred, который использовался в качестве основы для m.request. В v2.x, вместо этого, следует использовать Promises. В ситуациях, где ранее использовался m.deferred, следует использовать Promises.

v0.2.x ​

javascript
var greetAsync = function () {
  var deferred = m.deferred();
  setTimeout(function () {
    deferred.resolve('hello');
  }, 1000);
  return deferred.promise;
};

greetAsync()
  .then(function (value) {
    return value + ' world';
  })
  .then(function (value) {
    console.log(value);
  }); //logs "hello world" after 1 second

v2.x ​

javascript
var greetAsync = function () {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve('hello');
    }, 1000);
  });
};

greetAsync()
  .then(function (value) {
    return value + ' world';
  })
  .then(function (value) {
    console.log(value);
  }); //logs "hello world" after 1 second

m.sync удален ​

В v2.x, благодаря использованию Promises, соответствующих стандартам, m.sync является избыточным. Используйте Promise.all вместо этого.

v0.2.x ​

javascript
m.sync([
  m.request({ method: 'GET', url: 'https://api.github.com/users/lhorie' }),
  m.request({
    method: 'GET',
    url: 'https://api.github.com/users/dead-claudia',
  }),
]).then(function (users) {
  console.log('Contributors:', users[0].name, 'and', users[1].name);
});

v2.x ​

javascript
Promise.all([
  m.request({ method: 'GET', url: 'https://api.github.com/users/lhorie' }),
  m.request({
    method: 'GET',
    url: 'https://api.github.com/users/dead-claudia',
  }),
]).then(function (users) {
  console.log('Contributors:', users[0].name, 'and', users[1].name);
});

Требуется пространство имен xlink ​

В v0.2.x пространство имен xlink было единственным поддерживаемым пространством имен атрибутов, и оно поддерживалось с помощью специального поведения. Теперь синтаксический анализ пространств имен полностью поддерживается, и атрибуты с пространством имен должны явно объявлять свое пространство имен.

v0.2.x ​

javascript
m(
  'svg',
  // the `href` attribute is namespaced automatically
  m("image[href='image.gif']")
);

v2.x ​

javascript
m(
  'svg',
  // Пространство имен, указанное пользователем для атрибута `href`
  m("image[xlink:href='image.gif']")
);

Вложенные массивы в представлениях ​

Теперь массивы представляют фрагменты, которые структурно значимы в виртуальном DOM v2.x. В то время как вложенные массивы в v0.2.x были бы сведены в один непрерывный список виртуальных узлов для целей дифференцирования, v2.x сохраняет структуру массива - дочерние элементы любого данного массива не считаются одноуровневыми с дочерними элементами смежных массивов.

Проверки равенства vnode ​

Если виртуальный узел строго равен виртуальному узлу, занимающему его место в последней отрисовке, v2.x пропустит эту часть дерева, не проверяя мутации и не запуская какие-либо методы жизненного цикла в поддереве. Документация компонента содержит более подробную информацию по этому вопросу.

Pager
Предыдущая страницаПереход с v1.x
Следующая страницаAPI

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors

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

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors