Как подключить внешний css файл в vue

Обновлено: 03.07.2024

Совершенно очевидно, что CSS далёк от совершенства. При разработке больших комплексных проектов глобальная природа CSS легко может привести к появлению конфликтующих стилей, а наследование часто приводит к тому, что стили применяются не к тем, вернее не только к тем, элементам, которые мы имели в виду. Справедливости ради следует отметить, что большинство подобных ошибок возникает от непонимания особенностей CSS разработчиками. Но это не отменяет того факта, что указанные недостатки у CSS имеются, и даже опытный разработчик может стать их жертвой.

Чаще всего для борьбы с глобальной природой CSS используется методология БЭМ (Блок Элемент Модификатор). Но это решает только небольшую часть проблемы.

Каждое Vue.js приложение, созданное с помощью vue-cli, уже имеет на вооружении два мощных инструмента: Изолированный CSS (Scoped CSS) и CSS Модули. У каждого из них есть свои преимущества и недостатки. Давайте рассмотрим подробнее и определимся с тем, какое решение подойдёт вам.

Изолированные стили

Для подключения изолированных стилей необходимо добавить атрибут scoped в тэг style:

Это приведёт к тому, что стили применятся только к элементам компонента. В результате в скомпилированном виде стили будут выглядеть вот так:

Как видите это довольно просто. Всего одно слово — и у вас есть изолированные стили для компонента.

Теперь, если нужно, например, поменять ширину компонента на какой-то странице, просто добавляем класс и стилизуете его как необходимо:

Это превратится в:

И опять, без малейших усилий вы полностью контролируете стили.

Однако, у этого метода есть один серьёзный недостаток — если у корневого элемента дочернего компонента есть такой класс, как у родителя, то стили родителя применятся к дочернему компоненту. Посмотрите этот пример, чтобы увидеть это на практике.

Также использование изолированных классов не рекомендуется если нужно стилизовать что-то в дочернем компоненте, но сделать это необходимо из родительского компонента. Для простоты, предположим, что родительский компонент отвечает за стили хедера компонента BasePanel. В изолированных стилях для этого используется комбинатор >>> .

Это превратится в:

Легко и просто, да? Вот только при этом мы полностью потеряли инкапсуляцию. Любой элемент с классом .title внутри этого родительского компонента унаследует эти стили.

CSS Модули

CSS Модули стали очень популярны благодаря коммьюнити React, которое активно использует и развивает этот инструмент. Vue.js, в свою очередь, выводит его на новый уровень, объединяя мощь с простотой использования и поддержкой «из коробки» при использовании vue-cli.

Давайте посмотрим, как использовать CSS модули:

Тут всё не намного сложнее, чем при использовании изолированных стилей. Вместо атрибута scoped мы используем атрибут module. Этот атрибут сообщает компилятору шаблонов, что необходимо использовать соответствующий загрузчик, который сгенерирует следующий CSS:

Чем же модули в итоге отличаются от изолированных стилей? Тем, что при использовании модулей классы, объявленные в CSS, доступны через объект $style. Поэтому шаблон будет выглядеть вот так:

Это сгенерирует следующий HTML и стили:

Одно из преимуществ CSS модулей в том, что глядя на элемент в HTML мы сразу видим какому компоненту он принадлежит. Второе преимущество — всё работает очень предсказуемо и мы полностью контролируем процесс. Однако, необходимо проявлять осторожность при стилизации HTML тэгов. В отличие от изолированных стилей, при использовании CSS модулей стилизованные тэги в финальном файле будут стилизованы как есть (без уникального атрибута data), и окажут влияние на всё приложение. В любом случае, стилизовать тэги напрямую — плохая идея.

Теперь давайте посмотрим как стилизовать компонент в зависимости от контекста:

Это превратится в:

Всё работает как должно, без сюрпризов. Более того, так как все классы доступны через объект $style, мы можем передавать их как угодно глубоко с помощью props:

Представьте, что вы делает график и храните переменные с цветами в CSS. Вы можете экспортировать их для использования в компоненте:

Мы взглянули на очень небольшую часть того, что могут CSS модули. Их возможности гораздо шире и я настоятельно рекомендую вам ознакомиться с полной спецификацией.

Заключение

Оба решения очень просты в использовании и отлично выполняют свою задачу. Какое же выбрать?

Изолированные стили не требуют дополнительных знаний. Имеющиеся у них ограничения делают их использование очень простым. Они отлично подойдут для проектов небольшого и среднего размера.

