物料区的“超市大冒险”:组件、遥控器与快乐星球的奇遇记 🛒🦄

你有没有想过,开发也能像逛超市一样有趣?今天带你走进低代码平台物料区的"超市大冒险",看组件如何排队上架、拖拽入篮,遥控器(面板)如何一键切换频道,开发体验直接拉满!🌈


一、引言:组件江湖,物料为王 👑

在低代码平台的世界里,物料区就像厨房里的调料架------没有它,做菜(开发)就没滋味。想象一下,如果你家厨房只有盐和酱油,做出来的菜能好吃吗?物料区的设计,就是让你的开发"调料"丰富多彩,随心搭配!

代码仓库地址内附项目体验地址


二、原理篇:问题-解决方案大起底 🧐

1. 问题场景

  • 组件太多,找不到?(就像超市货架太长,找不到辣条)
  • 拖拽交互卡顿?(购物车推不动,体验感-100)
  • 结构层级混乱?(买了啥都忘了,回家一看全是泡面)

2. 解决思路

  • 组件列表(Material):像超市货架,分类明晰
  • 拖拽交互(MaterialItem):鼠标一拖,组件随行 🛒
  • 结构大纲(Outline):树状结构,层级一目了然 🌳
  • 源码预览(Source):所见即所得,代码同步 📝
  • 多视图切换(MaterialWrapper):一键切换,效率拉满 🎛️

三、实现篇:代码就是最好的说明书 💡

1. 物料区总控台------MaterialWrapper 🎮

tsx 复制代码
// src/editor/components/MaterialWrapper/index.tsx
import React, { useState } from 'react'
import { Segmented } from 'antd';
import Material from '../Materail'
import Outline from '../Outline'
import Source from '../Source'

export default function MaterialWrapper() {
    const [key, setKey] = useState('物料')
    return (
        <div>
            {/* 顶部标签切换,像遥控器一样一键切换视图 */}
            <Segmented value={key} options={['物料', '大纲', '源码']} block onChange={setKey} />
            <div className='pd-[20px] h-[calc(100vh-60px-30px-20px)]'>
                {key === '物料' && <Material />}
                {key === '大纲' && <Outline />}
                {key === '源码' && <Source />}
            </div>
        </div>
    )
}

详细解读

  • Segmented 组件就像遥控器的频道按钮,用户可以一键切换"物料"、"大纲"、"源码"三大视图。📺
  • useState 控制当前选中的频道,保证切换时内容实时刷新。
  • 下方内容区根据 key 动态渲染对应的子组件,实现"所见即所得"。
  • 生活比喻:MaterialWrapper 就像"万能遥控器",随时切换你想要的频道(视图),再也不用满屋子找遥控器啦!

2. 组件货架------Material & MaterialItem 🛒

Material:组件列表生成器

tsx 复制代码
// src/editor/components/Materail/index.tsx
import { useMemo } from 'react'
import { useComponentConfigStore } from '../../stores/component-config'
import MaterialItem from '../MaterialItem'
import { useComponentsStore } from '../../stores/components'

export default function Materail() {
  const { componentConfig } = useComponentConfigStore()
  // 过滤掉 Page,只展示可用组件
  const components = useMemo(() => {
    return Object.values(componentConfig).filter(item => item.name !== 'Page')
  }, [componentConfig])

  return (
    <div>
      {components.map((item, index) => {
        return <MaterialItem key={item.name + index} name={item.name} />
      })}
    </div>
  )
}

详细解读

  • useComponentConfigStore 获取全局组件配置,数据驱动,灵活扩展。
  • useMemo 优化性能,只有组件配置变化时才重新计算列表,避免无谓渲染。
  • 过滤掉"Page"组件,防止误操作。
  • 遍历生成 MaterialItem,每个都是可拖拽的"商品"。
  • 生活比喻:Material 就像超市货架,琳琅满目的商品(组件)任你挑选,别忘了带购物车哦!🛒

