当前位置:首页 > 科技  > 软件

Next-Admin最佳实践!支持可视化拖拽模块

来源: 责编: 时间:2024-04-26 17:29:04 226观看
导读模块演示图片技术实现拖拽模块我采用了 movable, 并研究了它的大量 API,最终实现了我想要的效果,当然我还设计了一套数据结构,如果大家对可视化搭建感兴趣,也可以扩展成自己的拖拽搭建结构。图片元素多选我采用了 selecto

模块演示

图片图片tzQ28资讯网——每日最新资讯28at.com

技术实现

拖拽模块我采用了 movable, 并研究了它的大量 API,最终实现了我想要的效果,当然我还设计了一套数据结构,如果大家对可视化搭建感兴趣,也可以扩展成自己的拖拽搭建结构。tzQ28资讯网——每日最新资讯28at.com

图片图片tzQ28资讯网——每日最新资讯28at.com

元素多选我采用了 selecto 模块,成组管理器我采用了 @moveable/helper, 当然在使用这些库的时候也踩了不少坑,好在已经完美解决。tzQ28资讯网——每日最新资讯28at.com

下面分享一个简单的数据结构,以支持我们的元素自由搭建:tzQ28资讯网——每日最新资讯28at.com

const schema = {    "Button": {        id: 'wep_001',        name: 'Button',        type: 'base', // 基础类型组件        base: {            width: 120,            height: 36,            transform: 'translate(100px,100px)'        }    },    "Image": {        id: 'wep_002',        name: 'Image',        type: 'base', // 基础类型组件        base: {            width: 120,            height: 120,            url: '',            transform: 'translate(300px,160px)'        }    }}export default schema

工具条实现

图片图片tzQ28资讯网——每日最新资讯28at.com

对于工具条的实现,我做了统一的封装,以便后期可能更低成本的维护和管理:tzQ28资讯网——每日最新资讯28at.com

  • config 工具条配置
  • actions 工具条选项对应的功能方法

接下来看看工具条的配置:tzQ28资讯网——每日最新资讯28at.com

const toolbar = {    base: [        {            key: 'group',            icon: <GroupOutlined />,            text: '成组',        },        {            key: 'ungroup',            icon: <UngroupOutlined />,            text: '取消成组'        },        {            key: 'left',            icon: <AlignLeftOutlined />,            text: '左对齐'        },        // ... 其他工具条配置        {            key: 'v-space',            icon: <PicCenterOutlined />,            text: '垂直分布空间'        },        {            key: 'h-space',            icon: <PicCenterOutlined style={{transform: 'rotate(-90deg)'}} />,            text: '水平分布空间'        },            ]}

工具条方法封装:tzQ28资讯网——每日最新资讯28at.com

const handleOperate = (key: string) => {        // ... some function        // 顶对齐实现        if(key === 'top') {            const rect = moveableRef.current!.getRect();            // console.log(rect)            const moveables = moveableRef.current!.getMoveables();            if (moveables.length <= 1) {                return;            }            moveables.forEach(child => {                child.request<DraggableRequestParam>("draggable", {                    y: rect.top,                }, true);            });            moveableRef.current?.updateRect();            return        }        // 底对齐        if(key === 'bottom') {            const rect = moveableRef.current!.getRect();            const moveables = moveableRef.current!.getMoveables();            if (moveables.length <= 1) {                return;            }            moveables.forEach(child => {                child.request<DraggableRequestParam>("draggable", {                    y: rect.top + rect.height - (child.props?.target ? (child.props.target as any).offsetHeight : 0),                }, true);            });            moveableRef.current?.updateRect();            return        }        // ... 其他工具条方法        // 水平分布        if(key === 'h-space') {            const groupRect = moveableRef.current!.getRect();            const moveables = moveableRef.current!.getMoveables();            let left = groupRect.left;            if (moveables.length <= 1) {                return;            }            const gap = (groupRect.width - groupRect.children!.reduce((prev, cur) => {                return prev + cur.width;            }, 0)) / (moveables.length - 1);            moveables.sort((a, b) => {                return a.state.left - b.state.left;            });            moveables.forEach(child => {                const rect = child.getRect();                child.request<DraggableRequestParam>("draggable", {                    x: left,                }, true);                left += rect.width + gap;            });            moveableRef.current?.updateRect();            return        }    }

通过以上的封装方式我们就能轻松扩展自己的工具条啦~tzQ28资讯网——每日最新资讯28at.com

接下来我们看看工具条实现的效果:tzQ28资讯网——每日最新资讯28at.com

图片图片tzQ28资讯网——每日最新资讯28at.com

当然代码我已经提交到 github 上了, 大家感兴趣可以参考研究一下。tzQ28资讯网——每日最新资讯28at.com

开源地址:https://github.com/MrXujiang/next-admintzQ28资讯网——每日最新资讯28at.com

多选 & 成组实现

图片图片tzQ28资讯网——每日最新资讯28at.com

下面直接上代码:tzQ28资讯网——每日最新资讯28at.com

<Selecto    ref={selectoRef}    // dragCnotallow={container.current}    selectableTargets={[".wep-area .cube"]}    hitRate={0}    selectByClick={true}    selectFromInside={false}    toggleCnotallow={["shift"]}    ratio={0}    notallow={e => {        const moveable = moveableRef.current!;        const target = e.inputEvent.target;        const flatted = deepFlat(targets);        if (            target.tagName === "BUTTON"            || moveable.isMoveableElement(target)            || flatted.some(t => t === target || t.contains(target))        ) {            e.stop();        }        e.data.startTargets = targets;    }}    notallow={e => {        const {            startAdded,            startRemoved,            isDragStartEnd,        } = e;        if (isDragStartEnd) {            return;        }        const nextChilds = groupManager.selectSameDepthChilds(            e.data.startTargets,            startAdded,            startRemoved,        );        setSelectedTargets(nextChilds.targets());    }}    notallow={e => {        const {            isDragStartEnd,            isClick,            added,            removed,            inputEvent,        } = e;        const moveable = moveableRef.current!;        if (isDragStartEnd) {            inputEvent.preventDefault();            moveable.waitToChangeTarget().then(() => {                moveable.dragStart(inputEvent);            });        }        let nextChilds: TargetList;        if (isDragStartEnd || isClick) {            if (isCommand) {                nextChilds = groupManager.selectSingleChilds(targets, added, removed);            } else {                nextChilds = groupManager.selectCompletedChilds(targets, added, removed, isShift);            }        } else {            nextChilds = groupManager.selectSameDepthChilds(e.data.startTargets, added, removed);        }        e.currentTarget.setSelectedTargets(nextChilds.flatten());        setSelectedTargets(nextChilds.targets());    }}></Selecto>

完整代码都同步到 Next-Admin 了, 如果大家感兴趣也可以研究一下。tzQ28资讯网——每日最新资讯28at.com

tzQ28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-85858-0.htmlNext-Admin最佳实践!支持可视化拖拽模块

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 每位开发者都需要知道的七个Django命令

下一篇: Go 语言入门指南:基础语法和常用特性解析

标签:
  • 热门焦点
  • 石头智能洗地机A10 Plus体验:双向自清洁治好了我的懒癌

    一、前言和介绍专为家庭请假懒人而生的石头科技在近日又带来了自己的全新旗舰新品,石头智能洗地机A10 Plus。从这个产品名上就不难看出,这次石头推出的并不是常见的扫地机器
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • 6月iOS设备性能榜:M2稳居榜首 A系列只能等一手3nm来救

    没有新品发布,自然iOS设备性能榜的上榜设备就没有什么更替,仅仅只有跑分变化而产生的排名变动,毕竟苹果新品的发布节奏就是这样的,一年下来也就几个移动端新品,不会像安卓厂商,一
  • 6月安卓手机性能榜:vivo/iQOO霸占旗舰排行榜前三

    2023年上半年已经正式过去了,我们也迎来了安兔兔V10版本,在新的骁龙8Gen3和天玑9300发布之前,性能榜的榜单大体会以骁龙8Gen2和天玑9200+为主,至于那颗3.36GHz的骁龙8Gen2领先
  • 太卷!Redmi MAX 100英寸电视便宜了:12999元买Redmi史上最大屏

    8月5日消息,从小米商城了解到,Redmi MAX 100英寸巨屏电视日前迎来官方优惠,到手价12999元,比发布价便宜了7000元,在大屏电视市场开卷。据了解,Redmi MAX 100
  • 一文看懂为苹果Vision Pro开发应用程序

    译者 | 布加迪审校 | 重楼苹果的Vision Pro是一款混合现实(MR)头戴设备。Vision Pro结合了虚拟现实(VR)和增强现实(AR)的沉浸感。其高分辨率显示屏、先进的传感器和强大的处理能力
  • 服务存储设计模式:Cache-Aside模式

    Cache-Aside模式一种常用的缓存方式,通常是把数据从主存储加载到KV缓存中,加速后续的访问。在存在重复度的场景,Cache-Aside可以提升服务性能,降低底层存储的压力,缺点是缓存和底
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 冯提莫签约抖音公会 前“斗鱼一姐”消失在直播间

    来源:直播观察提起&ldquo;冯提莫&rdquo;这个名字,很多网友或许听过,但应该不记得她是哪位主播了。其实,作为曾经的&ldquo;斗鱼一姐&rdquo;,冯提莫在游戏直播的年代影响力不输于现
Top