【实战】从零开始打造一个低代码平台——3、组件化应用


前言

前面我们通过改造App.tsx设计了应用的布局,但总不能把整个应用的代码都塞进App.tsx里。这章开始,我们要通过组件的方式重新组织代码,让代码可读性更好,也更方便扩展。


一、新的代码结构

先在src下新建一个目录components,这里放置各个组件,然后再把这些组件拼凑成应用。
前面布局的时候我们提到,会有Menu SideBar ToolBar Footer Content这几个部分。我们再进一步将Content分为画布区(Canvas)和属性区(Attrs),再挂上一个WidgetBar。现在我们就为分别为它们创建对应的组件(和文件)并放在components下。以下就是新的代码结构:

├── App.tsx
├── assets
│   └── react.svg
├── components
│   ├── attrs.tsx
│   ├── canvas.tsx
│   ├── content.tsx
│   ├── footer.tsx
│   ├── layout.tsx
│   ├── menu.tsx
│   ├── sidebar.tsx
│   ├── toolbar.tsx
│   └── widgetbar.tsx
├── main.tsx
├── styles
│   └── index.scss
├── styles.css
└── vite-env.d.ts

二、组件化应用

接下来,我们依次创建对应的组件。

2.1 Menu

interface MenuProps {
  className?: string;
}

export const Menu: React.FC<MenuProps> = ({ className }) => {
  return <div className={`h-10 ${className ?? ""}`}></div>;
};

2.2 SideBar

interface SideBarProps {
  className?: string;
}

export const SideBar: React.FC<SideBarProps> = ({ className }) => {
  return <div className={className ?? ""}></div>;
};

2.3 ToolBar

interface ToolBarProps {
  className?: string;
}

export const ToolBar: React.FC<ToolBarProps> = ({ className }) => {
  return <div className={className ?? ""}></div>;
};

2.4 Footer

interface FooterProps {
  className?: string;
}

export const Footer: React.FC<FooterProps> = ({ className }) => {
  return <div className={`h-10 ${className ?? ""}`}></div>;
};

2.5 Content

Content分为画布区(Canvas)和属性区(Attrs),再挂上一个WidgetBar

import { Attrs } from "./attrs";
import { Canvas } from "./canvas";
import { WidgetBar } from "./widgetbar";

interface ContentProps {
  className?: string;
}

export const Content: React.FC<ContentProps> = ({ className }) => {
  return (
    <div className={`relative h-full ${className ?? ""}`}>
      <WidgetBar />
      <div className="flex h-full">
        <div className="flex-1 flex justify-center items-center">
          <Canvas className="w-[360pt] h-[240pt] bg-white" />
        </div>
        <div className="w-[2px]  h-full bg-gray-950" />
        <Attrs />
      </div>
    </div>
  );
};

2.6 WidgetBar

interface WidgetBarProps {
  className?: string;
}

export const WidgetBar: React.FC<WidgetBarProps> = ({ className }) => {
  return (
    <div
      className={`absolute left-3 top-3 w-12 h-80 bg-gray-700 rounded-md ${
        className ?? ""
      }`}
    ></div>
  );
};

2.7 Canvas

interface CanvasProps {
  className?: string;
}

export const Canvas: React.FC<CanvasProps> = ({ className }) => {
  return <div className={className ?? ""}></div>;
};

2.8 Attrs

interface AttrsProps {
  className?: string;
}

export const Attrs: React.FC<AttrsProps> = ({ className }) => {
  return <div className={`w-1/5 min-w-[240px] ${className ?? ""}`}></div>;
};

2.9 AppLayout

我们把之前App的布局代码抽取成一个组件AppLayoutlayout.tsx),这样在其它界面也可以复用。为了看起来不像之前那么丑,我们也做了一些调整。

interface AppLayoutProps {
  menu: React.ReactNode;
  sidebar: React.ReactNode;
  toolbar: React.ReactNode;
  content: React.ReactNode;
  footer: React.ReactNode;
}

export const AppLayout: React.FC<AppLayoutProps> = ({
  menu,
  sidebar,
  toolbar,
  content,
  footer,
}) => {
  return (
    <div className="flex flex-col h-screen bg-gray-500">
      <div className="w-full">{menu}</div>
      <div className='h-[2px] bg-gray-950' />
      <div className="flex-1 flex w-full">
        <div className="w-[200px]">{sidebar}</div>
        <div className='w-[2px] bg-gray-950' />
        <div className="flex-1 flex flex-col">
          <div>{toolbar}</div>
          <div className="flex-1">{content}</div>
          <div className='h-[2px] bg-gray-950' />
          <div>{footer}</div>
        </div>
      </div>
    </div>
  );
};

2.10 App

改造后的App.tsx变成这个样子:

import { Canvas } from './components/canvas';
import { Footer } from './components/footer';
import { AppLayout } from './components/layout';
import { Menu } from './components/menu';
import { SideBar } from './components/sidebar';
import { ToolBar } from './components/toolbar';
import "./styles/index.scss";

function App() {
  return (
    <AppLayout
      menu={<Menu />}
      sidebar={<SideBar />}
      toolbar={<ToolBar />}
      content={<Canvas />}
      footer={<Footer />}
    />
  );
}

export default App;

现在我们的应用运行起来是这个样子的(深灰色的区块是WidgetBar):
在这里插入图片描述
这看起来就稍微正经点了。如果你看着还不够顺眼,那就撸起袖子改造它吧。


总结

至此,我们的应用布局工作就告一段落了,我们会有一段时间不会去动到App.tsx这个入口文件。接下去,我们将往各个区域添加内容,不断地拆解Menu SideBar ToolBar等这些组件。而随着代码越来越多,我们还会根据需要进行代码重构。
你有没有发现,除了在App.tsx中引入styles/index.scss,我们没有再引入任何其它的*.scss(或*.css/*.less)文件。在上一章节我们留下的问题“为什么要消灭样式文件”,你有答案了吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值