SASS 变量

Vuetify 使用 SASS/SCSS 来制作框架的风格和外观。利用你的 vue.config.js 文件中的 _sass/scss 数据选项_,你可以选择性地传递自定义变量来覆盖全局默认值。可用变量的列表位于每个组件的API部分和本页面的 Variable API 中。此功能由 vue-cli-plugin-vuetify 自动处理。

注意:只有使用 A-la-carte 安装 才支持 SASS/SCSS 变量。使用 \vue-cli-plugin-vuetify \插件时这将会自动设置。

Vue CLI 安装

如果你还没有安装 Vuetify,请查看 快速启动指南。安装完成后,在你的 src 目录下创建一个名为 sassscssstyles 的文件夹,文件名为 variables.scssvariables.sassvuetify-loader 会自动将你的变量引导到 Vue CLI 的编译过程中,覆盖框架的默认值。

当你运行 yarn serve 时,vuetify-cli-plugin 会自动将全局的 Vuetify 变量提升到你所有的 sass/scss 文件中。当对单个组件变量进行修改时,你仍然需要手动包含它的变量文件。你可以在下面找到一个 自定义变量 文件的例子。

Nuxt 安装

即将推出。如果你有兴趣在这部分的合作,请联系 社区 中的 _johnleider_。

Webpack 安装

本节假设你已经按照我们在 快速启动 页面上的 Webpack 指南进行了操作。这个选项会根据你所使用的 sass-loader 的版本而有所不同。确保你在设置 SASS/SCSS 数据选项时使用正确的语法,因为它们有不同的行尾。你可以在 sass-loader 的 Github 页面上找到更多关于 prependData 的信息。

  1. // webpack.config.js
  2. module.exports = {
  3. module: {
  4. rules: [
  5. // SASS has different line endings than SCSS
  6. // and cannot use semicolons in the markup
  7. {
  8. test: /\.sass$/,
  9. use: [
  10. 'vue-style-loader',
  11. 'css-loader',
  12. {
  13. loader: 'sass-loader',
  14. // Requires sass-loader@^7.0.0
  15. options: {
  16. // This is the path to your variables
  17. data: "@import '@/styles/variables.scss'"
  18. },
  19. // Requires sass-loader@^8.0.0
  20. options: {
  21. // This is the path to your variables
  22. prependData: "@import '@/styles/variables.scss'"
  23. },
  24. },
  25. ],
  26. },
  27. // SCSS has different line endings than SASS
  28. // and needs a semicolon after the import.
  29. {
  30. test: /\.scss$/,
  31. use: [
  32. 'vue-style-loader',
  33. 'css-loader',
  34. {
  35. loader: 'sass-loader',
  36. // Requires sass-loader@^7.0.0
  37. options: {
  38. // This is the path to your variables
  39. data: "@import '@/styles/variables.scss';"
  40. },
  41. // Requires sass-loader@^8.0.0
  42. options: {
  43. // This is the path to your variables
  44. prependData: "@import '@/styles/variables.scss';"
  45. },
  46. },
  47. ],
  48. },
  49. ],
  50. },
  51. }

Variable API

在整个 Vuetify 框架中,有很多 SASS/SCSS 变量可以被自定义。下面是一个自定义的 variables 文件的例子。你可以在下面找到更多关于可用的 变量 信息。

name

$blockquote-font-size

default

  1. 18px !default;

name

$blockquote-font-weight

default

  1. 300 !default;

name

$body-font-family

default

  1. 'Roboto', sans-serif !default;

name

$bootable-transition

default

  1. 0.2s map-get($transition, 'fast-out-slow-in') !default;

name

$border-radius-root

default

  1. 4px !default;

name

$code-color

default

  1. #bd4147 !default;

name

$code-kbd-border-radius

default

  1. 3px !default;

name

$code-kbd-font-size

default

  1. 85% !default;

name

$code-kbd-font-weight

default

  1. 900 !default;

name

$color-pack

default

  1. true !default;

name

$container-max-widths

default

  1. map-deep-merge(
  2. (
  3. 'md': map-get($grid-breakpoints, 'md') * 0.9375,
  4. 'lg': map-get($grid-breakpoints, 'lg') * 0.9375,
  5. 'xl': map-get($grid-breakpoints, 'xl') * 0.9375
  6. ),
  7. $container-max-widths
  8. );

name

$container-padding-x

default

  1. $grid-gutter / 2 !default;

name

$display-breakpoints

default

  1. map-deep-merge(
  2. (
  3. 'print-only': 'only print',
  4. 'screen-only': 'only screen',
  5. 'xs-only': 'only screen and (max-width: #{map-get($grid-breakpoints, 'sm') - 1})',
  6. 'sm-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')}) and (max-width: #{map-get($grid-breakpoints, 'md') - 1})',
  7. 'sm-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'md') - 1})',
  8. 'sm-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')})',
  9. 'md-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')}) and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})',
  10. 'md-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})',
  11. 'md-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')})',
  12. 'lg-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')}) and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})',
  13. 'lg-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})',
  14. 'lg-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')})',
  15. 'xl-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'xl')})'
  16. ),
  17. $display-breakpoints
  18. );

