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

JSX ​

Descrizione ​

JSX è un'estensione della sintassi che permette di scrivere tag HTML all'interno del codice JavaScript. Non è parte di alcuno standard JavaScript e non è strettamente necessario per creare applicazioni, ma può risultare più intuitivo a seconda delle preferenze personali o del team.

jsx
function MyComponent() {
  return {
    view: () => m('main', [m('h1', 'Hello world')]),
  };
}

// può essere scritto come:

function MyComponent() {
  return {
    view: () => (
      <main>
        <h1>Hello world</h1>
      </main>
    ),
  };
}

Quando si usa JSX, è possibile inserire espressioni JavaScript all'interno dei tag JSX utilizzando le parentesi graffe:

jsx
var greeting = 'Hello';
var url = 'https://google.com';
var link = <a href={url}>{greeting}!</a>;
// produce <a href="https://google.com">Hello!</a>

I componenti possono essere utilizzati capitalizzando la prima lettera del nome del componente o accedendovi come proprietà:

jsx
m.render(document.body, <MyComponent />)
// equivalente a m.render(document.body, m(MyComponent))
<m.route.Link href="/home">Go home</m.route.Link>
// equivalente a m(m.route.Link, {href: "/home"}, "Go home")

Configurazione ​

Il modo più semplice per utilizzare JSX è tramite un plugin di Babel.

Babel richiede npm, che viene installato automaticamente quando si installa Node.js. Una volta installato npm, crea una directory di progetto ed esegui questo comando:

bash
npm init -y

Se si desidera utilizzare Webpack e Babel insieme, passare alla sezione successiva.

Per installare Babel come strumento autonomo, usa questo comando:

bash
npm install @babel/core @babel/cli @babel/preset-env @babel/plugin-transform-react-jsx --save-dev

Crea un file .babelrc:

json
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "pragma": "m",
        "pragmaFrag": "'['"
      }
    ]
  ]
}

Per eseguire Babel, configura uno script npm. Apri package.json e aggiungi questa voce sotto "scripts":

json
{
  "name": "my-project",
  "scripts": {
    "babel": "babel src --out-dir bin --source-maps"
  }
}

Ora puoi eseguire Babel usando questo comando:

bash
npm run babel

Usare Babel con Webpack ​

Se non hai già installato Webpack come bundler, usa questo comando:

bash
npm install webpack webpack-cli --save-dev

Puoi integrare Babel in Webpack seguendo questi passaggi.

bash
npm install @babel/core babel-loader @babel/preset-env @babel/plugin-transform-react-jsx --save-dev

Crea un file .babelrc:

json
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "pragma": "m",
        "pragmaFrag": "'['"
      }
    ]
  ]
}

Successivamente, crea un file chiamato webpack.config.js

jsx
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, './bin'),
    filename: 'app.js',
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /\/node_modules\//,
        use: {
          loader: 'babel-loader',
        },
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};

Per chi ha già familiarità con Webpack, si noti che aggiungere le opzioni Babel direttamente alla sezione babel-loader del file webpack.config.js causerà un errore. È quindi necessario includerle nel file .babelrc separato.

Questa configurazione presuppone che il file di codice sorgente per il punto di ingresso dell'applicazione si trovi in src/index.js e che il bundle verrà generato in bin/app.js.

Per eseguire il bundler, configura uno script npm. Apri package.json e aggiungi questa voce sotto "scripts":

json
{
  "name": "my-project",
  "scripts": {
    "start": "webpack --mode development --watch"
  }
}

Ora puoi eseguire il bundler eseguendo questo comando dalla riga di comando:

bash
npm start

Build di produzione ​

Per generare un file minimizzato, apri package.json e aggiungi un nuovo script npm chiamato build:

json
{
  "name": "my-project",
  "scripts": {
    "start": "webpack -d --watch",
    "build": "webpack -p"
  }
}

Puoi utilizzare gli hook nel tuo ambiente di produzione per eseguire automaticamente lo script di build di produzione. Ecco un esempio per Heroku:

json
{
  "name": "my-project",
  "scripts": {
    "start": "webpack -d --watch",
    "build": "webpack -p",
    "heroku-postbuild": "webpack -p"
  }
}

Rendere m accessibile globalmente ​

Per poter accedere a m globalmente da tutto il tuo progetto, prima importa webpack nel tuo webpack.config.js in questo modo:

js
const webpack = require('webpack');

Quindi crea un nuovo plugin nella proprietà plugins dell'oggetto di configurazione Webpack:

js
{
  plugins: [
    new webpack.ProvidePlugin({
      m: 'mithril',
    }),
  ];
}

