Skip to content
Mithril.js 2
Main Navigation GuidaAPI

Italiano

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

Italiano

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

Aspetto

Sidebar Navigation

Per iniziare

Installazione di Mithril.js

Applicazione semplice

Risorse

JSX

ES6+ su browser legacy

Animazioni

Testing

Esempi

Integrazione di terze parti

Gestione dei Percorsi

Concetti chiave

Nodi del DOM virtuale

Componenti

Metodi del Ciclo di Vita

Chiavi

Il sistema di aggiornamento automatico

Varie

Confronto tra i Framework

Migrazione da v1.x

Migrazione da v0.2.x

API

In questa pagina

Migrazione da v0.2.x ​

Le versioni v1.x e v2.x sono ampiamente compatibili a livello di API con la v0.2.x, ma ci sono alcune modifiche che causano incompatibilità. La migrazione alla v2.x è quasi identica, quindi le note seguenti si applicano principalmente a entrambe.

Se stai eseguendo la migrazione, considera l'utilizzo dello strumento mithril-codemods per automatizzare le migrazioni più semplici.

m.prop rimosso ​

Nella v2.x, m.prop() è stato trasformato in una più potente micro-libreria di stream, ma è stato rimosso dal core. Puoi leggere come utilizzare il modulo Streams opzionale nella documentazione.

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 rimosso ​

Nella v0.2.x i componenti potevano essere creati usando sia m(Component) che m.component(Component). La v2.x supporta solo m(Component).

v0.2.x ​

javascript
// Questi sono equivalenti
m.component(Component);
m(Component);

v2.x ​

javascript
m(Component);

m.withAttr rimosso ​

Nella v0.2.x i listener di eventi potevano usare oninput: m.withAttr("value", func) e simili. Nella v2.x, leggi i valori direttamente dal target dell'evento. Funzionava bene con m.prop, ma, essendo quest'ultimo stato rimosso a favore di una soluzione esterna al core e non avendo la v1.x visto un utilizzo idiomatico e diffuso degli stream, m.withAttr ha perso gran parte della sua utilità.

v0.2.x ​

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

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

v2.x ​

javascript
var value = '';

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

m.version rimosso ​

Era poco utile in generale e puoi sempre aggiungerlo di nuovo tu stesso. È preferibile utilizzare il feature detection per sapere quali funzionalità sono disponibili e l'API v2.x è progettata per consentirlo meglio.

Funzione config ​

Nella v0.2.x Mithril.js forniva un singolo metodo del ciclo di vita, config. La v2.x offre un controllo più granulare sul ciclo di vita di un vnode (nodo virtuale).

v0.2.x ​

javascript
m('div', {
  config: function (element, isInitialized) {
    // viene eseguito ad ogni ridisegno
    // isInitialized è un booleano che indica se il nodo è stato aggiunto al DOM
  },
});

v2.x ​

Ulteriori informazioni su questi nuovi metodi sono disponibili in lifecycle-methods.md.

javascript
m('div', {
  // Chiamato prima che il nodo DOM venga creato
  oninit: function (vnode) {
    /*...*/
  },
  // Chiamato dopo che il nodo DOM è stato creato
  oncreate: function (vnode) {
    /*...*/
  },
  // Chiamato prima che il nodo venga aggiornato, restituisce false per annullare
  onbeforeupdate: function (vnode, old) {
    /*...*/
  },
  // Chiamato dopo che il nodo è stato aggiornato
  onupdate: function (vnode) {
    /*...*/
  },
  // Chiamato prima che il nodo venga rimosso, restituisce una Promise che si risolve quando
  // è pronto per la rimozione del nodo dal DOM
  onbeforeremove: function (vnode) {
    /*...*/
  },
  // Chiamato prima che il nodo venga rimosso, ma dopo che onbeforeremove chiama done()
  onremove: function (vnode) {
    /*...*/
  },
});

