noah.plus

単一ファイルコンポーネントで使えるグローバルなSCSS変数・mixinを定義する(Vue.js)

2018-11-18

vue-webpack-boilerplateを使ったときの例です。

vuejs-templates/webpack

単一ファイルコンポーネント(.vueファイル)では、以下のようにして簡単にSCSSが使える。

<style lang="scss" scoped>

// put your styles here

</style>

コンポーネントごとにスタイルを設定することでスコープが狭まりCSSが破綻しにくくなる。

しかし、共通の色を定義した変数やメディアクエリを呼び出すmixinなど、繰り返し使用するものに関してはグローバルに設定しておきたい。

そこで sass-resources-loader を使って、単一ファイルコンポーネントから共通の変数やmixinを呼び出せるようにする。

sass-resources-loader

ということでまずはモジュールをインストール。

npm install sass-resources-loader --save-dev

そして build/utils.js でローダーを生成している箇所を以下のように変更する。

exports.cssLoaders = function (options) {

  // ...省略...

  return {
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less'),
    sass: generateLoaders('sass', { indentedSyntax: true }),
    // sass-resources-loaderを適用
    scss: generateLoaders('sass').concat(
      {
        loader: 'sass-resources-loader',
        options: {
          resources: path.resolve(__dirname, '../src/styles/_index.scss')
        }
      }
    ),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')
  }
}

グローバルなSCSSは src/styles/_index.scss に記述することにした。

// src/styles/_index.scss

$primary: #FF6465
$secondary: #03C8A8

あとは指定したディレクトリの指定したファイル(_index.scss)に変数やmixinを記述していけばOK。

これで単一ファイルコンポーネントから $primary$secondary といった変数にアクセスできる。(mixinも同様)

万全を期すなら _variables.scss_mixin.scss を別ファイルで作成し、_index.scss でインポートすれば安心。

備考

sass-resources-loader は指定したSCSSファイルを全ての.vueファイルでインポートする。

したがって、src/styles/_index.scssは、自動的に全てのVueコンポーネントのSCSSで @import されることになる。

最終的にCSSとして書き出されるスタイルを_index.scssに含めると、Vueコンポーネントの数だけアウトプットのCSSファイルのサイズが肥大化してしまう。

変数・mixinなどはアウトプットに含まれないのでファイルサイズには関係ないが、うっかり普通にスタイルを記述してしまわないように気をつけたい。

そういった意味でファイル名の前に _ (アンダースコア)をつけておくことが大事。


noah.plus