Однако, когда речь идёт о комплексных сценариях и крупных приложениях, мы хотим иметь полный контроль над тем, что творится в нашем CSS. Даже тот факт, что многократное использование $style сделает ваш код немного менее читабельным, не перевесит той уверенности и гибкости, которую дают CSS модули.

, который будет парсить url() и разрешать их как зависимостями модуля. Это означает, что вы можете ссылаться на ресурсы, используя относительные пути на основе локальной файловой структуры. Обратите внимание, что если вы хотите ссылаться на файл внутри npm-зависимости или через псевдоним webpack, путь должен начинаться с префикса

для избежания двусмысленности. Подробнее в разделе Обработка статических ресурсов.

Вы можете выбрать пре-процессоры (Sass/Less/Stylus) при создании проекта. Если вы этого не сделали, то внутренняя конфигурация webpack всё равно настроена для их использования. Вам лишь требуется вручную доустановить соответствующие загрузчики для webpack:

Примечание при использовании webpack 4

При использовании webpack версии 4, по умолчанию во Vue CLI 4, следует убедиться в совместимости используемых загрузчиков. В противном случае будут появляться ошибки о конфликтующих зависимостях. В таких случаях можно использовать более старую версию загрузчика, которая всё ещё совместима с webpack 4.

Теперь вы можете импортировать соответствующие типы файлов, или использовать их синтаксис внутри файлов *.vue с помощью:

Совет по производительности Sass

Обратите внимание, при использовании Dart Sass синхронная компиляция вдвое быстрее асинхронной по умолчанию, из-за накладных расходов на асинхронные коллбэки. Чтобы избежать их можно воспользоваться пакетом fibers

для вызова асинхронных импортёров по пути синхронного кода. Для этого просто установите fibers в качестве зависимости проекта:

Также имейте в виду, поскольку это нативный модуль, то могут возникнуть различные проблемы совместимости, в зависимости от ОС и окружения сборки. В таких случаях выполните npm uninstall -D fibers для устранения проблемы.

Если вы хотите автоматически импортировать файлы (для цветов, переменных, примесей. ), можно использовать style-resources-loader

. Вот пример для stylus, который импортирует ./src/styles/imports.styl в каждый однофайловый компонент и в каждый файл stylus:

Vue CLI использует PostCSS внутри себя.

Вы можете настроить PostCSS через .postcssrc или любую другую конфигурацию, которая поддерживается postcss-load-config

через опцию css.loaderOptions.postcss в файле vue.config.js .

включён по умолчанию. Чтобы определить целевые браузеры используйте поле browserslist в файле package.json .

Примечание о префиксных CSS правилах

В сборке для production Vue CLI оптимизирует ваш CSS и удаляет ненужные префиксные правила CSS, основываясь на целевых браузерах. С autoprefixer включённым по умолчанию, вы должны всегда использовать только CSS-правила без префиксов.

доступны из коробки с помощью <style module> .

Для импорта CSS или других файлов пре-процессоров в качестве CSS-модулей в JavaScript, необходимо чтобы имя файла заканчивалось на .module.(css|less|sass|scss|styl) :

Если вы не хотите указывать .module в именах файлов, установите css.requireModuleExtension в false внутри файла vue.config.js :

Если вы хотите настроить генерируемые имена классов для CSS-модулей, вы можете сделать это с помощью опции css.loaderOptions.css в vue.config.js . Все настройки css-loader поддерживаются, например localIdentName и camelCase :

Иногда может возникнуть необходимость передать настройки в загрузчик пре-процессора для webpack. Вы можете сделать это с помощью опции css.loaderOptions в vue.config.js . Например, для передачи глобальных переменных во все стили Sass/Less:

Загрузчики которые можно настраивать с помощью опции loaderOptions :

Это предпочтительнее, чем вручную обращаться к конкретным загрузчикам, используя chainWebpack , потому что настройки необходимо применять в нескольких местах, где используется соответствующий загрузчик.

Изучаю vue первый день. Не могу разобраться. Хочу подключить библиотеку element-ui.
Простой HelloWorld:


Если задать явно "import 'element-ui/lib/theme-chalk/index.css'" то всё работает.

Но разве так правильно делать, стиль в js подключать? Я убрал import css из app.js.
Потом, добавляю в начало app.scss строку import '

element-ui/lib/theme-chalk/index'; Всё компилируется, но стили не применяются. Как такое может быть?

Ещё пара вопросов вдогонку:
1) Как вообще правильно подключать стили компонента? Писать style тег во .vue / импортировать из .vue / подгружать вебпапом отдельно в app.scss?

2) Есть ли какая-то разница между import (default) и require при использовании webpack (laravel mix)?

  • Вопрос задан более трёх лет назад
  • 831 просмотр