Se disponibile, è possibile accedere all'elemento DOM del vnode in vnode.dom.

Modifiche nel comportamento di ridisegno ​

Il motore di rendering di Mithril.js funziona ancora sulla base di ridisegni globali semi-automatici, ma alcune API e comportamenti differiscono:

Niente più blocchi di ridisegno ​

Nella v0.2.x, Mithril.js consentiva "blocchi di ridisegno" che impedivano temporaneamente l'esecuzione della logica di disegno: per impostazione predefinita, m.request bloccava il ciclo di disegno all'esecuzione e sbloccava quando tutte le richieste in sospeso erano state risolte - lo stesso comportamento poteva essere invocato manualmente usando m.startComputation() e m.endComputation(). Queste API e il comportamento associato sono stati rimossi nella v2.x senza sostituzione. Bloccare il ridisegno può causare UI difettose: non si dovrebbe permettere che i problemi di una parte dell'applicazione impediscano ad altre parti della view di aggiornarsi e riflettere i cambiamenti.

Annullamento del ridisegno dai gestori di eventi ​

m.mount() e m.route() ridisegnano ancora automaticamente dopo l'esecuzione di un gestore di eventi DOM. Per annullare questi ridisegni all'interno dei gestori di eventi, ora è necessario impostare la proprietà redraw dell'oggetto evento passato a 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;
  },
});

Ridisegno sincrono modificato ​

Nella v0.2.x era possibile forzare Mithril.js a ridisegnare immediatamente passando un valore truthy a m.redraw(). Nella v2.x, per maggiore chiarezza, questa funzionalità è stata suddivisa in due metodi distinti.

v0.2.x ​

javascript
m.redraw(true); // ridisegna immediatamente e in modo sincrono

v2.x ​

javascript
m.redraw(); // pianifica un ridisegno al successivo tick di requestAnimationFrame
m.redraw.sync(); // invoca un ridisegno immediatamente e attende che venga completato

m.startComputation/m.endComputation rimosso ​

Sono considerati anti-pattern e presentano diversi casi problematici, quindi sono stati rimossi senza sostituzione nella v2.x.

Funzione controller del componente ​

Nella v2.x, non c'è più la proprietà controller nei componenti - usa invece 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);
  },
});

// OPPURE

m.mount(document.body, {
  // `this` è legato a vnode.state per impostazione predefinita
  oninit: function (vnode) {
    this.fooga = 1;
  },

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

Argomenti del componente ​

Nella v2.x, gli argomenti di un componente devono essere un oggetto; i valori semplici come String/Number/Boolean saranno considerati figli di tipo testo. Si accede agli argomenti all'interno del componente leggendoli dall'oggetto 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 }));

Elementi figli vnode del componente ​

Nella v2.x, gli elementi figli vnode del componente sono passati tramite vnode.children come un array risolto di elementi figli; tuttavia, come nella v0.2.x, i singoli elementi figli non sono normalizzati, né l'array di elementi figli è appiattito.

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';
  })
);

Elementi figli vnode DOM ​

Nella v0.2.x, gli elementi figli dei nodi DOM erano rappresentati letteralmente senza alcuna normalizzazione, a parte l'utilizzo diretto degli elementi figli se è presente un solo elemento figlio array. Restituiva una struttura simile a questa.

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

// Diventa:
{
	tag: "div",
	attrs: {},
	children: [
		"value",
		["nested"],
	]
}

Nella v2.x, gli elementi figli dei vnode DOM sono normalizzati in oggetti con una struttura coerente.

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

// Diventa approssimativamente:
{
	tag: "div",
	attrs: null,
	children: [
		{tag: "#", children: "value"},
		{tag: "[", children: [
			{tag: "#", children: "nested"},
		]},
	]
}

Se è presente un solo elemento figlio testuale su un vnode DOM, imposta invece text su quel valore.

javascript
m("div", "value")

