使用react-sizeme解决react-grid-layout中侧栏(抽屉)展开或隐藏时不会自适应容器大小的问题
创始人
2024-03-01 11:59:03
0

文章目录

    • 使用react-sizeme解决react-grid-layout中侧栏(抽屉)展开或隐藏时不会自适应容器大小的问题
      • 前提概要
      • 问题代码
      • 解决代码
      • 参考

使用react-sizeme解决react-grid-layout中侧栏(抽屉)展开或隐藏时不会自适应容器大小的问题

前提概要

在上一篇博文中,我们讲到了使用react-grid-layoutecharts-for-react实现一个自定义的dashboar页面
《使用react-grid-layout和echarts-for-react实现一个支持拖拽的自定义响应式dashboard页面》

问题代码

import React, {useState} from "react";
import 'react-grid-layout/css/styles.css'
import 'react-resizable/css/styles.css'
import {Button} from "antd";
import {findIndex, uniqueId} from "lodash";
import './dashboard.css'
import WidgetLoadingSpin from "@/pages/Dashboard/Detail/WidgetLoadingSpin";
import {CloseOutlined, LockOutlined, QuestionCircleOutlined, UnlockOutlined} from "@ant-design/icons";
import RGL, {Layout, WidthProvider} from "react-grid-layout";
import {cloneDeep} from "lodash-es";
const BarChartWidgetLazy = React.lazy(() => import('@/pages/Dashboard/Detail/Widget/BarChartWidget'));
const PieChartWidgetLazy = React.lazy(() => import('@/pages/Dashboard/Detail/Widget/PieChartWidget'));
const ReactGridLayout = WidthProvider(RGL);
interface DashboardWidgetInfo {widgetName: string,layout: Layout
}
function DashboardGird() {const [widgets, setWidgets] = useState([]);const getLayouts: any = () => {return cloneDeep(widgets.map(item => item.layout));}const setLayoutStatic = (widget: DashboardWidgetInfo, staticFlag: boolean) => {const index = findIndex(widgets, (w: any) => w.widgetName === widget.widgetName);if (index !== -1) {const updateWidget = widgets[index];updateWidget.layout.static = staticFlag;widgets.splice(index, 1, {...updateWidget});const newWidgets = [...widgets];setWidgets(newWidgets);}}const lockWidget = (widget: DashboardWidgetInfo) => {setLayoutStatic(widget, true);}const unlockWidget = (widget: DashboardWidgetInfo) => {setLayoutStatic(widget, false);}const onRemoveWidget = (widget: DashboardWidgetInfo) => {const widgetIndex = findIndex(widgets, (w: any) => w.layout.i === widget.layout.i);if (widgetIndex !== -1) {widgets.splice(widgetIndex, 1);const newWidgets = [...widgets];setWidgets(newWidgets);}}const getWidgetComponent = (widgetName: string) => {if (widgetName === 'PieChartWidget') { //可以改成策略return (}>);} else {return (}>);}}const createWidget = (widget: DashboardWidgetInfo) => {return (
'dashboard-widget-wrapper'} key={widget.layout.i} data-grid={widget.layout}>'dashboard-widget-header-icon'}/>{widget.layout.static ? 'dashboard-widget-header-icon'} onClick={() => unlockWidget(widget)}/> : ('dashboard-widget-header-icon'} onClick={() => lockWidget(widget)}/>)}'dashboard-widget-header-icon'} onClick={() => onRemoveWidget(widget)}/>{getWidgetComponent(widget.widgetName)}
);}const onAddWidget = () => {const x = (widgets.length * 3) % 12;const widgetName = x % 2 == 0 ? 'BarChartWidget' : 'PieChartWidget'const newWidgets = [...widgets, {widgetName: widgetName,layout: {i: uniqueId(widgetName), x: x, y: Infinity, w: 3, h: 2, static: false}}] as DashboardWidgetInfo[];setWidgets(newWidgets);}const onLayoutChange = (layouts: any[]) => {for (const layout of layouts) {const updateIndex = findIndex(widgets, (w) => w.layout.i === layout.i);if (updateIndex !== -1) {const updateWidget = widgets[updateIndex];updateWidget.layout = {...layout,};widgets.splice(updateIndex, 1, {...updateWidget});}}const newWidgets = [...widgets];setWidgets(newWidgets);}return (<>12}rowHeight={100}autoSize={true}isDraggable={true}isResizable={true}isBounded={true}layout={getLayouts()}className={'layouts'}onLayoutChange={onLayoutChange}>{widgets?.map(item => createWidget(item))}); } export default DashboardGird

最终效果可以看到,当我们侧栏(抽屉)移动时并不会自动帮我们调整react-grid-layout中元素的占位,也就是在最右边我们可以看到,当侧栏(抽屉)隐藏的时候,最右边是有空白的,并不会自适应填充。

请添加图片描述

那其实在官网中给出了解决方案:https://github.com/react-grid-layout/react-grid-layout

Have a more complicated layout? WidthProvider is very simple and only listens to window ‘resize’ events. If you need more power and flexibility, try the SizeMe React HOC as an alternative to WidthProvider.

react-grid-layout中提供的WidthProvider只是很简单的监听了浏览器窗口’resize’的事件,根本没办法监听到当前容器大小更变的事件,所以我们需要react-sizeme来帮助我们知道当前容器的大小

所以我们需要首先npm install react-sizeme,然后我们就可以使用了。这里就不过多介绍如何使用,直接给出解决的代码

解决代码

import React, {useState} from "react";
import 'react-grid-layout/css/styles.css'
import 'react-resizable/css/styles.css'
import {Button} from "antd";
import {findIndex, uniqueId} from "lodash";
import './dashboard.css'
import WidgetLoadingSpin from "@/pages/Dashboard/Detail/WidgetLoadingSpin";
import {CloseOutlined, LockOutlined, QuestionCircleOutlined, UnlockOutlined} from "@ant-design/icons";
import ReactGridLayout from "react-grid-layout";
import {cloneDeep} from "lodash-es";
import {withSize} from 'react-sizeme';
const BarChartWidgetLazy = React.lazy(() => import('@/pages/Dashboard/Detail/Widget/BarChartWidget'));
const PieChartWidgetLazy = React.lazy(() => import('@/pages/Dashboard/Detail/Widget/PieChartWidget'));
interface DashboardWidgetInfo {widgetName: string,layout: ReactGridLayout.Layout
}
function DashboardGird({ size: { width } }: any) {const [widgets, setWidgets] = useState([]);const getLayouts: any = () => {return cloneDeep(widgets.map(item => item.layout));}const setLayoutStatic = (widget: DashboardWidgetInfo, staticFlag: boolean) => {const index = findIndex(widgets, (w: any) => w.widgetName === widget.widgetName);if (index !== -1) {const updateWidget = widgets[index];updateWidget.layout.static = staticFlag;widgets.splice(index, 1, {...updateWidget});const newWidgets = [...widgets];setWidgets(newWidgets);}}const lockWidget = (widget: DashboardWidgetInfo) => {setLayoutStatic(widget, true);}const unlockWidget = (widget: DashboardWidgetInfo) => {setLayoutStatic(widget, false);}const onRemoveWidget = (widget: DashboardWidgetInfo) => {const widgetIndex = findIndex(widgets, (w: any) => w.layout.i === widget.layout.i);if (widgetIndex !== -1) {widgets.splice(widgetIndex, 1);const newWidgets = [...widgets];setWidgets(newWidgets);}}const getWidgetComponent = (widgetName: string) => {if (widgetName === 'PieChartWidget') { //可以改成策略return (}>);} else {return (}>);}}const createWidget = (widget: DashboardWidgetInfo) => {return (
'dashboard-widget-wrapper'} key={widget.layout.i} data-grid={widget.layout}>'dashboard-widget-header-icon'}/>{widget.layout.static ? 'dashboard-widget-header-icon'} onClick={() => unlockWidget(widget)}/> : ('dashboard-widget-header-icon'} onClick={() => lockWidget(widget)}/>)}'dashboard-widget-header-icon'} onClick={() => onRemoveWidget(widget)}/>{getWidgetComponent(widget.widgetName)}
);}const onAddWidget = () => {const x = (widgets.length * 3) % 12;const widgetName = x % 2 == 0 ? 'BarChartWidget' : 'PieChartWidget'const newWidgets = [...widgets, {widgetName: widgetName,layout: {i: uniqueId(widgetName), x: x, y: Infinity, w: 3, h: 2, static: false}}] as DashboardWidgetInfo[];setWidgets(newWidgets);}const onLayoutChange = (layouts: any[]) => {for (const layout of layouts) {const updateIndex = findIndex(widgets, (w) => w.layout.i === layout.i);if (updateIndex !== -1) {const updateWidget = widgets[updateIndex];updateWidget.layout = {...layout,};widgets.splice(updateIndex, 1, {...updateWidget});}}const newWidgets = [...widgets];setWidgets(newWidgets);}return (
12}rowHeight={100}width={width}autoSize={true}isDraggable={true}isResizable={true}isBounded={true}layout={getLayouts()}className={'layouts'}onLayoutChange={onLayoutChange}>{widgets?.map(item => createWidget(item))}
); } export default withSize({ refreshMode: 'debounce', refreshRate: 60 })(DashboardGird);

接下来我们来看看效果

请添加图片描述

这样我们就通过react-sizeme解决react-grid-layout中侧栏(抽屉)移动时不会调整大小的问题了

参考

react-sizeme: 让你的React Components知道它们的宽度和高度!

Tired of Boring Static Dashboards? Let’s Build a Fully Customizable Dashboard in React

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...