Nicklas Kevin Frank
Nicklas Kevin Frank

Reputation: 6337

Using sass variables in a VueJS component

I got a rather simple problem with a VueJS component that needs to use a variable. The problem comes with getting sass to register variables inside a component.

I tried importing the _variables.scss file containing my variables but to no luck. At this point any guidance is very much appreciated, or if there is another way for a component to inherit styling.

MyComponent.vue

<template>
    <div class="my-color"></div>
</template>
<style lang="sass">
    .my-color {
        color: $primary-color;
    }
</style>
<script>
    export default{
        data(){
            return {}
        }
    }
</script>

Gulpfile.js

var elixir = require('laravel-elixir');
require('laravel-elixir-vueify');

elixir(function(mix) {
    mix.browserify('main.js');
    mix.sass('app.scss');
});

app.scss

@import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
@import "modules/variables";

variables.scss

$primary-color: #BA2731; //Red

Upvotes: 38

Views: 67487

Answers (6)

Jeandre van Zyl
Jeandre van Zyl

Reputation: 31

For Nuxt 3

Inside of nuxt.config.ts

export default defineNuxtConfig({
  css: ["@/assets/styles/main.scss"],
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@import "@/assets/styles/_variables.scss";'
        }
      }
    }
  }
})

Upvotes: 3

Gene Parcellano
Gene Parcellano

Reputation: 6044

For my project I used Vue CLI webpack and here's a solution that worked for me.

I manage all of my SCSS in the App.vue file. In each of my Component.vue I stopped using <style></style> and started creating a separate component.scss.


So my src folder looks like:

 /src
     /assets
     /components
         /compA
             CompA.vue
             compA.scss
         /compB
             CompB.vue
             compB.scss
    App.vue
    main.js

And my App.vue looks like

<template> ... </template>

<script> ... </script>

<style lang="less">
    //Bootstrap
    @import "../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";

    //Components
    @import "components/compA.scss";
    @import "components/compB.scss";
</style>

The advantage of this setup is getting to manage all your styles in one location, and also being able to use all your bootstrap variables and mixins.

Note:

This is just another option of using SASS variables in Vue.

I went this route since when I import the Boostrap SCSS in all of my components, the size of my app kept growing. The increase is negligible if I'm only importing the variables, but when I import the whole Boostrap SCSS the increase becomes significant. I do this so I can use the mixins and extend some existing styles.

Upvotes: 0

logee
logee

Reputation: 5077

Assuming you are using vue-cli, try this.

If you don't already have the sass loader installed:

npm install -D sass-loader node-sass

Then in vue.config.js:

const path = require('path');

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: `@import "@/pathto/variables.scss";`
      }
    }
  }
};

In your component:

<style lang="sass">
    .my-color {
        color: $primary-color;
    }
</style>

Source:

Edit:

As of sass-loader 8, data needs to be prependData (Thanks to @ben-y for pointing this out):

const path = require('path');

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        prependData: `@import "@/pathto/variables.scss";`
      }
    }
  }
};

Upvotes: 31

Wolle
Wolle

Reputation: 491

For me none of the solutions above worked (sass-loader 9.0.3) but this did:

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        sassOptions: {
          prependData: `@import "@/scss/variables.scss";`
        }
      },
    },
  },
};

Upvotes: 1

Oli
Oli

Reputation: 314

I'm using the latest version (v9.0.2) of sass-loader, and prependData doesn't seem like an option now. You might want to try this configuration in vue-config.js. Notice the additionalData option is being used as there's no longer a prependData option.

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        additionalData: '@import "@/pathto/variables.scss";'
      }
    }
  }
}

Upvotes: 6

nils
nils

Reputation: 27215

Importing the _variables.scss in every component seems to be the only solution I've found so far (it should work, according to this issue).

<template>
    <div class="my-color"></div>
</template>
<style lang="sass">
    @import 'path/to/your/_variable.scss'; // Using this should get you the variables
    .my-color {
        color: $primary-color;
    }
</style>
<script>
    export default{
        data(){
            return {}
        }
    }
</script>

As you are only going to include variables, this shouldn't be a problem.

But as mentioned in the issue, a word of caution: You should only include abstract entities (variables, extends, mixins) into every component, no concrete CSS rules.

Upvotes: 47

Related Questions