在VueJS组件中使用sass变量

38

我有一个在VueJS组件中需要使用变量的相当简单的问题。问题在于在组件中注册Sass变量。

我尝试导入包含我的变量的_variables.scss文件,但没有成功。此时非常感谢任何指导,或者如果有另一种方式让组件继承样式。

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
6个回答

44

目前我找到的唯一解决方案似乎是在每个组件中导入_variables.scss文件(根据这个问题,它应该有效)。

<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>

由于您只会包含变量,因此这不应该是问题。

但正如在问题中提到的那样,请注意:您应该仅将抽象实体(变量、扩展、混合)包含在每个组件中,而不是具体的CSS规则。


在编译后的 CSS 中,@import 出现了多次,导致浏览器加载了不存在的文件。我们该如何解决这个问题?@nils - Nicklas Kevin Frank
你在@import语句中是否包含了.scss.css文件? - nils
我找到了问题,只是一个单独的<style>没有设置语言:<style lang="sass">。我的错,谢谢! - Nicklas Kevin Frank
@nils这个答案还适用吗?我试过了,但是在导入后一切都给出错误提示说它不被允许存在那里。 - Nancy
请注意,如果您以这种方式导入100个组件,则每次导入文件大小都会增加。最好在全局加载一次。 - BobB
显示剩余4条评论

30

假设您正在使用 vue-cli,请尝试以下操作。

如果您尚未安装 Sass loader:

npm install -D sass-loader node-sass

然后在 vue.config.js 文件中:

const path = require('path');

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: `@import "@/pathto/variables.scss";`
      }
    }
  }
};
在你的组件中:
<style lang="sass">
    .my-color {
        color: $primary-color;
    }
</style>

来源:

编辑:

从sass-loader 8开始,data需要改成prependData(感谢@ben-y指出):

const path = require('path');

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

3
这取决于 webpack 而不是 vue-cli。 - Fabian von Ellerts
根据您的webpack配置,这种方法可能会导致变量在每个注入页面的<style>块中重复出现。如果您有很多组件和变量,这可能会显著增加页面的负荷。 - emersonthis

6

我正在使用最新版本(v9.0.2)的sass-loader,而现在似乎不存在prependData选项。你可以尝试在vue-config.js中尝试以下配置。请注意,由于不再存在prependData选项,因此使用了additionalData选项。

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

3

对于Nuxt 3

在nuxt.config.ts文件中

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

对于Vue 3 + Vite,在vite.config.ts中是一样的。谢谢。 - Gabriel Anderson

1

对我来说,以上的解决方案都不起作用(sass-loader 9.0.3),但是这个方法有效:

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

0

对于我的项目,我使用了Vue CLI webpack,这是一个适合我的解决方案。

我在App.vue文件中管理所有的SCSS。在每个Component.vue中,我停止使用<style></style>,并开始创建一个单独的component.scss文件。


所以我的src文件夹看起来像这样:

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

我的 App.vue 看起来像这样

<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>

这种设置的优点是可以在一个位置管理所有样式,并且能够使用所有的Bootstrap变量和mixin。

注意:

这只是在Vue中使用SASS变量的另一种选择。

我选择这条路,因为当我在所有组件中导入Boostrap SCSS时,我的应用程序大小会不断增长。如果我只导入变量,则增加是可以忽略不计的,但是当我导入整个Boostrap SCSS时,增加就变得显著了。我这样做是为了使用mixin并扩展一些现有的样式。


1
有趣的想法,如果可能的话,你会如何将<style scoped>加入到这个设置中? - Fractalf
1
这在一定程度上破坏了Vue基于组件的系统!为什么要这样做呢?使用webpack SASS加载器将变量导入到每个文件中,就像user2718281建议的那样。 - Fabian von Ellerts
@FabianvonEllerts 我同意,但是当你为一个大公司设置品牌并且有大量的变量和mixin时,在每个组件中复制这些变量和mixin似乎不是一个好主意。在2017年的时候,我找不到更好的方法来解决这个问题,也不想复制变量和mixin的代码。现在可能有更好的方法。我在这里发布它作为其他需要处理mixin和大型变量文件的人的替代方案。 - Gene Parcellano
1
这真的是最好的。老式和直接,没有重复和变量问题。点赞 @GeneParcellano - Vixson
在使用<style scoped>的同时,是否可以使用全局定义的SCSS变量(存在于资产文件夹中)?<style scoped> .myClass { color: $my-color-variable; } </style> - Luckytechy
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接