MaterialItem:拖拽小能手

tsx 复制代码
// src/editor/components/MaterialItem/index.tsx
import React from 'react'
import { useDrag } from 'react-dnd'

export interface MaterialItemProps {
  name: string
}

export default function MaterialItem(props: MaterialItemProps) {
  const [_, dragRef] = useDrag(() => ({
    type: props.name,
    item: {  // 被拖动的内容
      type: props.name
    }
  }))
  return (
    <div
      ref={dragRef as any}
      className='
        border-dashed
        border-[1px]
        border-[#000]
        py-[8px]
        px-[10px]
        inline-block
        bg-white
        m-[10px]
        cursor-move
        hover:bg-[#ccc]
      '
    >
      {props.name}
    </div>
  )
}

详细解读

  • useDrag 来自 react-dnd,赋予组件"可拖拽"能力,拖着组件满场飞,开发体验+100!🚀
  • type 标识拖拽类型,保证拖拽时能正确识别。
  • dragRef 绑定到 div 上,鼠标拖动时就像"购物车"把商品带走。
  • 样式设计突出"可拖拽"感,鼠标悬停变色,用户体验 up!
  • 生活比喻:MaterialItem 就像超市里的商品,每个都能被"购物车"(鼠标)拖走,随时加入你的开发"购物篮"。🧺

3. 结构大纲------Outline 🌳

tsx 复制代码
// src/editor/components/Outline/index.tsx
import React from 'react'
import { useComponentsStore } from '../../stores/components'
import { DownOutlined } from '@ant-design/icons';
import { Tree } from 'antd';

export default function Outline() {
    const { components, setCurComponentId } = useComponentsStore((state) => state)
    return (
        <div>
            <Tree
                defaultExpandAll
                switcherIcon={<DownOutlined />}
                showLine
                fieldNames={{title: 'desc', key: 'id'}}
                treeData={components as any}
                onSelect={([selectedKey], info) => {
                    setCurComponentId(Number(selectedKey))
                }}
            />
        </div>
    )
}

详细解读

  • Tree 组件展示组件层级结构,像"家谱树"一样清晰,谁是谁的"爸爸"一目了然。👨‍👩‍👧‍👦
  • defaultExpandAll 默认全部展开,避免用户频繁点击。
  • fieldNames 映射数据字段,灵活兼容不同数据结构。
  • onSelect 选中节点时,更新当前组件 id,实现"点谁谁高亮"。
  • 生活比喻:Outline 就像"家谱树",让你一眼看清组件的"祖孙三代",再也不怕迷路。

4. 源码预览------Source 📝

tsx 复制代码
// src/editor/components/Source/index.tsx
import React from 'react'
import MonacoEditor from '@monaco-editor/react'
import { useComponentsStore } from '../../stores/components'

export default function Source() {
  const { components } = useComponentsStore()
  return (
    <MonacoEditor
      height={'100%'}
      language="json"
      path='components.json'
      value={JSON.stringify(components, null, 2)}
    />
  )
}

详细解读

  • MonacoEditor 集成 VSCode 编辑器,所见即所得,开发者的"福音"。🎉
  • 实时展示组件树 JSON,方便开发者调试和导出。
  • 生活比喻:Source 就像"X光片",让你看清组件的"骨骼"结构,哪里有问题一目了然。

5. 效果展示


四、总结:物料区,让开发像搭乐高一样快乐 🧩

物料区通过组件化、数据驱动和多视图切换,把复杂的组件管理变成了"搭积木"。无论是拖拽、结构梳理还是源码预览,都让开发体验变得轻松有趣。下次你在低代码平台里拖组件时,别忘了,这背后藏着一套"快乐星球"的魔法工坊哦!✨


项目所有代码均已整理至以下仓库,方便大家查看与使用:

代码仓库地址内附项目体验地址

相关推荐
To_OC5 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic6 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy6 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志6 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble7 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯8 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜9 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司9 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g10 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森10 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http