name

$font-size-root

default

  1. 16px !default;

name

$font-weights

default

  1. map-deep-merge(
  2. (
  3. 'thin': 100,
  4. 'light': 300,
  5. 'regular': 400,
  6. 'medium': 500,
  7. 'bold': 700,
  8. 'black': 900
  9. ),
  10. $font-weights
  11. );

name

$form-grid-gutter

default

  1. $spacer * 2 !default;

name

$grid-breakpoints

default

  1. map-deep-merge(
  2. (
  3. 'xs': 0,
  4. 'sm': 600px,
  5. 'md': 960px,
  6. 'lg': 1280px - 16px,
  7. 'xl': 1920px - 16px
  8. ),
  9. $grid-breakpoints
  10. );

name

$grid-columns

default

  1. 12 !default;

name

$grid-gutter

default

  1. $spacer * 6 !default;

name

$grid-gutters

default

  1. map-deep-merge(
  2. (
  3. 'xs': $grid-gutter / 12,
  4. 'sm': $grid-gutter / 6,
  5. 'md': $grid-gutter / 3,
  6. 'lg': $grid-gutter * 2/3,
  7. 'xl': $grid-gutter
  8. ),
  9. $grid-gutters
  10. );

name

$heading-font-family

default

  1. $body-font-family !default;

name

$headings

default

  1. map-deep-merge(
  2. (
  3. 'h1': (
  4. 'size': 6rem,
  5. 'weight': 300,
  6. 'line-height': 6rem,
  7. 'letter-spacing': -.015625em,
  8. 'font-family': $heading-font-family
  9. ),
  10. 'h2': (
  11. 'size': 3.75rem,
  12. 'weight': 300,
  13. 'line-height': 3.75rem,
  14. 'letter-spacing': -.0083333333em,
  15. 'font-family': $heading-font-family
  16. ),
  17. 'h3': (
  18. 'size': 3rem,
  19. 'weight': 400,
  20. 'line-height': 3.125rem,
  21. 'letter-spacing': normal,
  22. 'font-family': $heading-font-family
  23. ),
  24. 'h4': (
  25. 'size': 2.125rem,
  26. 'weight': 400,
  27. 'line-height': 2.5rem,
  28. 'letter-spacing': .0073529412em,
  29. 'font-family': $heading-font-family
  30. ),
  31. 'h5': (
  32. 'size': 1.5rem,
  33. 'weight': 400,
  34. 'line-height': 2rem,
  35. 'letter-spacing': normal,
  36. 'font-family': $heading-font-family
  37. ),
  38. 'h6': (
  39. 'size': 1.25rem,
  40. 'weight': 500,
  41. 'line-height': 2rem,
  42. 'letter-spacing': .0125em,
  43. 'font-family': $heading-font-family
  44. ),
  45. 'subtitle-1': (
  46. 'size': 1rem,
  47. 'weight': 400,
  48. 'line-height': 1.75rem,
  49. 'letter-spacing': .009375em,
  50. 'font-family': $body-font-family
  51. ),
  52. 'subtitle-2': (
  53. 'size': .875rem,
  54. 'weight': 500,
  55. 'line-height': 1.375rem,
  56. 'letter-spacing': .0071428571em,
  57. 'font-family': $body-font-family
  58. ),
  59. 'body-2': (
  60. 'size': .875rem,
  61. 'weight': 400,
  62. 'letter-spacing': .0178571429em,
  63. 'line-height': 1.25rem,
  64. 'font-family': $body-font-family
  65. ),
  66. 'body-1': (
  67. 'size': 1rem,
  68. 'weight': 400,
  69. 'letter-spacing': .03125em,
  70. 'line-height': 1.5rem,
  71. 'font-family': $body-font-family
  72. ),
  73. 'caption': (
  74. 'size': .75rem,
  75. 'weight': 400,
  76. 'letter-spacing': .0333333333em,
  77. 'line-height': 1.25rem,
  78. 'font-family': $body-font-family
  79. ),
  80. 'overline': (
  81. 'size': .625rem,
  82. 'weight': 400,
  83. 'letter-spacing': .1666666667em,
  84. 'line-height': 1rem,
  85. 'font-family': $body-font-family
  86. )
  87. ),
  88. $headings
  89. );

name

$input-top-spacing

default

  1. 16px !default;

name

$line-height-root

default

  1. 1.5 !default;

name

$primary-transition

default

  1. 0.3s map-get($transition, 'swing') !default;