// Diventa approssimativamente:
{
	tag: "div",
	attrs: null,
	text: "",
	children: undefined,
}

Vedi la documentazione sui vnode per maggiori dettagli sulla struttura vnode v2.x e su come le cose sono normalizzate.

La maggior parte delle proprietà vnode v2.x qui sono omesse per brevità.

Key ​

Nella v0.2.x, potevi mescolare liberamente vnode con key e senza key.

Nella v2.x, gli elenchi di elementi figli, sia di frammenti che di elementi, devono essere omogenei: tutti con key o tutti senza key. Anche i "buchi" (undefined/null) sono considerati senza key ai fini di questo controllo: non vengono più ignorati.

Se hai bisogno di una soluzione alternativa, usa l'idioma di un frammento contenente un singolo vnode, come [m("div", {key: whatever})].

Parametri view() ​

Nella v0.2.x alle funzioni view viene passato un riferimento all'istanza controller e (facoltativamente) qualsiasi opzione passata al componente. Nella v2.x viene passato esclusivamente il vnode, proprio come accade per la funzione controller.

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) {
    // Usa vnode.state invece di ctrl
    // Usa vnode.attrs invece di options
  },
});

Passaggio di componenti a m() ​

Nella v0.2.x potevi passare i componenti come secondo argomento di m() senza alcun wrapping richiesto. Per garantire coerenza nella v2.x, devono sempre essere inclusi in una chiamata a m().

v0.2.x ​

javascript
m('div', Component);

v2.x ​

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

Passaggio di vnode a m.mount() e m.route() ​

Nella v0.2.x, m.mount(element, component) tollerava vnode come secondi argomenti invece di componenti (anche se non era documentato). Allo stesso modo, m.route(element, defaultRoute, routes) accettava vnode come valori nell'oggetto routes.

Nella v2.x, in entrambi i casi sono richiesti componenti.

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 ​

Nella v0.2.x, la modalità di routing si impostava assegnando una stringa tra "pathname", "hash" o "search" a m.route.mode. Nella v1.x è stata sostituita con m.route.prefix = prefix, dove prefix può essere un qualsiasi prefisso. Se inizia con #, funziona in modalità "hash", ? per la modalità "search" e qualsiasi altro carattere (o la stringa vuota) per la modalità "pathname". Supporta anche combinazioni delle precedenti come m.route.prefix = "/path/#!" o ?#.

L'impostazione predefinita è stata modificata per utilizzare un prefisso #! (hashbang) invece di solo #. Pertanto, se stavi utilizzando il comportamento predefinito e desideri conservare gli URL esistenti, specifica m.route.prefix = "#" prima di inizializzare le route.

v0.2.x ​

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

v2.x ​

javascript
// Equivalenti diretti
m.route.prefix = '#';
m.route.prefix = '';
m.route.prefix = '?';

m.route() e tag di ancoraggio ​

Ora, per la gestione dei link con routing, si utilizza un componente speciale integrato, invece di un attributo. Se lo stavi usando su elementi come <button>, puoi specificare il nome del tag usando l'attributo selector: "button".

v0.2.x ​

javascript
// Cliccando su questo link, verrà caricata la route "/path" invece di navigare
m('a', {
  href: '/path',
  config: m.route,
});

v2.x ​

javascript
// Cliccando su questo link, verrà caricata la route "/path" invece di navigare
m(m.route.Link, {
  href: '/path',
});

Template di percorso ​

Nella v1.x, esistevano tre sintassi separate per i template di percorso che, pur essendo simili, avevano due sintassi progettate separatamente e tre implementazioni diverse. Era definita in modo ad hoc e i parametri non venivano generalmente escaped. Ora, tutto viene codificato se è :key, raw se è :key.... Se le cose vengono codificate in modo imprevisto, usa :key.... È molto semplice.

Ecco come influisce su ciascun metodo:

URL di m.request ​

