Working with CSS #
Vue CLI projects come with support for PostCSS, CSS Modules and pre-processors including Sass, Less and Stylus.
Referencing Assets #
All compiled CSS are processed by css-loader, which parses url() and resolves them as module requests. This means you can refer to assets using relative paths based on the local file structure. Note if you want to reference a file inside an npm dependency or via webpack alias, the path must be prefixed with ~ to avoid ambiguity. See Static Asset Handling for more details.
Pre-Processors #
You can select pre-processors (Sass/Less/Stylus) when creating the project. If you did not do so, the internal webpack config is still pre-configured to handle all of them. You just need to manually install the corresponding webpack loaders:
# Sass npm install -D sass-loader sass # Less npm install -D less-loader less # Stylus npm install -D stylus-loader stylus
Note on webpack 4
When using webpack version 4, the default in Vue CLI 4, you need to make sure your loaders are compatible with it. Otherwise you will get errors about confliciting peer dependencies. In this case you can use an older version of the loader that is still compatible with webpack 4.
# Sass npm install -D sass-loader@^10 sass
Then you can import the corresponding file types, or use them in *.vue files with:
style lang="scss"> $color: red; style>
A Tip on Sass Performance
Note that when using Dart Sass, synchronous compilation is twice as fast as asynchronous compilation by default, due to the overhead of asynchronous callbacks. To avoid this overhead, you can use the fibers package to call asynchronous importers from the synchronous code path. To enable this, simply install fibers as a project dependency:
npm install -D fibers
Please also be aware, as it’s a native module, there may be compatibility issues vary on the OS and build environment. In that case, please run npm uninstall -D fibers to fix the problem.
Automatic imports #
If you want to automatically import files (for colors, variables, mixins. ), you can use the style-resources-loader. Here is an example for stylus that imports ./src/styles/imports.styl in every SFC and every stylus files:
// vue.config.js const path = require('path') module.exports = chainWebpack: config => const types = ['vue-modules', 'vue', 'normal-modules', 'normal'] types.forEach(type => addStyleResource(config.module.rule('stylus').oneOf(type))) >, > function addStyleResource (rule) rule.use('style-resource') .loader('style-resources-loader') .options( patterns: [ path.resolve(__dirname, './src/styles/imports.styl'), ], >) >
PostCSS #
Vue CLI uses PostCSS internally.
You can configure PostCSS via .postcssrc or any config source supported by postcss-load-config, and configure postcss-loader via css.loaderOptions.postcss in vue.config.js .
The autoprefixer plugin is enabled by default. To configure the browser targets, use the browserslist field in package.json .
Note on Vendor-prefixed CSS Rules
In the production build, Vue CLI optimizes your CSS and will drop unnecessary vendor-prefixed CSS rules based on your browser targets. With autoprefixer enabled by default, you should always use only non-prefixed CSS rules.
CSS Modules #
To import CSS or other pre-processor files as CSS Modules in JavaScript, the filename should end with .module(s).(css|less|sass|scss|styl) :
import styles from './foo.module.css' // works for all supported pre-processors as well import sassStyles from './foo.module.scss'
If you want to drop the .module in the file names and treat all style files as CSS Modules, you need to configure the css-loader option as follows:
// vue.config.js module.exports = css: loaderOptions: css: modules: auto: () => true > > > > >
If you wish to customize the generated CSS Modules class names, you can do so via css.loaderOptions.css in vue.config.js , too. All css-loader options are supported here:
// vue.config.js module.exports = css: loaderOptions: css: // Note: the following config format is different between different Vue CLI versions // See the corresponding css-loader documentation for more details. // Vue CLI v3 uses css-loader v1: https://www.npmjs.com/package/css-loader/v/1.0.1 // Vue CLI v4 uses css-loader v3: https://www.npmjs.com/package/css-loader/v/3.6.0 // Vue CLI v5 uses css-loader v5: https://github.com/webpack-contrib/css-loader#readme modules: localIdentName: '[name]-[hash]' exportLocalsConvention: 'camelCaseOnly' > > > > >
Passing Options to Pre-Processor Loaders #
Sometimes you may want to pass options to the pre-processor’s webpack loader. You can do that using the css.loaderOptions option in vue.config.js . For example, to pass some shared global variables to all your Sass/Less styles:
// vue.config.js module.exports = css: loaderOptions: // pass options to sass-loader // @/ is an alias to src/ // so this assumes you have a file named `src/variables.sass` // Note: this option is named as "prependData" in sass-loader v8 sass: additionalData: `@import "~@/variables.sass"` >, // by default the `sass` option will apply to both syntaxes // because `scss` syntax is also processed by sass-loader underlyingly // but when configuring the `prependData` option // `scss` syntax requires an semicolon at the end of a statement, while `sass` syntax requires none // in that case, we can target the `scss` syntax separately using the `scss` option scss: additionalData: `@import "~@/variables.scss";` >, // pass Less.js Options to less-loader less: // http://lesscss.org/usage/#less-options-strict-units `Global Variables` // `primary` is global variables fields name globalVars: primary: '#fff' > > > > >
Loaders which can be configured via loaderOptions include:
This is preferred over manually tapping into specific loaders using chainWebpack , because these options need to be applied in multiple locations where the corresponding loader is used.
Работа с CSS #
Проекты Vue CLI предоставляют поддержку для PostCSS, CSS-модулей, а также пре-процессоров, включая Sass, Less и Stylus.
Указание ссылок на ресурсы #
Весь скомпилированный CSS обрабатывается css-loader, который будет парсить url() и разрешать их как зависимостями модуля. Это означает, что вы можете ссылаться на ресурсы, используя относительные пути на основе локальной файловой структуры. Обратите внимание, что если вы хотите ссылаться на файл внутри npm-зависимости или через псевдоним webpack, путь должен начинаться с префикса ~ для избежания двусмысленности. Подробнее в разделе Обработка статических ресурсов.
Пре-процессоры #
Вы можете выбрать пре-процессоры (Sass/Less/Stylus) при создании проекта. Если вы этого не сделали, то внутренняя конфигурация webpack всё равно настроена для их использования. Вам лишь требуется вручную доустановить соответствующие загрузчики для webpack:
# Sass npm install -D sass-loader sass # Less npm install -D less-loader less # Stylus npm install -D stylus-loader stylus
Примечание при использовании webpack 4
При использовании webpack версии 4, по умолчанию во Vue CLI 4, следует убедиться в совместимости используемых загрузчиков. В противном случае будут появляться ошибки о конфликтующих зависимостях. В таких случаях можно использовать более старую версию загрузчика, которая всё ещё совместима с webpack 4.
# Sass npm install -D sass-loader@^10 sass
Теперь вы можете импортировать соответствующие типы файлов, или использовать их синтаксис внутри файлов *.vue с помощью:
style lang="scss"> $color: red; style>
Совет по производительности Sass
Обратите внимание, при использовании Dart Sass синхронная компиляция вдвое быстрее асинхронной по умолчанию, из-за накладных расходов на асинхронные коллбэки. Чтобы избежать их можно воспользоваться пакетом fibers для вызова асинхронных импортёров по пути синхронного кода. Для этого просто установите fibers в качестве зависимости проекта:
npm install -D fibers
Также имейте в виду, поскольку это нативный модуль, то могут возникнуть различные проблемы совместимости, в зависимости от ОС и окружения сборки. В таких случаях выполните npm uninstall -D fibers для устранения проблемы.
Автоматические импорты #
Если вы хотите автоматически импортировать файлы (для цветов, переменных, примесей. ), можно использовать style-resources-loader. Вот пример для stylus, который импортирует ./src/styles/imports.styl в каждый однофайловый компонент и в каждый файл stylus:
// vue.config.js const path = require('path') module.exports = chainWebpack: config => const types = ['vue-modules', 'vue', 'normal-modules', 'normal'] types.forEach(type => addStyleResource(config.module.rule('stylus').oneOf(type))) >, > function addStyleResource (rule) rule.use('style-resource') .loader('style-resources-loader') .options( patterns: [ path.resolve(__dirname, './src/styles/imports.styl'), ], >) >
PostCSS #
Vue CLI использует PostCSS внутри себя.
Вы можете настроить PostCSS через .postcssrc или любую другую конфигурацию, которая поддерживается postcss-load-config, а также настраивать postcss-loader через опцию css.loaderOptions.postcss в файле vue.config.js .
Плагин autoprefixer включён по умолчанию. Чтобы определить целевые браузеры используйте поле browserslist в файле package.json .
Примечание о префиксных CSS правилах
В сборке для production Vue CLI оптимизирует ваш CSS и удаляет ненужные префиксные правила CSS, основываясь на целевых браузерах. С autoprefixer включённым по умолчанию, вы должны всегда использовать только CSS-правила без префиксов.
CSS-модули #
Для импорта CSS или других файлов пре-процессоров в качестве CSS-модулей в JavaScript, необходимо чтобы имя файла заканчивалось на .module.(css|less|sass|scss|styl) :
import styles from './foo.module.css' // работает для всех поддерживаемых пре-процессоров import sassStyles from './foo.module.scss'
Если вы не хотите указывать .module в именах файлов, установите css.requireModuleExtension в false внутри файла vue.config.js :
// vue.config.js module.exports = css: requireModuleExtension: false > >
Если вы хотите настроить генерируемые имена классов для CSS-модулей, вы можете сделать это с помощью опции css.loaderOptions.css в vue.config.js . Все настройки css-loader поддерживаются, например localIdentName и camelCase :
// vue.config.js module.exports = css: loaderOptions: css: // Примечание: формат конфигурации отличается между Vue CLI v4 и v3 // Для пользователей Vue CLI v3, обратитесь к документации css-loader v1 // https://github.com/webpack-contrib/css-loader/tree/v1.0.1 modules: localIdentName: '[name]-[hash]' >, localsConvention: 'camelCaseOnly' > > > >
Передача настроек в загрузчики пре-процессоров #
Иногда может возникнуть необходимость передать настройки в загрузчик пре-процессора для webpack. Вы можете сделать это с помощью опции css.loaderOptions в vue.config.js . Например, для передачи глобальных переменных во все стили Sass/Less:
// vue.config.js module.exports = css: loaderOptions: // передача настроек в sass-loader // @/ это псевдоним к каталогу src/ поэтому предполагается, // что у вас в проекте есть файл `src/variables.scss` // Примечание: эта опция называется "prependData" в sass-loader v8 sass: additionalData: `@import "~@/variables.sass"` >, // по умолчанию опция `sass` будет применяться к обоим синтаксисам // потому что синтаксис `scss` по сути также обрабатывается sass-loader // но при настройке опции `prependData` синтаксис `scss` требует точку с запятой // в конце оператора, в то время как для `sass` точки с запятой не требуется // в этом случае синтаксис `scss` можно настроить отдельно с помощью опции `scss` scss: additionalData: `@import "~@/variables.scss";` >, // передача настроек Less.js в less-loader less: // http://lesscss.org/usage/#less-options-strict-units `Global Variables` // `primary` — имя поля глобальных переменных globalVars: primary: '#fff' > > > > >
Загрузчики которые можно настраивать с помощью опции loaderOptions :
Это предпочтительнее, чем вручную обращаться к конкретным загрузчикам, используя chainWebpack , потому что настройки необходимо применять в нескольких местах, где используется соответствующий загрузчик.
VueJS: где лучше хранить css, в компонентах .vue или main.css?
main.css
Плюсы:
— единый файл для стилей
— общие свойства можно объявлять сразу нескольким тегам, и быстро исправлять
— компоненты проще переносить из проекта в проект (нет излишних стилей)
Минусы:
— с ростом проекта его труднее читать и редактировать
— все равно иногда нужно добавить стиль в компонент, но это усложняет правку стилей еще больше
css в компонентах
Плюсы:
— хорошая инкапсуляция стилей
— не нужны методологии (БЭМ. )
— простота переноса из проекта в проект
Минусы:
— избыточность. Простые свойства могут повторяться почти в каждом компоненте
— сложность правки общих свойств
Как вариант, можно очень общие теги (body, a, p . ) описывать в main.css, все остальное — в компонентах.
Как делаете Вы и почему? Есть ли лучшие практики в оформлении при работе с компонентами?
- Вопрос задан более трёх лет назад
- 16985 просмотров
Комментировать
Решения вопроса 4
Сергей delphinpro @delphinpro Куратор тега CSS
frontend developer
В Vue приложении используем препроцессор (scss). Кроме того используем внешние пакеты для вертикального ритма и сетки.
Хочется хранить стили в однофайловых компонентах, при этом имея возможность определить глобально часть sass-переменных, кое-какие миксины и функции. Также нужно как-то подключить миксины сетки и ритма, возможно подключать стили от сторонних пакетов.
Вариант импортировать scss-файл с определениями в каждом компоненте сразу откинули, ибо люди мы ленивые.
Что делаем:
Подключаем в точке входа (main.js) основной стилевой файл:
import '@/styles/main.scss'; import Vue from 'vue'; //.
В нем подключаем всякое-разное-глобальное-базовое:
@import "base/normalize"; @import "base/init"; @import "base/typography"; @import "base/code"; @import "base/links"; @import "base/tables"; @import "base/buttons"; @import "base/control-group"; @import "base/general-form"; @import "parts/transitions"; .
Далаем два файла: env-development.scss и env-production.scss
$NODE_ENV: development; @import "cfg-vars";
$NODE_ENV: production; @import "cfg-vars";
Переменная $NODE_ENV нам нужно. чтобы управлять стилями в зависимости от окружения.
Дальше в cfg-vars.scss подключаем/пишем все необходимые глобальные конфиги
$DEV_MODE: $NODE_ENV == development; $MAX_INT32: 2147483647; @import "cfg-vrhythm"; @import "cfg-grid"; @import "../../../node_modules/vrhythm/source/vrhythm"; @import "../../../node_modules/bs-grid-system/source/scss/bs-grid"; @import "../mixins"; @import "cfg-z-indexes"; $wt-family-base: "Open Sans", sans-serif; $wt-family-head: "Roboto Slab", serif; $font-family-monospace: "Fira Code", Menlo, Monaco, Consolas, "Courier New", monospace; //== //== Color palette //== ======================================= ==// $palette-light-blue: #3c8dbc; // Primary $palette-red : #dd4b39; // Danger $palette-green : #00a65a; // Success $palette-aqua : #00c0ef; // Info $palette-yellow : #f39c12; // Warning .
Почти всё готово. Осталось только автоматически подключить эти конфиги к сборке.
Идём в vue.config.js и добавляем секцию css:
const NODE_ENV = process.env.NODE_ENV === 'development' ? 'development' : 'production'; //. module.exports = < //. css: < extract: NODE_ENV === 'production', loaderOptions: < sass: < data: `@import "@/styles/config/env-$.scss";`, >, >, >, >;
Теперь мы спокойно пишем стили компонентов на scss прямо vue-файлах, и оставляем возможность какие-то стили писать в отдельных файлах.
Ответ написан более трёх лет назад
Нравится 17 6 комментариев
floydback @floydback Автор вопроса
Спасибо! Очень интересно стало для чего вам разные стили в разных средах?

