用Mitosis和Builder.io创建可重复使用的组件

1,579 阅读5分钟

开发团队中常见的挑战是使用相同的语言;当一个子团队使用Vue时,另一个子团队可能使用React,导致工作冗余,迫使你两次创建共享组件。

在本教程中,我们将探讨Mitosis,这个工具除了可以将代码编译为标准的JavaScript外,还可以编译Angular、React和Vue等框架和库,使你能够创建可重用的组件。

我们将回顾一些背景信息,以澄清你何时应该使用Mitosis,然后在一个新项目中安装Mitosis,看看它的运行情况。让我们开始吧!

Mitosis vs. Web组件

虽然一些开发者最初转向Web组件来创建可重用的组件,但他们遇到了Web组件的浏览器兼容性和它的低级方法等问题,这使得创建可重用的组件成为一个密集的过程。

同样,像React这样的某些库的工作流程使得纳入网络组件变得困难,从而导致了像谷歌的LitElement、Ionic和Stencil.js这样的解决方案的产生

同时,在Svelte和SolidJS中出现了一个平行的趋势。Svelte和SolidJS旨在构建应用程序,通过将源代码编译为标准的JavaScript,创造出比Web组件更小更快的捆绑程序,从而获得巨大的性能提升。

Mitosis建立在Svelte和SolidJS的功能之上,采用了相同的编译速度,并允许你从同一代码库中将一个组件重新编译为不同的框架和库。编译后的组件像框架中的任何其他组件一样运行。

与SolidJS类似,Mitosis使用一个JSX的版本,将组件编译为JSON。然后插件将组件编译为不同的目标,允许你在两个方向上创建工具。

  • 可转换为Mitosis JSON的代码
  • 将JSON编译或序列化为目标框架的插件

由于这些原因,Mitosis支持无代码工具。例如,Builder.io允许你使用可视化工具创建你的网站,然后将其编译到你选择的框架中。Builder.io作为一个CMS,但由Mitosis提供动力。

Mitosis使用所见即所得的编辑和一个SPA框架进行编译。现在我们了解了Mitosis的工作原理,让我们用Mitosis创建一个组件。

开始使用Mitosis

首先,我们要安装Mitosis CLI。

npm install -g @builder.io/mitosis-cli

在你的电脑上创建一个空文件夹。在你的终端中,打开该文件夹并创建一个新的npm项目。

npm init -y

接下来,我们将安装Mitosis。

npm install @builder.io/mitosis

创建一个名为component.lite.jsx 的文件。lite.jsx 是Mitosis项目的扩展。接下来,我们将安装Builder.io VS Code扩展,它为lite.jsx 文件提供语法高亮。

component.lite.jsx 文件中,添加以下代码。

import { useState, Show, For } from "@builder.io/mitosis";
export default function Component(props){
const state = useState({count: 0})

在上面的代码中,我们使用useState Hook声明状态。现在,当状态对象中的任何属性被改变时,用户界面将呈现。

接下来,在component.lite.jsx ,添加以下代码块,它将像React或SolidJS一样返回JSX。

    return (<div>
        {/* DISPLAY SOME JSX CONDITIONALLY */}
        <Show when={state.count > 10}>
            <h1>You Win!!!</h1>    
        </Show>

        {/* DISPLAY THE COUNT */}
        <h1>{state.count}</h1>

        {/* BUTTON TO ADD TO THE COUNT */}
        <button onClick={(event) => {state.count += 1}}>Click to Add One</button>
    </div>)
}

在上面的代码中,show 组件允许我们有条件地渲染UI。因为状态是通过普通的重新分配来更新的,所以不需要添加setState 函数,我们会在React中使用。最后,注意到我们所有的状态都可以被捆绑在一个对象中。

现在我们的组件已经建立起来了,让我们看看我们的组件在不同框架中的编译实例吧

在Mitosis中的编译

React

让我们用Mitosis把我们的组件编译成一个React组件。

mitosis compile --to=react component.lite.jsx > component.jsx

--to= 标志让我们选择我们的Mitosis组件将被编译到哪个框架。当编译到React时,我们会得到以下输出。

