使用 SASS 类覆盖 Material UI 组件
Posted
技术标签:
【中文标题】使用 SASS 类覆盖 Material UI 组件【英文标题】:Override Material UI component with SASS classes 【发布时间】:2018-09-02 07:13:07 【问题描述】:我正在使用 Material UI 组件,但想将我的所有样式移动到 .scss
文件中。目前,我在使用 Material UI 组件的同一个 javascript 文件中有一个大型样式对象。此样式对象通过 style
属性传递给 Material UI 组件。在我看来,这或多或少只是内联样式,我的目标是消除这种模式。我在这些 Material UI 组件中有其他嵌套组件(Material UI 组件以及自定义 React 组件)。这是我正在使用的示例:
const styles= //all my css styles in here
<TableRowColumn key=index style=styles.column>
<span className="checkbox-thing">
<input
....
/>
</span>
</TableRowColumn>
我已经参考了覆盖文档:https://material-ui-next.com/customization/overrides/
还有这个 Stack Overflow 问题:How to style material ui next components with styled components and SASS
在我看来,这两个都没有明确说明如何使用外部.scss
(样式所在的位置)并将该文件中的类名引用到 Material UI 组件中。我只是为了能够做这样的事情,目前使用普通的 html 元素很容易做到这一点:
<input
type="checkbox"
checked=
this.props.isChecked
className="someClassInTheSCSSFile"
/>
总之我想:
将我的大型样式对象移除到单独的类中,放入.scss
文件中
在.scss
文件中引用一个类并将其弹出到 Material UI 组件中
【问题讨论】:
【参考方案1】:我不知道为什么它现在开始工作,而不是我之前尝试过的时候,但使用 className="someClassInTheSCSSFile"
最终工作,只要我的 .scss
文件包含类似的内容:
//.scss file
.someClassInTheSCSSFile
color: blue;
//rest of the styles go here
总之,直接在 MATERIAL UI 组件中使用 className
属性是可行的。因此,使用我的问题中的示例代码可以实现以下工作:
//Javascript file
<TableRowColumn key=index className="someClassInTheSCSSFile">
<span className="checkbox-thing">
<input
....
/>
</span>
</TableRowColumn>
现在,真正有趣(但令人失望)的是当您想将值传递给 CSS 时。例如,假设这个TableRowColumn
组件有一个width
属性,但我不想将它硬编码到我的.scss
文件中。坚持我不使用任何内联样式的模式,这是一个挑战。让我们说这个TableRowColumn
组件在一个函数内部,该函数接受一个名为colWidth
的参数。当调用该函数时,我想将这个colWidth
值动态传递到我的这个TableRowColumn
组件的css width
属性中。然而,据我所知,这最终成为目前不可能完成的任务。可以做的是:
//Javascript File
<TableRowColumn key=index style=width:`$coldWidth` className="someClassInTheSCSSFile">
<span className="checkbox-thing">
<input
....
/>
</span>
</TableRowColumn>
但这是内联样式。正是我试图避免的。所以现在,我最终拥有了内联样式和引用我的.scss
文件的className
。可以说更加笨重和繁重。如果我在.scss
中使用attr()
函数怎么样?好吧,根据 MDN (https://developer.mozilla.org/en-US/docs/Web/CSS/attr),这将只支持传递的字符串,而主流浏览器不支持所有其他类型。哎哟。请参阅此代码笔 (https://jsfiddle.net/hmr0hckf/131/) 以获取此操作的示例。故事的寓意是,对于我想要动态更改值的任何 css 属性,我都坚持使用内联样式。
【讨论】:
【参考方案2】:带有 node-sass 和 sass-loader 的 Webpack
你已经很接近了。像往常一样,将所有样式放入一个或多个 .scss 文件中。例如,一个名为“nodeContent”的类。
.nodeContent
position: absolute;
top: 0;
bottom: 0;
display: flex;
align-items: center;
您需要做的就是导入您的样式并访问类名作为您的样式对象的属性。请参阅下面的示例,我在与我的组件相同的目录中有一个名为 styles.scss
的 Sass 文件。在我的组件中,我可以像这样导入它们:
import * as styles from './styles.scss'
样式是一个对象,我可以像引用对象的任何其他属性一样引用我的类。因此,如果我想在材质组件上使用 nodeContent 类,我可以这样做:
<Card className=styles.nodeContent />
不使用 webpack(不是 100% 确定)
我认为您可以将 .scss 文件编译为 .css 并将它们作为 index.html 文件中的 a 引用。之后,我认为您应该能够像上面显示的那样将 classNames 引用为字符串。 这是我刚刚读到的类似的文章,除了它们在其组件中导入 css 文件:https://hackernoon.com/using-sass-with-create-react-app-without-ejecting-b5f4f827ed9e
【讨论】:
这样直接导入我的.scss
就是给我一个404
嗯...有趣。你在用 webpack 吗?
我没有使用 webpack
我明白了。我假设您正在使用带有 node-sass 和 sass-loader 的 webpack,我的错。在您的情况下,我认为您可以将 .scss 文件编译为 .css 并将它们作为 index.html 文件中的 引用。之后,我认为您应该能够像上面显示的那样将 classNames 引用为字符串。这是我刚刚读到的类似的文章,只是它们在其组件中导入了 css 文件。 hackernoon.com/…
参考我更新的答案。结果很失望,还是谢谢你。以上是关于使用 SASS 类覆盖 Material UI 组件的主要内容,如果未能解决你的问题,请参考以下文章
让 svelte-material-ui 与 snowpack 和 sass 一起使用
设置 Material UI 套件 React 时,Sass-Loader 的模块构建失败
javascript 版本0.x的Material-UI排版(基于SASS和CSS模块)