Сергей delphinpro @delphinpro Куратор тега CSS
floydback, в основном использую разные миксины для визуализации чего-либо при верстке, чего не должно быть в конечном продукте, или добавляю какие служебные классы через if.
@mixin outline() < @if $NODE_ENV == 'development' < outline: 1px doted red; >> @if $NODE_ENV == 'development' < .some-debug-class < // . >>
Таким образом, даже если я забуду удалить отладочный код из исходников, он точно не попадет в сборку.
Сергей delphinpro, Сергей, добрый день!
Скажите, существует ли способ задать где-то в одном месте $переменную и использовать её внутри scoped стилей компонентов?

Сергей delphinpro @delphinpro Куратор тега CSS
vogordin, я скоуп-стили не использую. Но думаю, что описанный способ вполне должен подойти.
немного поменялся файл конфигурации
теперь вместо data prependData
// vue.config.js module.exports = < css: < loaderOptions: < // передача настроек в sass-loader // @/ это псевдоним к каталогу src/ поэтому предполагается, // что у вас в проекте есть файл `src/variables.scss` // Примечание: эта опция называется "prependData" в sass-loader v8 sass: < additionalData: `@import "~@/variables.sass"` >, // по умолчанию опция `sass` будет применяться к обоим синтаксисам // потому что синтаксис `scss` по сути также обрабатывается sass-loader // но при настройке опции `prependData` синтаксис `scss` требует точку с запятой // в конце оператора, в то время как для `sass` точки с запятой не требуется // в этом случае синтаксис `scss` можно настроить отдельно с помощью опции `scss` scss: < additionalData: `@import "~@/variables.scss";` >, // передача настроек Less.js в less-loader less:< // http://lesscss.org/usage/#less-options-strict-units `Global Variables` // `primary` — имя поля глобальных переменных globalVars: < primary: '#fff' >> > > >