Nella v2.x, i componenti del percorso vengono escaped automaticamente quando vengono interpolati e leggono i loro valori da params. Nella v0.2.x, m.request({url: "/user/:name/photos/:id", data: {name: "a/b", id: "c/d"}}) invierebbe la sua richiesta con l'URL impostato su /user/a%2Fb/photos/c/d. Nella v2.x, il corrispondente m.request({url: "/user/:name/photos/:id", params: {name: "a/b", id: "c/d"}}) invierebbe la sua richiesta a /user/a%2Fb/photos/c%2Fd. Se si desidera deliberatamente interpolare una key senza escape, utilizzare invece :key....

Le interpolazioni nelle query string inline, come in /api/search?q=:query, non vengono eseguite nella v2.x. Passa invece quelle tramite params con i nomi delle key appropriati, senza specificarlo nella query string.

Nota che questo vale anche per m.jsonp. Quando si esegue la migrazione da m.request + dataType: "jsonp" a m.jsonp, è necessario tenerne conto.

Percorsi di m.route(route, params, shouldReplaceHistoryEntry) ​

Questi ora consentono le interpolazioni e funzionano in modo identico a quello di m.request.

Pattern di route di m.route ​

Nella v1.x, le key del percorso nella forma :key... restituiscono il loro URL decodificato, mentre nella v2.x restituiscono l'URL raw.

In precedenza, elementi come :key.md venivano erroneamente accettati, con il valore del parametro risultante impostato su keymd: "...". Questo non è più il caso: .md ora fa parte del pattern, non del nome.

Lettura/scrittura della route corrente ​

Nella v0.2.x, tutte le interazioni con la route corrente avvenivano tramite m.route(). Nella v2.x questo è stato suddiviso in due funzioni.

v0.2.x ​

javascript
// Ottenere la route corrente
m.route();

// Impostare una nuova route
m.route('/other/route');

v2.x ​

javascript
// Ottenere la route corrente
m.route.get();

// Impostare una nuova route
m.route.set('/other/route');

Accesso ai parametri della route ​

Nella v0.2.x, la lettura dei parametri della route era gestita completamente tramite m.route.param(). Questa API è ancora disponibile nella v2.x e, inoltre, tutti i parametri della route vengono passati come proprietà nell'oggetto attrs sul vnode (nodo virtuale).

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"
    },
  },
});

Costruzione/parsing di query string ​

La v0.2.x utilizzava metodi associati a m.route, m.route.buildQueryString() e m.route.parseQueryString(). Nella v2.x questi sono stati separati e spostati alla root 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');

Inoltre, nella v2.x, {key: undefined} viene serializzato come key=undefined da m.buildQueryString e dai metodi che lo utilizzano come m.request. Nella v0.2.x, la key veniva omessa e questo è stato riportato a m.request. Se in precedenza ti affidavi a questo, modifica il tuo codice per omettere completamente le key dall'oggetto. Potresti utilizzare una semplice utility per rimuovere tutte le key da un oggetto i cui valori sono undefined, qualora non fosse possibile farlo facilmente e si volesse conservare il comportamento della v0.2.x.

javascript
// Usala quando devi omettere i parametri `undefined` da un oggetto.
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;
}

Prevenzione dello smontaggio ​

Non è più possibile impedire lo smontaggio tramite e.preventDefault() all'interno di onunload. Invece, dovresti chiamare esplicitamente m.route.set quando vengono soddisfatte le condizioni previste.

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('/');
      },
    });
  },
};

Esecuzione di codice alla rimozione del componente ​

Quando vengono rimossi, i componenti non chiamano più this.onunload. Ora utilizzano l'hook del ciclo di vita standardizzato 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 ​

Le Promise restituite da m.request non sono più getter-setter m.prop. Inoltre, initialValue, unwrapSuccess e unwrapError non sono più opzioni supportate.

Inoltre, le richieste non hanno più la semantica m.startComputation/m.endComputation. Invece, i redraw vengono sempre attivati quando una catena di Promise di richiesta viene completata (a meno che non sia impostato background: true).

