Mitosis项目结构
以下是Mitosis的项目结构:
- src/ 包含Mitosis的源代码
- output/ 包含项目每个目标的输出,output中存在.lite和.tsx文件,这是可读的Mitosis组件,可以参考这些文件让我们更方便的进行调试。因为实际输出的js被简化了很难阅读。
- mitosis.config.js 包含一些通用的配置和每个目标的配置,对Mitosis进行构建的时候使用。
- overrides/ 包含一个模仿src/目录的文件夹,并且将完全替换具有相同名称的文件夹,比如我们定义overrides/react-native/src/functions/is-react-native.ts,它将在
output/react-native/src/functions/is-react-native.js. 中覆盖
src/functions/is-react-native.ts
Mitosis组件
Mitosis受许多现代框架的影响,Mitosis组件看起来像React组件,使用类似React的hooks,拥有类似Vue的可变的响应式状态,使用类似Solid那样的静态形式的JSX,像Slvelte那样可以进行编译,并使用Angular那样简单的规范结构。
概括就是:React Hooks + Vue state + JSX + 可编译 + Angular 规范
Mitosis组件示例:
import { For, Show, useStore } from '@builder.io/mitosis';
export default function MyComponent(props) {
const state = useStore({
newItemName: 'New item',
list: ['hello', 'world'],
addItem() {
state.list = [...state.list, state.newItemName];
},
});
return (
<div>
<Show when={props.showInput}>
<input
value={state.newItemName}
onChange={(event) => (state.newItemName = event.target.value)}
/>
</Show>
<div css={{ padding: '10px' }}>
<button onClick={() => state.addItem()}>Add list item</button>
<div>
<For each={state.list}>{(item) => <div>{item}</div>}</For>
</div>
</div>
</div>
);
}
Mitosis和大多数前端框架一样是组件驱动的。每个Mitosis组件应该在它自己的文件中单独默认导出。它们是返回JSX结构的简单函数。
样式
样式是通过dom元素和组件的css props控制的。可以设置css属性对象或者有效的css 属性字符串。例如:
export default function CSSExample() {
return <div css={{ marginTop: '10px', color: 'red' }} />;
}
还可以将媒体查询作为键,将样式对象作为值。
export default function ResponsiveExample() {
return (
<div
css={{
marginTop: '10px',
'@media (max-width: 500px)': {
marginTop: '0px',
},
}}
/>
);
}
Mitosis更希望你使用class,同样也支持className,如果两者在同一组件中使用,最好合并起来,使用class。
State
state由useStore钩子提供,目前,这个值的名称必须是state,如下所示:
export default function MyComponent() {
const state = useStore({
name: 'Steve',
});
return (
<div>
<h2>Hello, {state.name}</h2>
<input onInput={(event) => (state.name = event.target.value)} value={state.name} />
</div>
);
}
如果初始状态值是计算出来的,无论是参数props中获取的还是方法的返回值,都不能直接使用,这种情况需要使用getter方法:
import { kebabCase } from 'lodash';
export default function MyComponent(props) {
const state = useStore({
name: 'Steve',
get transformedName() {
return kebabCase('Steve');
},
get transformedName() {
return props.name;
},
});
return (
<div>
<h2>Hello, {state.name}</h2>
<input onInput={(event) => (state.name = event.target.value)} value={state.name} />
</div>
);
}
当状态值发生变化时组件会自动更新