import { useContext } from "react";
import { useLocalObservable } from "mobx-react-lite";
export default function Component(props) {
  const state = useLocalObservable(() => ({ count: 0 }));
  return (
    <div>
      {state.count > 10 && (
        <>
          <h1>You Win!!!</h1>
        </>
      )}
      <h1>{state.count}</h1>
      <button
        onClick={(event) => {
          state.count += 1;
        }}
      >
        Click to Add One
      </button>
    </div>
  );
}

Vue

--to=vue component.lite.jsx > component.vue

当编译到Vue时,我们的组件将看起来像下面的代码。

<template>
  <div>
    {{/* DISPLAY SOME JSX CONDITIONALLY */}}
    <template v-if="count > 10">
      <h1>You Win!!!</h1>
    </template>

    {{/* DISPLAY THE COUNT */}}
    <h1>{{ count }}</h1>

    {{/* BUTTON TO ADD TO THE COUNT */}}
    <button @click="count += 1">Click to Add One</button>
  </div>
</template>
<script>
export default {
  name: "Component",

  data: () => ({ count: 0 }),
};
</script>

Svelte

--to=svelte component.lite.jsx > component.svelte

当我们把Mitosis组件编译到Svelte时,我们会得到下面的输出。

<script>

     let  count= 0

</script>

<div >

  {#if count > 10 }       
    <h1 >You Win!!!</h1>
  {/if}

  <h1 >{count}</h1>

  <button  on:click="{event => 
    count += 1;
  }" >Click to Add One</button>

</div>

Angular

--to=angular component.lite.jsx > component.tsx

当我们把我们的Mitosis组件编译到Angular时,它将看起来像下面的代码。

import { Component } from "@angular/core";

@Component({
  selector: "component",
  template: 
    <div>
      <ng-container *ngIf="count > 10">
        <h1>You Win!!!</h1>
      </ng-container>

      <h1>{{count}}</h1>

      <button
        (click)="
      count += 1;
    "
      >
        Click to Add One
      </button>
    </div>
  ,
})
export default class Component {
  count = 0;
}

web组件

--to=customElement component.lite.jsx > component.js

当编译到web组件时,我们会得到下面的输出。

/**
 * Usage:
 *
 *  <component></component>
 *
 */
class Component extends HTMLElement {
  constructor() {
    super();

    const self = this;
    this.state = { count: 0 };

    // Event handler for 'click' event on button-1
    this.onButton1Click = (event) => {
      this.state.count += 1;
      this.update();
    };
  }

  connectedCallback() {
    this.innerHTML = `
      <div>
        <span data-name="show">
          <h1>You Win!!!</h1>
        </span>

        <h1>
         <span data-name="div-1"><!-- state.count --></span>
        </h1>

        <button data-name="button-1">Click to Add One</button>
      </div>
     <style></style>`;
    this.update();
  }

  update() {
    this.querySelectorAll("[data-name='show']").forEach((el) => {
      el.style.display = this.state.count > 10 ? "inline" : "none";
    });

    this.querySelectorAll("[data-name='div-1']").forEach((el) => {
      el.innerText = this.state.count;
    });

    this.querySelectorAll("[data-name='button-1']").forEach((el) => {
      el.removeEventListener("click", this.onButton1Click);
      el.addEventListener("click", this.onButton1Click);
    });
  }
}

customElements.define("component", Component);

正如你所看到的,安装Mitosis,创建一个组件,然后将其编译为你所选择的语言、库或框架是很直接的。我们在本教程中涵盖了几个例子,但只是触及了表面;其他编译目标包括Swift、Liquid.js、SolidJS、React Native等等。

结论

当你不可能与你的团队其他成员使用相同的语言时,Mitosis是一个有用的工具,它通过减少冗余的工作来节省时间。

Mitosis允许你为单个组件编写一个代码库,然后将其编译到许多目标之一。它 为创建快速、反应式应用程序的低代码和无代码解决方案提供了便利。

我们探讨了 Builder.io 插件,但另一个流行的插件是figma-html插件,它允许你将你的 Figma 设计变成任何框架的代码。

当你构建自己的可重用组件时,你可以使用Builder.io的JJS-lite fiddle看到可视化的结果。然而,在撰写本文时,这一功能仍处于早期预览阶段。我希望你喜欢这个教程

The postCreate reusable components with Mitosis and Builder.ioappeared first onLogRocket Blog.