name

$ripple-animation-transition-in

default

  1. transform 0.25s map-get($transition, 'fast-out-slow-in'), opacity 0.1s map-get($transition, 'fast-out-slow-in') !default;

name

$ripple-animation-transition-out

default

  1. opacity 0.3s map-get($transition, 'fast-out-slow-in') !default;

name

$ripple-animation-visible-opacity

default

  1. 0.15 !default;

name

$secondary-transition

default

  1. 0.2s map-get($transition, 'ease-in-out') !default;

name

$spacer

default

  1. 4px !default;

name

$spacers

default

  1. @if (type-of($spacers) == list) {
  2. @for $i from 0 through 12 {
  3. $spacers: map-merge($spacers, ($i: $spacer * $i))
  4. }
  5. }
  6. $negative-spacers: () !default;

name

$text-field-active-label-height

default

  1. 12px !default;

name

$transition

default

  1. map-deep-merge(
  2. (
  3. 'fast-out-slow-in': cubic-bezier(0.4, 0, 0.2, 1),
  4. 'linear-out-slow-in': cubic-bezier(0, 0, 0.2, 1),
  5. 'fast-out-linear-in': cubic-bezier(0.4, 0, 1, 1),
  6. 'ease-in-out': cubic-bezier(0.4, 0, 0.6, 1),
  7. 'fast-in-fast-out': cubic-bezier(0.25, 0.8, 0.25, 1),
  8. 'swing': cubic-bezier(0.25, 0.8, 0.5, 1)
  9. ),
  10. $transition
  11. );

变量文件示例

下面是变量文件的示例:

  1. // src/sass/variables.scss
  2. // Globals
  3. $body-font-family: 'Work Sans', serif;
  4. $border-radius-root: 6px;
  5. $font-size-root: 14px;
  6. // Variables must come before the import
  7. $btn-letter-spacing: 0;
  8. $btn-font-weight: 400;
  9. $list-item-title-font-size: 0.929rem;
  10. $list-item-dense-title-font-size: 0.929rem;
  11. $list-item-dense-title-font-weight: initial;
  12. $fab-icon-sizes: (
  13. 'small': 20
  14. );
  15. $btn-sizes: (
  16. 'default': 41,
  17. 'large': 54
  18. );
  19. $headings: (
  20. 'h1': (
  21. 'size': 3.3125rem,
  22. 'line-height': 1.15em
  23. ),
  24. 'h2': (
  25. 'size': 2.25rem,
  26. 'line-height': 1.5em
  27. )
  28. );

组件中的使用

有两种方法可以在你的组件中导入和使用 Vuetify 变量,这两种方法提供了相同的结果。第一种方法是导入默认的框架样式文件:

如果你使用 预设 或根本 使用变量文件,这是首选的方法。

  1. <style lang="sass">
  2. @import '~vuetify/src/styles/styles.sass'
  3. @media #{map-get($display-breakpoints, 'md-and-down')}
  4. .custom-class
  5. display: none
  6. </style>

第二种方法是导入你的项目的 specific 变量文件。如果你使用自己的变量文件导入全局的 Vuetify 样式,建议使用这个方法。

  1. <style lang="scss">
  2. @import '@/path/to/variables.scss';
  3. .custom-class {
  4. border-radius: $border-radius-root;
  5. }
  6. </style>

请记住,在导入和使用变量文件时,你使用的 SASS 或 SCSS 这些语法 _并不重要_。

注意事项

使用 sass 变量时,有几个注意事项需要注意。

导入变量文件

当使用变量文件时,请确保你 定义或导入其他变量。引导的文件会被添加到每个组件中,并且会导致你的应用程序中的 CSS 重复。下面是 要这么做的一个例子。

  1. // src/styles/overrides.sass
  2. .v-btn
  3. text-transform: capitalize
  4. // src/styles/variables.scss
  5. // This will inject the overrides file into
  6. // every component that imports variables
  7. @import '@/styles/overrides.sass';
  8. $card-border-radius: 6px;
  9. $headings: (
  10. 'h1': (
  11. 'font-size': 2rem
  12. )
  13. );

编译时间

当使用变量时,你的应用程序的初始编译工作会增加。这是由于每当你对挂起的变量文件进行修改时,样式会实时更新。这种情况只有在初始编译步骤中才会出现,可以通过改变你从哪里导入 Vuetify 来改善。请记住,如果你的应用程序受到任何 Vuetify loader 限制 的影响,则此方法 将无法 正常使用;你的应用程序仍然可以运行,但不会得到性能的提升。

  1. // src/plugins/vuetify.js
  2. // CORRECT
  3. import Vuetify from 'vuetify/lib/framework'
  4. // INCORRECT
  5. import Vuetify, { VRow } from 'vuetify/lib/framework'
  6. export default new Vuetify()