//安装下面的包时可能会报错,此时可以使用 cnpm 淘宝镜像进行安装
cnpm install node-sass --save-dev   
cnpm install sass-loader --save-dev
//node-sass和sass-loader的版本过高可能会有各种奇奇怪怪的问题。亲测,以下版本可配合 node8.11.1使用
//最好先装node-sass,否则可能会有问题
cnpm install node-sass@4.14.1 --save-dev
cnpm install sass-loader@7.3.1 --save-dev

然后修改 webpack.base.config.js 文件,修改 module 下的 rules :

module: {
   rules: [
          test: /\.scss$/,
          loaders: ["style", "css", "sass"]

在 vscode 中使用 sass 语法可能会提示语法错误,但是编译运行都没问题,此时修改 vscode 的设置:先安装vetur插件,在vscode的设置中添加:  "files.associations": { "*.vue": "vue" }

1.2、sass 的特性介绍

sass的语法完全兼容css,所以我们可以把css文件直接改名为.scss后缀,并且可以用来直接导入。

2、Sass 的基本语法

 2.1、变量

在sass中你可以把反复使用的css属性值定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。

2.1.1、变量声明及使用

sass使用 $ 符号来标识变量。任何可以用作css属性值的赋值都可以用作sass的变量值,甚至是以空格分割的多个属性值,如$basic-border: 1px solid black;,或以逗号分割的多个属性值。

变量可以在css规则块定义之外声明,也可以在规则块之内声明。当变量定义在css规则块内,那么该变量只能在此规则块内使用。

$nav-color: #F90;
$plain-font: "Myriad Pro"、Myriad、"Helvetica Neue"、Helvetica、"Liberation Sans"、Arial和sans-serif; sans-serif;
nav {
  $width: 100px;  //此时的width 变量只能在这个规则块内使用
  width: $width;
  color: $nav-color;

在声明变量时,变量值也可以引用其他变量。

$highlight-color: #F90;
$highlight-border: 1px solid $highlight-color;
.selected {
  border: $highlight-border;

sass 的变量名可以使用中划线 - 或者下划线 _ 命名,sass并不强迫一定要使用中划线或下划线,所以这两种用法都相互兼容。甚至用中划线声明的变量可以使用下划线的方式引用,反之亦然。

2.2、嵌套规则

在sass中可以不用重复写选择器,sass允许在规则块中嵌套规则块

#content {
  background-color: #f5f5f5;
  article {
    h1 { color: #333 }
    p { margin-bottom: 1.4em }
  aside { background-color: #EEE }
 /* 编译后 */
#content {background-color: #f5f5f5;}
#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }

2.2.1、父选择器标识符(&)

用 & 符号放在嵌套规则中可以表示嵌套规则的父选择器

article h1 {
  color: blue;
  &:hover { color: red }
/*编译后*/
article a { color: blue }
article h1:hover { color: red }   /* 表示 h1 hover变红色 */
/*  如果不使用&符号则可能表示的会是另一种意思  */
/*  下面的sass代码表示article元素内 h1 的所有子元素被hover时都会变成红色,而不是h1元素 */
article h1 {
  color: blue;
  :hover { color: red }

在嵌套规则中,& 符号表示的就是父选择器,在 & 选择器之前也可以添加选择器。

#content aside {
  color: red;
  body.ie & { color: green }
/*编译后*/
#content aside {color: red};
body.ie #content aside { color: green }

2.2.2、群组选择器的嵌套

.container {
  h1, h2, h3 {margin-bottom: .8em}
/* 编译后 */
.container h1, .container h2, .container h3 { 
  margin-bottom: .8em

你需要特别注意群组选择器的规则嵌套生成的css,虽然sass让你的样式表看上去很小,但实际生成的css却可能非常大,这会降低网站的速度。

2.2.3、子组合选择器和同层组合选择器:>、+ 和 ~

article {
  ~ article { border-top: 1px dashed #ccc }
  > section { background: #eee }
  dl > {
    dt { color: #333 }
    dd { color: #555 }
  nav + & { margin-top: 0 }
/* 编译后 */
article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { margin-top: 0 }

2.2.4、属性嵌套

属性嵌套指的是在CSS规则中把属性名从中划线 - 的地方断开,在根属性后边添加一个冒号:,紧跟一个{ }块,把子属性部分写在这个{ }块中。

nav {
  border: {
    style: solid;
    width: 1px;
    color: #ccc;
/* 编译后 */
nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;

对于属性的缩写形式,你甚至可以像下边这样来嵌套,指明例外规则:

nav {
  border: 1px solid #ccc {
    left: 0px;
    right: 0px;
/* 编译后 */
nav {
  border: 1px solid #ccc;
  border-left: 0px;
  border-right: 0px;

3、如何导入SASS文件

css有一个特性,即@import规则(非常不常用),它允许在一个css文件中导入其他css文件。然而,在只有执行到@import时,浏览器才会去下载其他css文件,这会导致页面加载起来变慢,因为这样你会需要加载几个css文件。

sass也有一个@import规则,但不同的是,sass@import规则在生成css文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css文件中,而无需发起额外的下载请求。并且被导入文件中定义的所有变量和混合器均可在导入文件中使用。

使用sass@import规则并不需要指明被导入文件的全名。你可以省略.sass.scss文件后缀,比如:

/* index.scss文件 */
   color: red;
/* 导入语句不要漏了后面的分号';' ,否则有可能会报错 */
@import './index';     /* 导入index.scss文件 */
.hello h1{
  &:hover {
    color: red;

3.1、导入sass局部文件

用下划线开头 _ 命名的 scss 文件,代码在编译时并不会将这些文件编译为单独的 css 文件,我们把这样的 scss 文件称之为局部文件。其他的 scss 文件在编译时应该每个都会被编译成单独的 css 文件(未验证过)。

我们可以在局部文件中写入一些用来给其他文件导入的样式及变量等,而且它们并不会被编译成单独的 css 文件。在@import一个 scss 局部文件时,可以省略文件名开头的下划线。比如想导入 '_common.scss'  文件,可以这样写: @import './common';

3.2、默认变量值

可以用 !default 来声明一个默认变量,如果没有重复声明的话,用户使用该变量就会使用默认值。但是如果被重复声明赋值,该默认变量值就会被覆盖掉。

$link-color: blue !default;;
$link-color: red;
  color: $link-color;   /*color会被赋值为red*/

3.3、嵌套导入

 sass允许 @import命令写在css规则内,在这种导入方式下,被导入的局部文件中定义的所有变量和混合器,只会在这个规则范围内生效,而不会全局生效。

/* blue.scss文件 */
aside {
  background: blue;
  color: white;
/* 导入 */
.blue {
  @import "blue.scss"
/* 编译后 */
.blue {
  aside {
    background: blue;
    color: #fff;

3.4、原生的CSS导入

通常在sass中使用@import时,sass会尝试找到对应的sass文件并导入进来。但是在 sass 中也可以导入 css 文件,在下列三种情况下,sass 会将 @import 命令认为是导入 css 文件,这会造成浏览器额外的下载。

  • 被导入文件的名字以.css结尾;
  • 被导入文件的名字是一个URL地址(比如http://www.sass.hk/css/css.css),由此可用谷歌字体API提供的相应服务;
  • 被导入文件的名字是CSS的url()值。
  • 4、静默注释

    css中的注释是对用户可见的,在sass中另外提供了一种语法即静默注释,该语法不同于css标准注释格式/* ... */,并且其注释的内容不会出现在生成的css文件中。以 // 开头的注释语法即为静默注释,跟javascript注释语法一样。

    body {
      color: #333; // 这种注释内容不会出现在生成的css文件中
      padding: 0; /* 这种注释内容会出现在生成的css文件中 */
    

    5、混合器(@mixin、@include)

    使用sass的混合器可以实现大段样式的重用,混合器使用@mixin标识符定义,这个标识符可以给一段样式命名,然后我们就可以通过@include引用这个名字来重用这段样式。

    @mixin aaa { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; notice { background-color: green; @include aaa; //sass最终生成: .notice { background-color: green; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;

    混合器中不仅可以包含属性,同时也可以包含css规则,包含选择器和选择器中的属性等

    @mixin no-bullets {
      list-style: none;    //混合器中使用属性
      li {                      //混合器中使用元素选择器
        list-style-image: none;
        list-style-type: none;
        margin-left: 0px;
    ul.plain {
      color: #444;
      @include no-bullets;
    //相当于
    ul.plain {
      color: #444;
      list-style: none;
        list-style-image: none;
        list-style-type: none;
        margin-left: 0px;
    

    5.1、给混合器传参

    混合器并不一定总得生成相同的样式。可以通过在@include混合器时给混合器传参,来定制混合器生成的精确样式。当@include混合器时,参数就是css属性值,混合器的这种特性跟 javascript 中的 function 类似。

    @mixin link-colors($normal, $hover, $visited) { color: $normal; &:hover { color: $hover; } &:visited { color: $visited; } @include link-colors(blue, red, green); //Sass最终生成的是: a { color: blue; } a:hover { color: red; } a:visited { color: green; }

    sass 还允许通过语法 $name: value 的形式指定每个参数的值,这种形式的传参,就可以不必在乎参数的顺序了,只需要保证没有漏掉参数即可

    @include link-colors( $normal: blue, $visited: green, $hover: red

    5.2、混合器默认参数

    在混合器中,我们可以给参数指定默认的属性值。参数默认值使用 $name: value 的声明形式,默认值可以是任何有效的 css 属性值,或者是其他参数的引用。

    @mixin link-colors(
        $normal,
        $hover: red,
        $visited: $normal
      color: $normal;
      &:hover { color: $hover; }
      &:visited { color: $visited; }
    

    6、选择器继承(@extend)

    使用选择器继承 @extend 可以在一个选择器中继承另一个选择器定义的所有样式。

    .error {
      border: 1px solid red;
      background-color: #fdd;
    //通过选择器继承继承样式
    .seriousError {
      @extend .error;
      border-width: 3px;
    

    上面的代码会使得以class="seriousError"修饰的 html 元素最终的展示效果是class="seriousError error"

    注意:上面中的.seriousError不仅会继承.error自身的所有样式,任何跟.error有关的组合选择器样式也会被.seriousError以组合选择器的形式继承

    .error a{  //将也会影响.seriousError a
      color: red;
    h1.error { //将也会影响hl.seriousError
      font-size: 1.2rem;
    //使用继承后class="seriousError"的所有元素内的 h1 标签和超链接也会变成红色和粗体。
    .seriousError {
      @extend .error;
    

    6.1、继承元素标签的样式

    实际上,@extend 不仅可以继承类的样式,同样也可以继承元素标签的的样式

    color
    : green; //继承 a 标签的样式 .panel { @extend a;

    6.2、sass继承的原理

    sass 中继承实际上是在每个被继承的类处添加需要继承的类名,以使得样式对两个类名都起作用。

    .seriousError{
       @extend .error;
    //使用继承后,样式表中的任何一处.error都用.error, .seriousError这一选择器组进行替换。
    .error {
      color: red;
    //将会被替换为
    .error, .seriousError {
      color: red;
    .error a{
      color: red;
    //将会被替换为
    .error a, .seriousError a{
      color: red;
    

    注意:应避免用复杂选择器(比如.a .b这种有后代选择器的)去使用继承,那样会使得在一个CSS规则中的选择器的个数变得非常大,代码也变得艰涩难懂。