5

ユーザーが自分のウェブサイトでテーマを選択できるようにしたいのですが、これはドロップダウンから行います。私は現在、ダムコードを書かずにこの機能をサポートする方法を理解するのに苦労しています.

私は現在、postcss と一緒に css-modules を使用して生活を楽にしています。Webpack は、すべてをまとめるために使用されます。開発中はホット リロードを利用し、代わりにスタイル ローダーを使用します。

完全な構成は次のようになります

{
  test: /\.css$/,
  loader: !isDev
    ? ExtractTextPlugin.extract('style-loader', 'css-loader?sourcemap&minimize&modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!postcss-loader')
    : 'style-loader!css-loader?sourcemap&minimize&modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!postcss-loader'
},

解決策 1

body タグにクラス名を配置して、どのテーマがロードされているかを判別します。これは、各コンポーネント css 内から正しいテーマを選択するために使用されます。これは非常に面倒で避けたいことですが、次のようになります。

.myComponent {
  margin: 10px;
  width: 100px;
}

:global(.theme1) {
  .myComponent {
    background: $theme1_myComponent_background;
  }
}

:global(.theme2) {
  .myComponent {
    background: $theme2_myComponent_background;
  }
}

これはすぐに拡張が難しく、保守できないものになるため、避けたいと思います。

解決策 2

css の事前にテーマ設定された静的バンドルを生成します。ユーザーが を要求する/main.cssと、サーバー上のハンドラーが送信するテーマ (おそらくクエリ文字列) を決定し、それらの行に沿ってそれらまたは何かtheme1-main.cssを送信します。theme2-main.css問題は、開発環境をサポートする方法がわからないことです。

これの良いところは、私の css ファイルが追加のロジックを維持するのが難しいことを必要としないということです:

.myComponent {
  margin: 10px;
  width: 100px;
  background: $myComponent_background;
}

解決策 3

ネイティブの CSS 変数を使用します。これらは実行時に更新でき、すでにロードされている css を反映し、本番環境と開発環境の両方で正常に動作します。私のコンポーネントも解決策 2 のように (または同様に) 見えます。ここでの問題は、それらがネイティブであまり広くサポートされていないことです。また、この種のことを行うために検討する価値のあるポリフィルがあるかどうかもわかりません。


以上が私の考えです。私はまだ決定的な結論に達していません。この問題を解決する方法について、すべてのフィードバックをお待ちしております。おそらく、私はそれについてすべて間違って考えており、私がやりたいことを行うためのはるかに良い方法があります.

前もって感謝します!

4

2 に答える 2

0

SASSを使用したソリューションを次に示します。これは基本的にソリューション 1 ですが、作成と保守が簡単です。あなたはSASSを使用していないようですが、個人的な使用のために見つけることができる最良のソリューションであるため、共有する価値があると思いました...

SCSS コードは次のとおりです ( CodePen here )。

// Define theme variables

$themes: (
  default: ( // default theme
    bg-color: white,
    text-color: black,
  ),
  dark: (
    bg-color: black,
    text-color: white,
  ),
  colorful: (
    bg-color: green,
    text-color: orange,
  )
);

// This is how you use your themes

.example{
  padding: 10px;
  @include themify {
    background: theme-get(bg-color);
    color: theme-get(text-color);
  }
}

これが機能する必要があります:

@mixin themify() {
  // Iterate over the themes
  @each $theme-name, $theme in $themes {
    $current-theme: $theme !global;
    @if $theme-name == 'default' {
      @content;
    } @else {
      .theme-#{$theme-name} & {
        @content;
      }
    }
  }
}

@function theme-get($key, $theme: $current-theme) {
  $ret: map-get($theme, $key);
  @if not $ret {
    @error 'Your theme doesn\'t have a value for `#{$key}`.';    
  }
  @return $ret;
}

結果の CSS:

.example {
  padding: 10px;
  background: white;
  color: black;
}
.theme-dark .example {
  background: black;
  color: white;
}
.theme-colorful .example {
  background: green;
  color: orange;
}

これは、次のことに大きく影響を受けています。

于 2016-10-24T23:56:49.603 に答える
0

1つの可能なアプローチは次のようになります

  1. style-loaderCSS を自動的に挿入するので使用しませんが、必要なとき手動で行います。

例えば:

const css1 = require("raw!./App1.css");
const css2 = require("raw!./App2.css");

(ここで必要raw-loaderです)

  1. 次に、必要なスタイルをドキュメントに挿入するだけです。

例えば:

const style = document.createElement("link");
style.type = "stylesheet/text-css";
style.rel = "stylesheet";
style.href=`data:text/css,${css1}`;
// style.href=`data:text/css,${css2}`;
style.id = "theming";

document.querySelector("head").appendChild(style);
  1. その後、必要に応じてテーマを変更できます

に別のスタイルを入れるだけhrefです:

style.href=`data:text/css,${css2}`

または React 経由で同じことをしましょう:

import React, { Component } from 'react';
import logo from './logo.svg';

class App extends Component {
  constructor(props) {
    super(props);

    this.cssThemes = [];
    this.cssThemes.push(require("./App.css"));
    this.cssThemes.push(require("./App1.css"));
    this.cssThemes.push(require("./App2.css"));
    this.cssThemes.push(require("./App3.css"));

    this.state = { 
      themeInd: 0,
    }
  }
  render() {
    return (
      <div >
      <style>
        {this.cssThemes[this.state.themeInd]}
      </style>
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p >
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
        <button 
          onClick={() => this.setState({themeInd: this.state.themeInd+1})}
        >
          Change theme
        </button>
      </div>
    );
  }
}

export default App;

raw-loaderwebpack.config で css ファイルを処理するように設定すると機能します

{
  test: /\.css$/,
  loader: 'raw'
},
于 2016-11-13T09:43:15.667 に答える