Il parametro data è stato ora suddiviso in params, parametri di query interpolati nell'URL e aggiunti alla richiesta, e body (corpo), il body da inviare nell'XHR sottostante.

Nella v0.2.x, useresti dataType: "jsonp" per avviare una richiesta JSONP. Nella v2.x, ora usi m.jsonp, che ha sostanzialmente la stessa API di m.request senza le parti relative a 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,
});

// OR

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,
});

Inoltre, se l'opzione extract viene passata a m.request, il valore di ritorno della funzione fornita verrà utilizzato direttamente per risolvere la Promise di richiesta e la callback deserialize viene ignorata.

Header di m.request ​

Nella v0.2.x, Mithril.js non impostava alcuna intestazione sulle richieste per impostazione predefinita. Ora, imposta fino a 2 header:

  • Content-Type: application/json; charset=utf-8 per le richieste con body JSON che sono != null
  • Accept: application/json, text/* per le richieste che si aspettano risposte JSON

Il primo dei due header, Content-Type, attiverà un prefetch CORS in quanto non è un header di richiesta CORS-safelisted a causa del tipo di contenuto specificato; ciò potrebbe introdurre nuovi errori a seconda di come è configurato CORS sul server. Se riscontri problemi con questo, potrebbe essere necessario sovrascrivere l'header in questione passando headers: {"Content-Type": "text/plain"}. (L'header Accept non attiva nulla, quindi non è necessario sovrascriverlo.)

Gli unici tipi di contenuto che la specifica Fetch consente di evitare i controlli di prefetch CORS sono application/x-www-form-urlencoded, multipart/form-data e text/plain. Non consente nient'altro e vieta intenzionalmente JSON.

m.deferred rimosso ​

La v0.2.x utilizzava il proprio oggetto di contratto asincrono personalizzato, esposto come m.deferred, che veniva utilizzato come base per m.request. La v2.x utilizza invece le Promise e implementa un polyfill in ambienti non supportati. Nei casi in cui usavi m.deferred, dovresti invece utilizzare le Promise.

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 rimosso ​

Poiché la v2.x utilizza Promise conformi agli standard, m.sync è ridondante. Usa invece 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);
});

Namespace xlink richiesto ​

Nella v0.2.x, il namespace xlink era l'unico namespace di attributo supportato ed era supportato tramite un comportamento di special casing. Ora il parsing del namespace è completamente supportato e gli attributi con namespace devono dichiarare esplicitamente il proprio namespace.

v0.2.x ​

javascript
m(
  'svg',
  // l'attributo `href` è namespaced automaticamente
  m("image[href='image.gif']")
);

v2.x ​

javascript
m(
  'svg',
  // Namespace specificato dall'utente sull'attributo `href`
  m("image[xlink:href='image.gif']")
);

Array nidificati nelle view ​

Ora, gli array rappresentano frammenti, che sono strutturalmente significativi nel DOM virtuale della v2.x. Mentre gli array nidificati nella v0.2.x verrebbero appiattiti in un unico elenco continuo di nodi virtuali ai fini del diffing, la v2.x preserva la struttura dell'array: i figli di un dato array non sono considerati fratelli di quelli di array adiacenti.

Controlli di uguaglianza vnode ​

Se un vnode è strettamente uguale al vnode che occupa il suo posto nell'ultimo draw (rendering), la v2.x salterà quella parte dell'albero senza verificare la presenza di mutazioni o attivare alcun metodo del ciclo di vita nel sottoalbero. La documentazione del componente contiene maggiori dettagli su questo problema.

Pager
Pagina precedenteMigrazione da v1.x
Pagina successivaAPI

Rilasciato sotto la licenza MIT.

Copyright (c) 2024 Mithril Contributors

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

Rilasciato sotto la licenza MIT.

Copyright (c) 2024 Mithril Contributors