【实战】从零开始打造一个低代码平台——8、全局状态管理2


前言

前一章我们开始引入了全局状态管理,扩展了侧边栏显示屏幕列表,但拖拽到屏幕的组件还没有同步用全局数据。这一章我们把相关的地方都同步用全局数据来管理,实现屏幕切换,还要继续扩展WidgetBar


一、扩展控件

前面章节里的WidgetBar只有一个Button,所以我们偷了点懒,在Canvas绘制组件的时候直接写死了Button。在实际产品里当然不能这么做了,接下来我们进一步扩展控件和WidgetBar,让它看起来更产品化。
我们已经定义了ButtonContainer的数据类型,但对应的控件我们还没有定义。先来完成它们的外观。

// Button Widget
import {
   
    WidgetProps } from '.';

export const ButtonWidget: React.FC<WidgetProps> = ({
   
   
  className,
  left,
  top,
  width,
  height,
}) => {
   
   
  return (
    <div
      className={
   
   `absolute left-3 top-3 w-12 bg-gray-700 rounded-md flex flex-col justify-center items-center p-2 space-y-2 ${
     
     
        className ?? ""
      }`}
      style={
   
   {
   
    left, top, width, height }}
    >
      Button
    </div>
  );
};

// Container Widget
import {
   
    WidgetProps } from '.';

export const ContainerWidget: React.FC<WidgetProps> = ({
   
    className, left, top, width, height }) => {
   
   
  return (
    <div
      className={
   
   `absolute left-3 top-3 w-12 bg-gray-700 rounded-md flex flex-col justify-center items-center p-2 space-y-2 ${
     
     
        className?? ""
        }`}
      style={
   
   {
   
   
        left, top, width, height
      }}
    >Container</div>
  );
};

嗯?这两个控件有什么差别吗?本质上没差别,就是一个普通的<div>,但对于系统来说就是两个控件,这就够了。至于它们的具体实现不是这一章节的主要内容,我们留待日后再表。

二、定义控件库

上面定义好了ButtonContainer控件,我们还要把控件的数据类型跟对应的控件映射起来,这样我们可以根据组件的控件类型绘出相应的组件。

import {
   
    ButtonWidget } from './btn-widget';
import {
   
    ContainerWidget } from './cont-widget';

export interface WidgetProps {
   
   
    className?: string;
}

interface WidgetLib {
   
   
    [key: string]: {
   
    icon: string, widget: React.FC<WidgetProps> };
}

export const widgetLib: WidgetLib = {
   
   
    btn: {
   
    icon: 'icon-anniu', widget: ButtonWidget },
    cont: {
   
    icon: 'icon-rongqi', widget: ContainerWidget },
}

WidgetLib是一个Map类型,key是控件名称,对应控件数据里的type,这里我把Button的控件数据再列出来对比看下:

export interface Button extends Widget {
   
   
    type: 'btn'; // 对应`WidgetLib`里的`key`
    text: string; // `Button`的属性
}

好,这样我们就定义好了控件数据,控件外观和它们的映射关系。

二、扩展WidgetStore

前面我们只在WidgetStore里定义了AddScrRemoveScr用来添加/删除屏幕,现在我们要增加一个AddWidget,当拖拽控件到画布上时,通过AddWidget来添加一个组件到当前的屏幕里。另外,我们增加currScrId用来标记当前处于哪个屏幕,和setCurrScrId来变更当前的屏幕,当用户点击不同屏幕时做切换。对了,还有一个init用作初始化操作,谁家还没个初始化呢。如

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值