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 目录下创建一个名为 sass
、scss
或 styles
的文件夹,文件名为 variables.scss
或 variables.sass
。vuetify-loader 会自动将你的变量引导到 Vue CLI 的编译过程中,覆盖框架的默认值。
当你运行 yarn serve 时,vuetify-cli-plugin 会自动将全局的 Vuetify 变量提升到你所有的 sass/scss 文件中。当对单个组件变量进行修改时,你仍然需要手动包含它的变量文件。你可以在下面找到一个 自定义变量 文件的例子。
Nuxt 安装
即将推出。如果你有兴趣在这部分的合作,请联系 社区 中的 _johnleider_。
Webpack 安装
本节假设你已经按照我们在 快速启动 页面上的 Webpack 指南进行了操作。这个选项会根据你所使用的 sass-loader 的版本而有所不同。确保你在设置 SASS/SCSS 数据选项时使用正确的语法,因为它们有不同的行尾。你可以在 sass-loader 的 Github 页面上找到更多关于 prependData 的信息。
// webpack.config.js
module.exports = {
module: {
rules: [
// SASS has different line endings than SCSS
// and cannot use semicolons in the markup
{
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// Requires sass-loader@^7.0.0
options: {
// This is the path to your variables
data: "@import '@/styles/variables.scss'"
},
// Requires sass-loader@^8.0.0
options: {
// This is the path to your variables
prependData: "@import '@/styles/variables.scss'"
},
},
],
},
// SCSS has different line endings than SASS
// and needs a semicolon after the import.
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// Requires sass-loader@^7.0.0
options: {
// This is the path to your variables
data: "@import '@/styles/variables.scss';"
},
// Requires sass-loader@^8.0.0
options: {
// This is the path to your variables
prependData: "@import '@/styles/variables.scss';"
},
},
],
},
],
},
}
Variable API
在整个 Vuetify 框架中,有很多 SASS/SCSS 变量可以被自定义。下面是一个自定义的 variables 文件的例子。你可以在下面找到更多关于可用的 变量 信息。
name
$blockquote-font-size
default
18px !default;
name
$blockquote-font-weight
default
300 !default;
name
$body-font-family
default
'Roboto', sans-serif !default;
name
$bootable-transition
default
0.2s map-get($transition, 'fast-out-slow-in') !default;
name
$border-radius-root
default
4px !default;
name
$code-color
default
#bd4147 !default;
name
$code-kbd-border-radius
default
3px !default;
name
$code-kbd-font-size
default
85% !default;
name
$code-kbd-font-weight
default
900 !default;
name
$color-pack
default
true !default;
name
$container-max-widths
default
map-deep-merge(
(
'md': map-get($grid-breakpoints, 'md') * 0.9375,
'lg': map-get($grid-breakpoints, 'lg') * 0.9375,
'xl': map-get($grid-breakpoints, 'xl') * 0.9375
),
$container-max-widths
);
name
$container-padding-x
default
$grid-gutter / 2 !default;
name
$display-breakpoints
default
map-deep-merge(
(
'print-only': 'only print',
'screen-only': 'only screen',
'xs-only': 'only screen and (max-width: #{map-get($grid-breakpoints, 'sm') - 1})',
'sm-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')}) and (max-width: #{map-get($grid-breakpoints, 'md') - 1})',
'sm-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'md') - 1})',
'sm-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')})',
'md-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')}) and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})',
'md-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})',
'md-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')})',
'lg-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')}) and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})',
'lg-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})',
'lg-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')})',
'xl-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'xl')})'
),
$display-breakpoints
);
name
$font-size-root
default
16px !default;
name
$font-weights
default
map-deep-merge(
(
'thin': 100,
'light': 300,
'regular': 400,
'medium': 500,
'bold': 700,
'black': 900
),
$font-weights
);
name
$form-grid-gutter
default
$spacer * 2 !default;
name
$grid-breakpoints
default
map-deep-merge(
(
'xs': 0,
'sm': 600px,
'md': 960px,
'lg': 1280px - 16px,
'xl': 1920px - 16px
),
$grid-breakpoints
);
name
$grid-columns
default
12 !default;
name
$grid-gutter
default
$spacer * 6 !default;
name
$grid-gutters
default
map-deep-merge(
(
'xs': $grid-gutter / 12,
'sm': $grid-gutter / 6,
'md': $grid-gutter / 3,
'lg': $grid-gutter * 2/3,
'xl': $grid-gutter
),
$grid-gutters
);
name
$heading-font-family
default
$body-font-family !default;
name
$headings
default
map-deep-merge(
(
'h1': (
'size': 6rem,
'weight': 300,
'line-height': 6rem,
'letter-spacing': -.015625em,
'font-family': $heading-font-family
),
'h2': (
'size': 3.75rem,
'weight': 300,
'line-height': 3.75rem,
'letter-spacing': -.0083333333em,
'font-family': $heading-font-family
),
'h3': (
'size': 3rem,
'weight': 400,
'line-height': 3.125rem,
'letter-spacing': normal,
'font-family': $heading-font-family
),
'h4': (
'size': 2.125rem,
'weight': 400,
'line-height': 2.5rem,
'letter-spacing': .0073529412em,
'font-family': $heading-font-family
),
'h5': (
'size': 1.5rem,
'weight': 400,
'line-height': 2rem,
'letter-spacing': normal,
'font-family': $heading-font-family
),
'h6': (
'size': 1.25rem,
'weight': 500,
'line-height': 2rem,
'letter-spacing': .0125em,
'font-family': $heading-font-family
),
'subtitle-1': (
'size': 1rem,
'weight': 400,
'line-height': 1.75rem,
'letter-spacing': .009375em,
'font-family': $body-font-family
),
'subtitle-2': (
'size': .875rem,
'weight': 500,
'line-height': 1.375rem,
'letter-spacing': .0071428571em,
'font-family': $body-font-family
),
'body-2': (
'size': .875rem,
'weight': 400,
'letter-spacing': .0178571429em,
'line-height': 1.25rem,
'font-family': $body-font-family
),
'body-1': (
'size': 1rem,
'weight': 400,
'letter-spacing': .03125em,
'line-height': 1.5rem,
'font-family': $body-font-family
),
'caption': (
'size': .75rem,
'weight': 400,
'letter-spacing': .0333333333em,
'line-height': 1.25rem,
'font-family': $body-font-family
),
'overline': (
'size': .625rem,
'weight': 400,
'letter-spacing': .1666666667em,
'line-height': 1rem,
'font-family': $body-font-family
)
),
$headings
);
name
$input-top-spacing
default
16px !default;
name
$line-height-root
default
1.5 !default;
name
$primary-transition
default
0.3s map-get($transition, 'swing') !default;
name
$ripple-animation-transition-in
default
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
opacity 0.3s map-get($transition, 'fast-out-slow-in') !default;
name
$ripple-animation-visible-opacity
default
0.15 !default;
name
$secondary-transition
default
0.2s map-get($transition, 'ease-in-out') !default;
name
$spacer
default
4px !default;
name
$spacers
default
@if (type-of($spacers) == list) {
@for $i from 0 through 12 {
$spacers: map-merge($spacers, ($i: $spacer * $i))
}
}
$negative-spacers: () !default;
name
$text-field-active-label-height
default
12px !default;
name
$transition
default
map-deep-merge(
(
'fast-out-slow-in': cubic-bezier(0.4, 0, 0.2, 1),
'linear-out-slow-in': cubic-bezier(0, 0, 0.2, 1),
'fast-out-linear-in': cubic-bezier(0.4, 0, 1, 1),
'ease-in-out': cubic-bezier(0.4, 0, 0.6, 1),
'fast-in-fast-out': cubic-bezier(0.25, 0.8, 0.25, 1),
'swing': cubic-bezier(0.25, 0.8, 0.5, 1)
),
$transition
);
变量文件示例
下面是变量文件的示例:
// src/sass/variables.scss
// Globals
$body-font-family: 'Work Sans', serif;
$border-radius-root: 6px;
$font-size-root: 14px;
// Variables must come before the import
$btn-letter-spacing: 0;
$btn-font-weight: 400;
$list-item-title-font-size: 0.929rem;
$list-item-dense-title-font-size: 0.929rem;
$list-item-dense-title-font-weight: initial;
$fab-icon-sizes: (
'small': 20
);
$btn-sizes: (
'default': 41,
'large': 54
);
$headings: (
'h1': (
'size': 3.3125rem,
'line-height': 1.15em
),
'h2': (
'size': 2.25rem,
'line-height': 1.5em
)
);
组件中的使用
有两种方法可以在你的组件中导入和使用 Vuetify 变量,这两种方法提供了相同的结果。第一种方法是导入默认的框架样式文件:
如果你使用 预设 或根本 不 使用变量文件,这是首选的方法。
<style lang="sass">
@import '~vuetify/src/styles/styles.sass'
@media #{map-get($display-breakpoints, 'md-and-down')}
.custom-class
display: none
</style>
第二种方法是导入你的项目的 specific 变量文件。如果你使用自己的变量文件导入全局的 Vuetify 样式,建议使用这个方法。
<style lang="scss">
@import '@/path/to/variables.scss';
.custom-class {
border-radius: $border-radius-root;
}
</style>
请记住,在导入和使用变量文件时,你使用的 SASS 或 SCSS 这些语法 _并不重要_。
注意事项
使用 sass 变量时,有几个注意事项需要注意。
导入变量文件
当使用变量文件时,请确保你 只 定义或导入其他变量。引导的文件会被添加到每个组件中,并且会导致你的应用程序中的 CSS 重复。下面是 不 要这么做的一个例子。
// src/styles/overrides.sass
.v-btn
text-transform: capitalize
// src/styles/variables.scss
// This will inject the overrides file into
// every component that imports variables
@import '@/styles/overrides.sass';
$card-border-radius: 6px;
$headings: (
'h1': (
'font-size': 2rem
)
);
编译时间
当使用变量时,你的应用程序的初始编译工作会增加。这是由于每当你对挂起的变量文件进行修改时,样式会实时更新。这种情况只有在初始编译步骤中才会出现,可以通过改变你从哪里导入 Vuetify 来改善。请记住,如果你的应用程序受到任何 Vuetify loader 限制 的影响,则此方法 将无法 正常使用;你的应用程序仍然可以运行,但不会得到性能的提升。
// src/plugins/vuetify.js
// CORRECT
import Vuetify from 'vuetify/lib/framework'
// INCORRECT
import Vuetify, { VRow } from 'vuetify/lib/framework'
export default new Vuetify()