Skip to content
Mithril.js 2
Main Navigation GuíaAPI

Español

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

Español

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

Apariencia

Sidebar Navigation

Primeros pasos

Instalación

Aplicación sencilla

Recursos

JSX

ES6+ en navegadores antiguos

Animaciones

Pruebas

Ejemplos

Integración con terceros

Manejo de Rutas

Conceptos clave

Nodos del DOM virtual

Componentes

Métodos de ciclo de vida

Claves

El sistema de redibujado automático

Varios

Comparación de frameworks

Migrando desde v1.x

Migración desde v0.2.x

API

En esta página

Migrando desde v1.x ​

La v2.x es casi completamente compatible con la API de v1.x, pero existen algunos cambios significativos.

Asignación a vnode.state ​

En v1.x, se podía manipular vnode.state y asignar cualquier valor. En v2.x, se lanzará un error si se intenta modificarlo directamente. La migración puede variar, pero en la mayoría de los casos, es tan simple como cambiar las referencias de vnode.state a vnode.state.foo, eligiendo un nombre apropiado para foo (como count, si representa el valor actual de un contador).

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

Cuando se lanzó v1.0 por primera vez, los componentes de clase y de closure no existían, por lo que simplemente se extraía lo que se necesitaba de vnode.tag. Este detalle de implementación es lo que permitía hacerlo, y algunos comenzaron a depender de ello. También se insinuaba como posible en algunos lugares dentro de la documentación. Ahora, las cosas son diferentes, y esto facilita la administración desde un punto de vista de implementación, ya que solo hay una referencia al estado, no dos.

Cambios en los enlaces de ruta ​

En v1.x, se utilizaba oncreate: m.route.link y, si el enlace podía cambiar, onupdate: m.route.link también, como ciclos de vida en el vnode que se podía enrutar. En v2.x, ahora se utiliza un componente m.route.Link. El selector se puede especificar a través de un atributo selector:, en caso de que se estuviera usando algo diferente a m("a", ...), las opciones se pueden especificar a través de options:, se puede deshabilitar a través de disabled:, y otros atributos se pueden especificar en línea, incluyendo href: (obligatorio). El selector: en sí mismo puede contener cualquier selector válido como el primer argumento para m, y los atributos [href=...] y [disabled] se pueden especificar tanto en el selector como en las opciones normales.

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

Cambios en los errores de m.request ​

En v1.x, m.request analizaba los errores de las llamadas JSON y asignaba las propiedades del objeto resultante analizado a la respuesta. Entonces, si se recibía una respuesta con el estado 403 y un cuerpo de {"code": "backoff", "timeout": 1000}, el error tendría dos propiedades adicionales: err.code = "backoff" y err.timeout = 1000.

En v2.x, la respuesta se asigna a una propiedad response en el resultado, y una propiedad code contiene el código de estado resultante. Entonces, si se recibía una respuesta con el estado 403 y un cuerpo de {"code": "backoff", "timeout": 1000}, el error tendría asignadas dos propiedades: err.response = {code: "backoff", timeout: 1000} y err.code = 403.

m.withAttr eliminado ​

En v1.x, los listeners de eventos podían usar oninput: m.withAttr("value", func) y similares. En v2.x, simplemente se leen directamente del elemento objetivo del evento. Se integraba bien con los streams, pero dado que el uso de m.withAttr("value", stream) no era ni de lejos tan común como m.withAttr("value", prop), m.withAttr perdió la mayor parte de su utilidad y, por lo tanto, se eliminó.

v1.x ​

javascript
var value = '';

// En tu vista
m('input[type=text]', {
  value: value(),
  oninput: m.withAttr('value', function (v) {
    value = v;
  }),
});

// O

var value = m.stream('');

// En tu vista
m('input[type=text]', {
  value: value(),
  oninput: m.withAttr('value', value),
});

v2.x ​

javascript
var value = '';

// En tu vista
m('input[type=text]', {
  value: value,
  oninput: function (ev) {
    value = ev.target.value;
  },
});

// O

var value = m.stream('');

// En tu vista
m('input[type=text]', {
  value: value(),
  oninput: function (ev) {
    value(ev.target.value);
  },
});

m.route.prefix ​

En v1.x, m.route.prefix era una función que se llamaba a través de m.route.prefix(prefix). Ahora es una propiedad que se establece a través de m.route.prefix = prefix

v1.x ​

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

v2.x ​

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

Parámetros y cuerpo de m.request/m.jsonp ​

data y useBody se refactorizaron en params (parámetros de consulta interpolados en la URL y añadidos a la petición) y body (el cuerpo para enviar en el XHR subyacente). Esto proporciona un mejor control sobre la petición real enviada y permite tanto interpolar en los parámetros de consulta con las peticiones POST como crear peticiones GET con cuerpos.

m.jsonp, al no tener un "cuerpo" significativo, simplemente usa params, por lo que renombrar data a params es suficiente para ese método.

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

Plantillas de ruta ​

En v1.x, había tres sintaxis separadas de plantilla de ruta que, aunque eran similares, tenían 2 sintaxis diseñadas por separado y 3 implementaciones diferentes. Se definía de una manera bastante ad-hoc, y los parámetros generalmente no se escapaban. Ahora, todo se codifica si es :key, sin formato si es :key.... Si las cosas se codifican inesperadamente, usa :path.... Es así de simple.

Concretamente, así es como afecta a cada método:

URLs de m.request y m.jsonp, rutas de m.route.set ​

Los componentes de ruta en v2.x se escapan automáticamente cuando se interpolan. Supongamos que se invoca m.route.set("/user/:name/photos/:id", {name: user.name, id: user.id}). Anteriormente, si user era {name: "a/b", id: "c/d"}, esto establecería la ruta a /user/a%2Fb/photos/c/d, pero ahora la establecerá a /user/a%2Fb/photos/c%2Fd. Si deliberadamente quieres interpolar una clave sin escapar, usa :key... en su lugar.

Las claves en v2.x no pueden contener ninguna instancia de . o -. En v1.x, podían contener cualquier cosa que no fuera /.

Las interpolaciones en cadenas de consulta en línea, como en /api/search?q=:query, no se realizan en v2.x. Pásalas a través de params con los nombres de clave apropiados en su lugar, sin especificarlos en la cadena de consulta.

Patrones de ruta de m.route ​

Las claves de ruta de la forma :key... devuelven su URL decodificada en v1.x, pero devuelven la URL sin formato en v2.x.

Anteriormente, cosas como :key.md se aceptaban erróneamente, con el valor del parámetro resultante establecido en keymd: "...". Este ya no es el caso: el .md ahora es parte del patrón, no del nombre.

Orden de llamada del ciclo de vida ​

En v1.x, los ciclos de vida de los atributos en los vnodes de los componentes se llamaban antes que los ciclos de vida propios del componente en todos los casos. En v2.x, este es el caso solo para onbeforeupdate. Por lo tanto, es posible que se deba ajustar el código en consecuencia.

v1.x ​

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

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

// Logs:
// Attrs oncreate
// Component oncreate

v2.x ​

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

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

// Logs:
// Component oncreate
// Attrs oncreate

Sincronía de m.redraw ​

m.redraw() en v2.x siempre es asíncrono. Se puede solicitar específicamente un redraw síncrono a través de m.redraw.sync() siempre que no se esté produciendo actualmente ningún redraw.

Precedencia de los atributos del selector ​

En v1.x, los atributos del selector tenían prioridad sobre los atributos especificados en el objeto de atributos. Por ejemplo, m("[a=b]", {a: "c"}).attrs devolvía {a: "b"}.

En v2.x, los atributos especificados en el objeto de atributos tienen prioridad sobre los atributos del selector. Por ejemplo, m("[a=b]", {a: "c"}).attrs devuelve {a: "c"}.

Ten en cuenta que esto técnicamente revierte al comportamiento de v0.2.x.

Normalización de los hijos ​

En v1.x, los hijos de los vnodes de los componentes se normalizaban como los demás vnodes. En v2.x, este ya no es el caso y se deberá planificar en consecuencia. Esto no afecta la normalización realizada en el renderizado.

Encabezados de m.request ​

En v1.x, Mithril.js establecía estos dos encabezados en todas las peticiones que no eran GET, pero solo cuando useBody se establecía en true (el valor predeterminado) y se cumplían las otras condiciones enumeradas:

  • Content-Type: application/json; charset=utf-8 para peticiones con cuerpos JSON
  • Accept: application/json, text/* para peticiones que esperan respuestas JSON

En v2.x, Mithril.js establece el primero para todas las peticiones con cuerpos JSON que son != null y lo omite de forma predeterminada en caso contrario, y esto se hace independientemente del método que se elija, incluso en las peticiones GET.

El primero de los dos encabezados, Content-Type, activará una pre-petición CORS ya que no es un encabezado de petición seguro para CORS debido al tipo de contenido especificado, y eso podría introducir nuevos errores dependiendo de cómo esté configurado CORS en el servidor. Si se tienen problemas con esto, es posible que se deba anular ese encabezado en cuestión pasando headers: {"Content-Type": "text/plain"}. (El encabezado Accept no activa nada, por lo que no es necesario anularlo).

Los únicos tipos de contenido que la especificación Fetch permite evitar las comprobaciones previas a la petición CORS son application/x-www-form-urlencoded, multipart/form-data y text/plain. No permite nada más, y prohíbe intencionalmente JSON.

Parámetros de consulta en cadenas hash en rutas ​

En v1.x, se podían especificar parámetros de consulta para rutas tanto en la cadena de consulta como en la cadena hash, por lo que m.route.set("/route?foo=1&bar=2"), m.route.set("/route?foo=1#bar=2") y m.route.set("/route#foo=1&bar=2") eran todos equivalentes y los atributos extraídos de ellos habrían sido {foo: "1", bar: "2"}.

En v2.x, el contenido de las cadenas hash se ignora pero se conserva. Entonces, los atributos extraídos de cada uno serían estos:

  • 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") → {}

La razón para hacer esto es que las URLs como https://example.com/#!/route#key son técnicamente inválidas según la especificación de URL e incluso eran inválidas según el RFC que la precedió, y es solo una peculiaridad de la especificación HTML que se permitan. (La especificación HTML debería haber requerido que los IDs y los fragmentos de ubicación fueran fragmentos de URL válidos desde el principio si quería seguir la especificación).

O en resumen, ¡deja de usar URLs inválidas!

Claves ​

En v1.x, se podían mezclar vnodes con clave y sin clave libremente. Si el primer nodo tiene clave, se realiza una diferencia con clave, asumiendo que cada elemento tiene una clave y simplemente ignorando los agujeros a medida que avanza. De lo contrario, se realiza una diferencia iterativa, y si un nodo tiene una clave, se verificaría que no haya cambiado al mismo tiempo que se verifican las etiquetas y similares.

En v2.x, las listas de hijos tanto de fragmentos como de elementos deben ser todas con clave o todas sin clave. Los agujeros también se consideran sin clave para los propósitos de esta verificación; ya no los ignora.

Si se necesita solucionar esto, se puede usar el modismo de un fragmento que contiene un solo vnode, como [m("div", {key: whatever})].

m.version eliminado ​

Tenía poco uso en general, y siempre se puede volver a añadir por cuenta propia. Se debe preferir la detección de características para saber qué características están disponibles, y la API v2.x está diseñada para habilitar mejor esto.

Pager
AnteriorComparación de frameworks
SiguienteMigración desde v0.2.x

Publicado bajo la licencia MIT.

Copyright (c) 2024 Mithril Contributors

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

Publicado bajo la licencia MIT.

Copyright (c) 2024 Mithril Contributors