Спасибо вам, то, что нужно!
quadabrashell @quadabrashell
Vue-way — хранить стили в .vue , для того оно и придумано. Компонентный подход улучшает восприятие кода.
css-файл можно оставить только если, например, он уже остался от верстальщика и лень раскидывать по компонентам.
Ответ написан более трёх лет назад
Нравится 6 2 комментария
floydback @floydback Автор вопроса
А общие стили, такие как
вы где храните, в App.vue?
quadabrashell @quadabrashell

Владимир Сартаков @Arhangel7b
1. Используем препроцессор, любой: sass, less, stylus
2. Общие стили(все что используется или может использоваться часто) в общее.
Один файл точка входа, в него импортируется другие файлы с общими стилями.
Файлы с общими стилями, максимально разбиты, по назначению, разделам. Зависит от проекта. На огромных проэктах, можно дополнительно по подпапкам разбивать. Главное что бы удобно было в этом ориентироваться.
Все общие переменные обязательно в отдельный файл*
Все общие миксины обязательно в отдельный файл*
** Дает возможность быстро изменить препроцессор, если понадобится. У всех разные синтаксис переменных и миксинов
Если миксин статичный, без параметров, лучше заменить его на класс, например .some-mixin-class
И использовать его так:
.some-class @extend .some-mixin-class;
.
>
При этом .some-mixin-class нельзя использовать как обычный класс напримую, только экстендить в других классах
@extend .some-mixin-class — Работает одинаково во всех препроцессорах и хорошо читается
Все общие стили только по БЕМ
3. Специфичные стили для компонента пишем в файле компонента.
Или scoped или БЕМ — как удобней
Если таких стилей очень много, то выносим в отдельный файл и импортируем в компаненте
В эти стили по необходимости(если нужно использовать) и импортируем файл с общими переменными или миксинами
Самое сложное, научится определять, что общее а что специфичное, это не объяснить. Приходит с опытом и постепенно