kleinmaximus

Импортировать стили надо там же, где Вы подключаете саму библиотеку. Ни к чему разносить это в разные части кода. Если Вам мозолят глаза расширения .css в js-коде основной программы, то можете сделать отдельный модуль, который будет подключать как саму библиотеку Element-ui, так и стили, а уже этот модуль подключать в свое приложение. А вообще в документации довольно подробно описано как подключать стили, и почему сделано именно так.

Кстати, а что такое app.scss, и как оно у Вас подключается?

1) Как вообще правильно подключать стили компонента? Писать style тег во .vue / импортировать из .vue / подгружать вебпапом отдельно в app.scss?
2) Есть ли какая-то разница между import (default) и require при использовании webpack (laravel mix)?

Это разные системы модулей - подробнее об этом (и не только) здесь. Советую изучить все материалы из данного учебника - вопросов у Вас будет на много меньше :)
Кстати, а что такое app.scss, и как оно у Вас подключается?

Я создал единый файл app.scss, где внутри подключаю все используемые стили из node_modules + свои, минимизирую вебпаком и подключаю уже типа app.min.css где всё

Плохой подход? Поэтому и возник вопрос о необходимости импортировать стили именно из vue.

kleinmaximus

l4m3r, ознакомьтесь, как ведется работа с css в vue-cli-3.
Так же предлагаю посмотреть документацию по vue-loader, в опять же по загрузке css.

Вообще, в экоситеме vue достаточно много решений, которые позволяют не отвлекаться на написания своих реализаций, а использовать готовое.

Если Вам удобно объединять все css в одном файле, и после перерыва в работе с конкретным кодом Вы сразу можете найти нужное место и быстро вспомнить, где и что лежит, то скорее всего, Вы выбрали правильный подход именно для себя.

Но все же лучше все требуемые компоненты сторонней библиотеки подключать где-то рядом. Вы ведь не можете быть уверены, что с Вашим кодом в будущем не будет работать другой программист. Сделайте код удобным и для него, разместите все подключения, относящиеся к конкретной библиотеке в одном месте, ведь он может не знать, что надо заглянуть куда-то еще.

Например, если нужно Вам подключить element-ui , но не хочется, чтобы расширения css встречались в основном js-файле, то можно создать отдельный js-модуль:

И в главном файле уже вместо import Element from 'element-ui'; подключить именно его.
Это как вариант.

От автора: давайте посмотрим, как можно оптимизировать взаимодействие Vue Sass. Если вы работаете над крупномасштабным приложением Vue, скорее всего, вам захочется организовать структуру приложения так, чтобы у вас были некоторые глобально определенные переменные для CSS, которые вы можете использовать в любой части приложения.

Это может быть достигнуто путем написания этого фрагмента кода в каждом компоненте приложения:

Но у кого есть время на это ?! Мы программисты, поэтому давайте сделаем это программно.


Фреймворк VUE JS: быстрый старт

Получите бесплатный курс и узнайте, как создать веб-приложение на трендовой Frontend-технологии VUE JS с полного нуля

Для чего?

Возможно, вам интересно, для чего нам делать что-то подобное, особенно если вы только начинаете заниматься веб-разработкой. Глобально это не есть хорошо, не так ли? Зачем нам это нужно? Что такое переменные Sass? Если вы уже все это знаете, вы можете перейти к следующему разделу, посвященному реализации.

Крупные и малые компании, как правило, выполняют редизайн, по крайней мере, каждые 1-2 года. Если ваша база кода большая, она управляется многими людьми, и вам нужно везде изменить высоту строки с 1.1rem на 1.2rem, действительно ли вы должны возвращаться в каждый модуль и изменять это значение? Здесь нужна глобальная переменная. Вы решаете, что может быть на верхнем уровне и что нужно унаследовать для других, меньших частей. Это позволяет избежать спагетти-кода в CSS и сохраняет код чистым.

Я когда-то работал в компании, у которой была гигантская постоянно расширяющаяся база код. За день до крупного релиза сверху спускались приказы, чтобы мы поменяли основной цвет бренда. Поскольку база кода была правильно настроена с определенными переменными, я мог изменить цвет в одном месте и это изменение распространялось на 4000 файлов. Это довольно мощно. Мне также не нужно было пересматривать все подряд, чтобы ввести изменения.

Глобальные определения могут быть само-проверяемыми для дизайнеров: «Подождите, у нас есть еще одна вспомогательная кнопка? Для чего?» Эта практика согласованности UI / UX хорошо себя зарекомендовали.

Читайте также: