MUI Box 组件有啥用?

Posted

技术标签:

【中文标题】MUI Box 组件有啥用?【英文标题】:What is the MUI Box component for?MUI Box 组件有什么用? 【发布时间】:2020-06-12 13:43:09 【问题描述】:

尽我所能,我无法理解here 给出的描述。

Box 组件用作大多数 CSS 实用程序需求的包装器组件。

CSS 实用程序需要什么?

这个组件的用例是什么?它解决了什么问题?你是怎么用的?

我发现 MUI 文档非常有限且难以理解。我用谷歌搜索过,但通常只找到关于如何使用 Material UI 的相当轻量级的博客文章。除了帮助理解这个组件之外,我真的很感谢任何好的资源(如果存在这样的东西的话,就像他们自己的文档的更好版本一样)。

(背景,我一般了解React、JS、CSS、html等,后两者实力稍逊)。

【问题讨论】:

【参考方案1】:

Box 就是这样一个盒子。它是一个包裹在其内容周围的元素,它本身不包含样式规则,也不会对视觉输出产生任何默认效果。但它是根据需要放置样式规则的地方。它不提供任何实际功能,只是用于控制分层标记结构中的样式的占位符。

从结构上讲,它导致<div>

我经常认为它在语义上类似于 JSX 空元素:

<>
  Some elements here
</>

因为它用于对事物进行分组。但它会生成&lt;div&gt;,并且可以包含一些 Material UI 功能:

<Box className=classes.someStyling>
  Some elements here
</Box>

【讨论】:

感谢您的详细说明。我还是不明白。它从根本上来说是一种用于设置其他 Material-UI(或普通 React)元素样式的机制吗?为什么要在 中包装一些其他元素? @XavierTaylor:您目前可能确实没有理由包装您的任何元素。如果我有几个要组合在一起的兄弟元素并将样式应用于分组,我会将它们包装在Box 中。如果我有一个复杂的 UI 设置,我需要嵌套元素来执行一些 CSS 技巧(例如背景和文本之间的透明效果),那么我会使用 Box 作为父容器元素,因为它不应用除默认样式之外的其他样式我明确告诉它的。 这个答案可能会产生误导,Box 实际上会在 DOM 中呈现一个 div,而 `>" 代表一个未在 DOM 中呈现的 React Fragment,它仅在您需要时使用包装多个元素,因为您只能在 JSX 中返回单个元素【参考方案2】:

Material UI 中的 Box 组件有很多有用的东西

最重要的是 box 元素默认内置了 material-ui/system 功能,这意味着如果您将其用作包装器,您可以将系统功能应用于您需要的东西

像这个例子:

<Box bgcolor="primary.main" color="primary.contrastText" p=2>
  primary.main
</Box>

你可以根据自己的喜好添加css类

它提供的另一个好用的东西可以在其他组件中变形,并且非常有助于将系统功能应用于它

像这个例子:

<Typography component="div" variant="body1">
  <Box color="primary.main">primary.main</Box>
</Typography>

上面的两个例子都是我从文档中提取的 您可以在此链接中找到它们:here

你可以找到我所说的材料ui系统功能的意思:here

注意:您可以将任何材料 ui 系统功能添加到任何组件,例如 docs here,但我建议您使用 box 组件扭曲您需要的东西,这会让生活变得更轻松

【讨论】:

【参考方案3】:

编辑:这是在 MUI v4 时代编写的。在 MUI v5 中,所有 MUI 组件都允许您通过 sx 属性定义 CSS 样式,而不仅仅是 Box;但Box 也接受顶层的样式道具,以及sx 内的样式。

其他答案并不能真正解释使用Box 的动机。

Box 渲染一个 &lt;div&gt; 你可以通过 React props 直接应用 CSS 样式,为了方便起见,因为像单独的 CSS 文件、CSS-in-JS 或内联样式这样的替代方案可能会更加打字和麻烦使用。

例如,考虑这个使用 JSS 的组件:

import * as React from 'react'

import  makeStyles  from '@material-ui/styles'

const useStyles = makeStyles(theme => (
  root: 
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    padding: theme.spacing(1),
  
))

const Example = (children, ...props) => 
  const classes = useStyles(props);

  return (
    <div className=classes.root>
      children
    </div>
  )

使用Box 传递您想要的道具来执行此操作要短得多:

import * as React from 'react'

import Box from '@material-ui/core/Box'

const Example = (children) => (
  <Box display="flex" flexDirection="column" alignItems="stretch" padding=1>
    children
  </Box>
)

还要注意padding=1theme.spacing(1) 的简写。 Box 为使用这样的 Material-UI 主题提供了各种便利。

在较大的文件中,从渲染元素到样式之间来回跳转可能比在元素上正确存在样式时更麻烦。

不想使用Box (MUI v4) 的情况:

您希望封闭组件能够通过传递 classes 来覆盖样式(makeStyles 启用此功能。&lt;Example classNames= root: 'alert' /&gt;makeStyles 示例中有效,但在 Box 示例中无效。) 您需要使用重要的选择器(例如 JSS 选择器:$root &gt; li &gt; a$root .third-party-class-name

【讨论】:

对于material-ui v5,Box 将会改变。 所以如果我理解正确,如果我不使用/传入display="flex" padding=1 等CSS 样式的东西,我可以只使用普通的olediv?除了少打字和利用预制的东西(bgcolor="primary.main"theme.spacing(1)1 或其他任何东西),为什么有人会这样做?!它还使用 CSS 样式使结构混乱。内联 CSS 是不是不鼓励,这基本上就是这样?!? @reddtoric 这真的取决于你的目标。如果您希望设计团队能够在不乱写代码的情况下编辑 UI 外观,那就太糟糕了。如果您拥有所有的编码人员并且不希望单独的设计团队,那么与内联 CSS 相比,在 JSX 和 CSS 之间来回切换可能不值得浪费精力时间。 我在哪里可以找到像这样记录的东西? MUI documentation 显然仅在您已经知道要使用哪个组件时才解释如何使用这些组件,而不是出于什么目的使用它们。 其实有这个页面:material-ui.com/system。这实际上是我第一次了解Box【参考方案4】:

Box 基本上是类固醇上的div*。 Box 允许您将动态样式应用于其他正常的 div 非常快,就像内联样式(但它不是内联样式)。除此之外,它还与 MUI 主题进行了一流的集成:

<Box
  sx=
    bgcolor: 'primary.main',
    color: 'text.secondary',
    border: 4,
    borderRadius: 2,
    px: 2,
    fontWeight: 'fontWeightBold',
    zIndex: 'tooltip',
    boxShadow: 8,
  
>
  Box
</Box>

如果您需要使用普通的div 执行上述操作,则必须使用useTheme 挂钩获取theme 对象并创建一个内联样式,如果到处滥用这不是一个好习惯:

<div
  style=
    backgroundColor: theme.palette.primary.main,
    color: theme.palette.text.secondary,
    border: '4px solid black',
    borderRadius: theme.shape.borderRadius * 2,
    padding: `0 $theme.spacing(2)`,
    fontWeight: theme.typography.fontWeightBold,
    zIndex: theme.zIndex.tooltip,
    boxShadow: theme.shadows[8],
  
>
  div
</div>

Box 以及 TypographyStack 等其他组件还支持 system properties,它允许您将样式值传递给*** props,从而使代码更短。在内部,系统属性被收集并与sx 属性合并,因此它们是相同的(有关更多详细信息,请参阅this 答案)

<Box
  bgcolor="primary.main"
  color="text.secondary"
  border=4
  borderRadius=2
  px=2
  fontWeight="fontWeightBold"
  zIndex="tooltip"
  boxShadow=8
>
  Box
</Box>

因为Box 利用了sx 属性,您还可以使用sx 功能,例如添加responsive values:

<Box
  display=
    xs: 'none',
    sm: 'block',
  
  width=
    sm: 30,
    md: 50,
    lg: 100,
  
>

或者创建嵌套样式:

<Box
  display='flex'
  sx=
    '& > :not(:last-child)': 
      mr: 2 // maginRight: theme.spacing(2)
    ,
    ':hover': 
      bgcolor: 'green'
    
  
>
什么时候使用Box
当您想在原型制作时快速创建样式 div。 当您想要创建在其他任何地方都不能真正重复使用的一次性内联样式时。当您想要修复布局的特定部分中的某些问题时,这很方便。 当您想要添加动态或响应式样式并同时使您的代码更易于理解时,因为所有内容都定义在一个地方,而且sx 语法非常紧凑。 当您想要引用多个 MUI 主题属性时,因为许多 sx 属性是开箱即用的主题感知。
什么时候使用Box?
当您不需要设置任何样式时。只需使用普通的div 即可。 当您在高度可重用的组件(如列表项、网格项或表格单元格)中使用它时。这是因为sx prop 的性能最慢(2x slower than the second slowest approach) 当您使用其他 MUI 组件时。在 v5 中,来自 MUI 的所有组件都支持 sx,因此如果您只想设置其他 MUI 组件的样式,则无需使用 Box 作为包装器或根组件。

*:默认情况下Boxdiv,但您可以覆盖它的根组件。例如:&lt;Box component='span'&gt;

【讨论】:

以上是关于MUI Box 组件有啥用?的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 中的子组件有啥用,为啥要创建子组件?

如果我们不能从父组件更改属性或操作它们,@ViewChild 有啥用?

visualstudio的unity组件有啥用

Unity3d 中MeshCollider组件下convex勾选有啥用?

qt中的“morph into”有啥用?

Vue 中的 .sync 修饰符有啥用