Vedi la documentazione di Webpack per maggiori informazioni su ProvidePlugin.

Differenze con React ​

JSX in Mithril ha alcune differenze sottili ma importanti rispetto al JSX di React.

Convenzioni di case delle proprietà di attributi e stili ​

React richiede di usare i nomi delle proprietà DOM in camelCase invece dei nomi degli attributi HTML per tutti gli attributi diversi dagli attributi data-* e aria-*. Ad esempio, usare className invece di class e htmlFor invece di for. In Mithril, è più comune utilizzare i nomi degli attributi HTML in minuscolo. Mithril utilizza sempre l'impostazione degli attributi se una proprietà non esiste, il che si allinea in modo più intuitivo con HTML. Si noti che nella maggior parte dei casi, i nomi delle proprietà DOM e degli attributi HTML sono uguali o molto simili. Ad esempio, value/checked per gli input e l'attributo globale tabindex rispetto alla proprietà elem.tabIndex sugli elementi HTML. Molto raramente differiscono oltre l'uso di maiuscole/minuscole: la proprietà elem.className per l'attributo class o la proprietà elem.htmlFor per l'attributo for sono tra le poche eccezioni.

Allo stesso modo, React usa sempre i nomi delle proprietà di stile in camelCase esposti nel DOM tramite le proprietà di elem.style (come cssHeight e backgroundColor). Mithril supporta sia questo che i nomi delle proprietà CSS in kebab-case (come height e background-color) e preferisce idiomaticamente quest'ultimo. Solo cssHeight, cssFloat e le proprietà con prefisso del vendor differiscono in qualcosa di più del case.

Eventi DOM ​

React mette in maiuscolo il primo carattere di tutti i gestori di eventi: onClick ascolta gli eventi click e onSubmit per gli eventi submit. Alcuni vengono ulteriormente modificati poiché sono più parole concatenate insieme. Ad esempio, onMouseMove ascolta gli eventi mousemove. Mithril non esegue questa mappatura di case, ma aggiunge semplicemente on all'evento nativo, quindi dovresti aggiungere listener per onclick e onmousemove per ascoltare rispettivamente questi due eventi. Ciò corrisponde molto più da vicino allo schema di denominazione di HTML ed è molto più intuitivo se si proviene da un background HTML o DOM vanilla.

React supporta la pianificazione dei listener di eventi durante la fase di acquisizione (nel primo passaggio, da fuori a dentro, al contrario della fase di bubble predefinita che va da dentro a fuori nel secondo passaggio) aggiungendo Capture a quell'evento. Mithril attualmente non ha tale funzionalità, ma potrebbe acquisirla in futuro. Se ciò è necessario, puoi aggiungere e rimuovere manualmente i tuoi listener negli hook del ciclo di vita.

JSX vs hyperscript ​

JSX e hyperscript sono due sintassi diverse che puoi usare per specificare i vnode e hanno diversi compromessi:

  • JSX è molto più accessibile se provieni da un background HTML/XML e ti senti più a tuo agio a specificare elementi DOM con quel tipo di sintassi. È anche leggermente più pulito in molti casi poiché utilizza meno punteggiatura e gli attributi contengono meno rumore visivo, quindi molte persone lo trovano molto più facile da leggere. E, naturalmente, molti editor comuni forniscono il supporto per il completamento automatico per gli elementi DOM nello stesso modo in cui lo fanno per HTML. Tuttavia, richiede un passaggio di build aggiuntivo per essere usato, il supporto dell'editor non è così ampio come lo è con il normale JS ed è considerevolmente più prolisso. È anche un po' più prolisso quando si ha a che fare con molti contenuti dinamici perché devi usare le interpolazioni per tutto.

  • Hyperscript è più accessibile se provieni da un background JS backend che non coinvolge molto HTML o XML. È più conciso con meno ridondanza e fornisce uno zucchero sintattico simile a CSS per classi statiche, ID e altri attributi. Può anche essere usato senza alcun passaggio di build, anche se puoi aggiungerne uno se lo desideri. Ed è leggermente più facile da usare di fronte a molti contenuti dinamici, perché non è necessario "interpolare" nulla. Tuttavia, la concisione lo rende più difficile da leggere per alcune persone, specialmente quelle meno esperte e provenienti da uno sfondo HTML/CSS/XML front-end, e non sono a conoscenza di alcun plugin che completi automaticamente parti di selettori hyperscript come ID, classi e attributi.

Puoi vedere i compromessi manifestarsi in alberi più complessi. Ad esempio, si consideri questo esempio hyperscript, adattato da un progetto reale di @dead-claudia con alcune modifiche per chiarezza e leggibilità:

javascript
function SummaryView() {
  let tag, posts;

  function init({ attrs }) {
    Model.sendView(attrs.tag != null);
    if (attrs.tag != null) {
      tag = attrs.tag.toLowerCase();
      posts = Model.getTag(tag);
    } else {
      tag = undefined;
      posts = Model.posts;
    }
  }

  function feed(type, href) {
    return m('.feed', [
      type,
      m('a', { href }, m('img.feed-icon[src=./feed-icon-16.gif]')),
    ]);
  }

  return {
    oninit: init,
    // Per garantire che il tag venga differenziato correttamente al cambio di rotta.
    onbeforeupdate: init,
    view: () =>
      m('.blog-summary', [
        m('p', 'My ramblings about everything'),

        m('.feeds', [
          feed('Atom', 'blog.atom.xml'),
          feed('RSS', 'blog.rss.xml'),
        ]),

        tag != null
          ? m(TagHeader, { len: posts.length, tag })
          : m('.summary-header', [
              m('.summary-title', 'Posts, sorted by most recent.'),
              m(TagSearch),
            ]),

        m(
          '.blog-list',
          posts.map(post =>
            m(
              m.route.Link,
              {
                class: 'blog-entry',
                href: `/posts/${post.url}`,
              },
              [
                m(
                  '.post-date',
                  post.date.toLocaleDateString('en-US', {
                    year: 'numeric',
                    month: 'long',
                    day: 'numeric',
                  })
                ),

                m('.post-stub', [
                  m('.post-title', post.title),
                  m('.post-preview', post.preview, '...'),
                ]),

                m(TagList, { post, tag }),
              ]
            )
          )
        ),
      ]),
  };
}

Ecco l'esatto equivalente del codice sopra, usando invece JSX. Puoi vedere come le due sintassi differiscono proprio in questo bit e quali compromessi si applicano.

jsx
function SummaryView() {
  let tag, posts;

  function init({ attrs }) {
    Model.sendView(attrs.tag != null);
    if (attrs.tag != null) {
      tag = attrs.tag.toLowerCase();
      posts = Model.getTag(tag);
    } else {
      tag = undefined;
      posts = Model.posts;
    }
  }

  function feed(type, href) {
    return (
      <div class="feed">
        {type}
        <a href={href}>
          <img class="feed-icon" src="./feed-icon-16.gif" />
        </a>
      </div>
    );
  }

  return {
    oninit: init,
    // Per garantire che il tag venga differenziato correttamente al cambio di rotta.
    onbeforeupdate: init,
    view: () => (
      <div class="blog-summary">
        <p>My ramblings about everything</p>

        <div class="feeds">
          {feed('Atom', 'blog.atom.xml')}
          {feed('RSS', 'blog.rss.xml')}
        </div>

        {tag != null ? (
          <TagHeader len={posts.length} tag={tag} />
        ) : (
          <div class="summary-header">
            <div class="summary-title">Posts, sorted by most recent</div>
            <TagSearch />
          </div>
        )}

        <div class="blog-list">
          {posts.map(post => (
            <m.route.Link class="blog-entry" href={`/posts/${post.url}`}>
              <div class="post-date">
                {post.date.toLocaleDateString('en-US', {
                  year: 'numeric',
                  month: 'long',
                  day: 'numeric',
                })}
              </div>

              <div class="post-stub">
                <div class="post-title">{post.title}</div>
                <div class="post-preview">{post.preview}...</div>
              </div>

              <TagList post={post} tag={tag} />
            </m.route.Link>
          ))}
        </div>
      </div>
    ),
  };
}

Suggerimenti e trucchi ​

Conversione di HTML in JSX ​

In Mithril.js, l'HTML ben formato è generalmente JSX valido. Per far funzionare il tutto, è sufficiente incollare codice HTML grezzo. Le uniche cose che normalmente dovresti fare sono cambiare i valori delle proprietà senza virgolette come attr=value in attr="value" e cambiare gli elementi void come <input> in <input />, in quanto JSX è basato su XML e non su HTML.

Quando si usa hyperscript, spesso è necessario tradurre HTML in sintassi hyperscript per usarlo. Per accelerare questo processo, puoi utilizzare un convertitore HTML-to-Mithril-template creato dalla comunità per fare gran parte del lavoro per te.

Pager
Pagina precedenteApplicazione semplice
Pagina successivaES6+ su browser legacy

Rilasciato sotto la licenza MIT.

Copyright (c) 2024 Mithril Contributors

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

Rilasciato sotto la licenza MIT.

Copyright (c) 2024 Mithril Contributors