开发团队中常见的挑战是使用相同的语言;当一个子团队使用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.