【问题标题】:Load SCSS file dynamically on button click单击按钮时动态加载 SCSS 文件
【发布时间】:2018-02-14 19:41:39
【问题描述】:

如您所见,我为整个项目加载了一个 scss 文件,我想知道是否可以通过单击按钮更改加载的 scss 文件。请记住,此 scss 文件适用于根组件,但我将把按钮放在它的孙子组件上。

我已经尝试了一些事情,但问题显然是除了通过导入之外没有其他方法来属性 scss 文件(这是在 /Components/App.jsx 中):

import '../scss/app.scss';
//import '../scss/darcula.scss'; for dark theme.

如果我取消上面的注释,导入的 scss 是 darcula,但我无法动态更改我知道的导入集。

一个可接受的解决方案是在子级中发生的触发单独导入,它不会完全替换其他文件,而是仅取代每个重新定义的样式,允许我只更改颜色以获得我想要的“夜间模式”按钮.

我不明白为什么不能在 ifs 中隔离 requires 即使我这样做:

turnLightsOnOff() {
    if (this.state.theme) {
        require('../../../scss/app.scss');
        this.setState({
            theme: false,
        });
    } else {
        //require('../../../scss/darcula.scss');
        this.setState({
            theme: true,
        });
    }
}

app.css 已加载,即使条件尚未满足

如果我取消注释另一行,则两个 scss 都会一个接一个地加载。

【问题讨论】:

  • 不知道如何实现,只是一个简单的建议;为什么不直接使用 className 作为应用程序的主题?类似<App className={this.props.theme} />
  • 我不明白我几乎只使用 className 而不是 id。除了给 div 一个我缺少的 .class 之外,还有什么特殊的 className 功能吗?
  • 抱歉,我的评论不清楚。我试图解释一些像body.black-theme h1 { color: '#F2F2F2' } body.white-theme h1 { color: '#606060' } 这样的实现。这样更改 body 的类名可以更改整个应用程序主题。这是一个解释我的解决方案的小例子。可能不适合你。
  • 你能不能把它作为一个更广泛的例子,并附上具体的实施例子作为答案?作为一个初学者,我还不太清楚这会是什么样子:S

标签: reactjs dynamic sass


【解决方案1】:

您可以查看this question 了解有关主题管理的详细信息。我建议的是更简单的解决方案(在我看来)

而不是像这样分隔不同样式的文件;

/* main.css */
#box {
    position: absolute;
    top: 50px;
    left: 50px;
    width: 200px;
    height: 200px;
}

/* theme1.css */
#box {
    backround-color: red;
}

/* theme2.css */
#box {
    background-color: maroon
}

像这样将它们设置在一个文件中;

#box {
    position: absolute;
    top: 50px;
    left: 50px;
    width: 200px;
    height: 200px;
}

div.theme1 #box {
    backround-color: red;
}

div.theme2 #box {
    background-color: maroon
}

我知道这是一个 css 解决方案而不是 scss,但逻辑几乎相同。

您可以在更高级别的组件上设置所需的主题 className 并影响整个应用程序。

class App extends React.Component {
    render() {
        return (
            <div className={this.props.theme}>
                <MainApp />
            </div>
        )
    }
}

更新

你可以根据this answer做条件要求。

class Main extends Component {
    componentWillMount() {
         if(this.props.language === 'ar') {
            require('arabic.css');
         } else {
            require('english.css');
         }
    }
}

【讨论】:

  • 但我更喜欢拥有一个单独文件的解决方案,因为我的 reactjs 应用程序由 50 多个组件组成,所有组件都取决于一个 scss 文件的颜色,所以如果我必须进入每个组件并且每个 div 并在那里设置动态类,工作量太大了
  • 更新了答案。请检查添加的部分。
  • 好吧,只加载两者似乎反应并不关心是否在 if 中提到了一个 css,如果它在某处被加载。
【解决方案2】:

SCSS 需要在构建时编译。浏览器不具备处理 SASS 的能力。此外,require() 方法是在构建时运行的 webpack 方法,而不是在浏览器中动态运行。你可以做的是使用类似extract-css-chunks plugin

的 webpack 创建拆分

【讨论】:

  • 这看起来很酷,但对于我认为很简单的事情来说却相当笨拙。我正在研究它尝试演示。你真的推荐这个吗?顺便说一句:在我看来,浏览器上的原生 SASS 支持是一个真正必要的更新。
  • 它的效果非常好,你不觉得有点矫枉过正吗?
  • 好吧,它不会为您的最终捆绑包增加任何重量,该插件仅存在于您的本地机器/构建服务器上。对于任何接触您的代码的开发人员来说,它确实会使安装时间稍长一些,但它通过使用两个单独的 css 文件而不是一个大的 css 文件来减少客户端必须下载的包的大小。既然 CSS 变量和模块正在登陆,SASS 可能会消失:developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 2020-11-05
  • 2013-02-23
  • 1970-01-01
相关资源
最近更新 更多