[JavaScript, VueJS] Nuxt.js app от UI-кита до деплоя. Часть 2: Темная тема
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Привет, Хабр!
Публикуем вторую часть серии статей о создании современного блога на Nuxt.js. Сегодня реализуем темную тему в приложении, которое мы написали вместе с вами в первой части.
Обратите внимание, что код каждой части можно найти в собственной ветке на Github, а в master доступна версия приложения из последней опубликованной статьи.
Что такое темная тема?
Темная тема — это цветовая схема любого интерфейса, которая отображает светлый текст и элементы интерфейса на темном фоне, что упрощает просмотр экрана на мобильных телефонах, планшетах и компьютерах при плохой освещенности. Темная тема уменьшает свет, излучаемый экраном, при сохранении минимального соотношения цветового контраста, необходимого для удобочитаемости.
Темная тема улучшает визуальную эргономику, снижая нагрузку на глаза, настраивая экран в соответствии с текущими условиями освещения и обеспечивая простоту использования в ночное время или в темноте.
Также нельзя забывать о том, что использование темной темы в веб- и мобильных приложениях может продлить срок службы батареи устройства. Компания Google подтвердила, что темная тема на OLED экранах очень помогает продлить срок службы батареи.
@nuxtjs/color-mode
Для реализации темной темы мы будем использовать модуль @nuxtjs/color-mode, который предоставляет следующие возможности:
- добавляет класс .${color}-mode к тегу <html> для упрощения управлением темами CSS;
- работает в любом режиме Nuxt (static, ssr или spa);
- автоматически определяет цветовой режим системы на устройстве пользователя и может установить соответствующую тему, исходя из этих данных;
- позволяет синхронизировать выбранную тему между вкладками и окнами;
- позволяет использовать реализованные темы для отдельных страниц, а не для всего приложения (идеально подходит для постепенной разработки);
- также модуль поддерживает IE9+ (не уверен, что это всё еще актуально в современной разработке, но кому-то может пригодиться).
Для начала установим модуль:
npm i --save-dev @nuxtjs/color-mode
А затем добавим добавим информацию об этом модуле в секцию buildModules в файле nuxt.config.js:
{
buildModules: [
'@nuxtjs/color-mode'
]
}
Отлично! Теперь, если мы запустим наше приложение и откроем вкладку Elements в консоли разработчика, то увидим, что к тегу html добавился класс, который соответствует теме операционный системы, например, в нашем случае class="light-mode".
Переключатель темы
На следующем этапе давайте реализуем переключатель, который будет менять темную тему на светлую и наоборот.
Если посмотреть на дизайн нашего приложения в Figma, то мы увидим, что рядом с переключателем темы также находится переключатель языка, который мы реализуем в одной из следующих статей этого цикла.
Сразу напишем компонент-обертку, который будет инкапсулировать эти переключатели и отвечать за внешние отступы до других компонентов.
Для этого создадим компонент AppOptions со следующим содержимым:
<template lang="pug">
section.section
.content
.app-options
switcher-color-mode
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'AppOptions',
})
</script>
<style lang="scss" scoped>
.app-options {
display: flex;
margin-top: 24px;
}
</style>
Компонент на Github.
Как мы видим, в этом компоненте нет никакой логики, он просто устанавливает внешние отступы для вложенных компонентов. Сейчас у нас только один вложенный компонент switcher-color-mode, реализуем его.
Взглянем на секцию script этого компонента:
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'SwitcherColorMode',
computed: {
icon() {
return (this as any).$colorMode.value === 'light'
? 'assets/icons/sun.svg'
: 'assets/icons/moon.svg'
},
},
methods: {
changeColorMode() {
;(this as any).$colorMode.preference =
(this as any).$colorMode.value === 'light' ? 'dark' : 'light'
},
},
})
</script>
Здесь мы реализуем метод changeColorMode, который меняет тему в объекте, предоставляемом модулем @nuxtjs/color-mode.
При изменении значения $colorMode.preference также будет установлен соответствующий класс у тега html: class="light-mode" или class="dark-mode".
Кроме того, здесь есть вычисляемое свойство icon, которое возвращает нужную нам иконку в зависимости от выбранной темы. Обратите внимание, что для корректной работы нужно добавить иконки sun.svg и moon.svg в директорию assets/icons.
Шаблон компонента будет выглядеть следующим образом:
<template lang="pug">
button(@click="changeColorMode")
img(
alt="theme-icon"
:src="getDynamicFile(icon)"
)
</template>
Здесь всё совсем просто! У нас есть кнопка, при клике на которую мы вызываем метод changeColorMode и меняем нашу тему. Внутри кнопки мы показываем изображение выбранной темы.
Компонент на Github.
Остается только добавить этот компонент на главную страницу нашего приложения. После этого шаблон страницы должен выглядеть так:
<template lang="pug">
.page
section-header(
title="Nuxt blog"
subtitle="The best blog you can find on the global internet"
)
app-options
post-list
</template>
Управление переменными
Как вы, возможно, помните из первой части, для определения всех цветов в приложении мы использовали scss переменные, и теперь всё, что нам остаётся сделать, это изменять значения этих переменных в зависимости от выбранной темы.
Но проблема в том, что scss переменные задаются один раз при сборке приложения и в дальнейшем мы не можем переопределять их при изменении темы.
Это ограничение можно обойти с помощью js, но есть решение намного проще: мы можем использовать нативные css переменные.
Сейчас в нашем файле с переменными assets/styles/variables.scss секция с цветами выглядит следующим образом:
// colors
$text-primary: rgb(22, 22, 23);
$text-secondary: rgb(110, 109, 122);
$line-color: rgb(231, 231, 233);
$background-color: rgb(243, 243, 244);
$html-background-color: rgb(255, 255, 255);
Давайте для начала в этом же файле определим две цветовые схемы — светлую и темную — с помощью css переменных:
:root {
// light theme
--text-primary: rgb(22, 22, 23);
--text-secondary: rgb(110, 109, 122);
--line-color: rgb(231, 231, 233);
--background-color: rgb(243, 243, 244);
--html-background-color: rgb(255, 255, 255);
// dark theme
&.dark-mode {
--text-primary: rgb(250, 250, 250);
--text-secondary: rgb(188, 187, 201);
--line-color: rgb(45, 55, 72);
--background-color: rgb(45, 55, 72);
--html-background-color: rgb(26, 32, 44);
}
}
Мы определили css переменные в селекторе :root. По стандарту css переменная задается и используется с помощью префикса --.
О css псевдоклассе :root можно прочесть на MDN и W3Schools. Цитата с MDN:
css псевдокласс :root находит корневой элемент дерева документа. Применимо к HTML, :root находит тег html и идентичен селектору по тегу html, но его специфичность выше.
Как мы видим, те цвета, которые раньше были прописаны напрямую в scss переменные, сейчас указаны в css переменных как значения по умолчанию, а при наличии класса .dark-mode эти значения переопределяются.
Теперь наши scss переменные с цветами будут выглядеть следующим образом:
$text-primary: var(--text-primary);
$text-secondary: var(--text-secondary);
$line-color: var(--line-color);
$background-color: var(--background-color);
$html-background-color: var(--html-background-color);
При переключении темы цветовая схема будет меняться в соответствии с заданными значениями и нам не нужно ничего менять в уже реализованных компонентах.
Заключение
Благодаря этой статье мы научились реализовывать темную тему для приложения на Nuxt.js.
Удалось выполнить все шаги? Как вы думаете, темная тема — это просто хайп или все-таки необходимость? Делитесь мыслями в комментариях.
Ссылки на необходимые материалы:
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 6 (перевод)
- [JavaScript, Программирование, Совершенный код, ReactJS, TypeScript] HowToCode — Адаптация системного подхода к разработке для React и TypeScript
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 5 (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование, ReactJS] 20 основных частей любого крупномасштабного React-приложения (перевод)
- [Научно-популярное, Игры и игровые приставки] Sony позволит владельцам PlayStation использовать бананы вместо джойстиков
- [JavaScript, Монетизация мобильных приложений, Natural Language Processing, Голосовые интерфейсы] Аккредитация разработчиков навыков для ассистентов Салют и первый аккредитованный партнёр
- [Обработка изображений, Дизайн, Финансы в IT, Криптовалюты] Ответы на часто задаваемые вопросы о NFT (перевод)
- [Научно-популярное, Физика] Что скрывают протоны? (перевод)
- [Программирование, ReactJS] Изучение методов кэширования в React (перевод)
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 4 (перевод)
Теги для поиска: #_javascript, #_vuejs, #_nuxt.js, #_dark_mode, #_timeweb, #_blog_kompanii_timeweb (
Блог компании Timeweb
), #_javascript, #_vuejs
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:32
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Привет, Хабр! Публикуем вторую часть серии статей о создании современного блога на Nuxt.js. Сегодня реализуем темную тему в приложении, которое мы написали вместе с вами в первой части. Обратите внимание, что код каждой части можно найти в собственной ветке на Github, а в master доступна версия приложения из последней опубликованной статьи. Что такое темная тема? Темная тема — это цветовая схема любого интерфейса, которая отображает светлый текст и элементы интерфейса на темном фоне, что упрощает просмотр экрана на мобильных телефонах, планшетах и компьютерах при плохой освещенности. Темная тема уменьшает свет, излучаемый экраном, при сохранении минимального соотношения цветового контраста, необходимого для удобочитаемости. Темная тема улучшает визуальную эргономику, снижая нагрузку на глаза, настраивая экран в соответствии с текущими условиями освещения и обеспечивая простоту использования в ночное время или в темноте. Также нельзя забывать о том, что использование темной темы в веб- и мобильных приложениях может продлить срок службы батареи устройства. Компания Google подтвердила, что темная тема на OLED экранах очень помогает продлить срок службы батареи. @nuxtjs/color-mode Для реализации темной темы мы будем использовать модуль @nuxtjs/color-mode, который предоставляет следующие возможности:
Для начала установим модуль: npm i --save-dev @nuxtjs/color-mode
А затем добавим добавим информацию об этом модуле в секцию buildModules в файле nuxt.config.js: {
buildModules: [ '@nuxtjs/color-mode' ] } Отлично! Теперь, если мы запустим наше приложение и откроем вкладку Elements в консоли разработчика, то увидим, что к тегу html добавился класс, который соответствует теме операционный системы, например, в нашем случае class="light-mode". Переключатель темы На следующем этапе давайте реализуем переключатель, который будет менять темную тему на светлую и наоборот. Если посмотреть на дизайн нашего приложения в Figma, то мы увидим, что рядом с переключателем темы также находится переключатель языка, который мы реализуем в одной из следующих статей этого цикла. Сразу напишем компонент-обертку, который будет инкапсулировать эти переключатели и отвечать за внешние отступы до других компонентов. Для этого создадим компонент AppOptions со следующим содержимым: <template lang="pug">
section.section .content .app-options switcher-color-mode </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ name: 'AppOptions', }) </script> <style lang="scss" scoped> .app-options { display: flex; margin-top: 24px; } </style> Компонент на Github. Как мы видим, в этом компоненте нет никакой логики, он просто устанавливает внешние отступы для вложенных компонентов. Сейчас у нас только один вложенный компонент switcher-color-mode, реализуем его. Взглянем на секцию script этого компонента: <script lang="ts">
import Vue from 'vue' export default Vue.extend({ name: 'SwitcherColorMode', computed: { icon() { return (this as any).$colorMode.value === 'light' ? 'assets/icons/sun.svg' : 'assets/icons/moon.svg' }, }, methods: { changeColorMode() { ;(this as any).$colorMode.preference = (this as any).$colorMode.value === 'light' ? 'dark' : 'light' }, }, }) </script> Здесь мы реализуем метод changeColorMode, который меняет тему в объекте, предоставляемом модулем @nuxtjs/color-mode. При изменении значения $colorMode.preference также будет установлен соответствующий класс у тега html: class="light-mode" или class="dark-mode". Кроме того, здесь есть вычисляемое свойство icon, которое возвращает нужную нам иконку в зависимости от выбранной темы. Обратите внимание, что для корректной работы нужно добавить иконки sun.svg и moon.svg в директорию assets/icons. Шаблон компонента будет выглядеть следующим образом: <template lang="pug">
button(@click="changeColorMode") img( alt="theme-icon" :src="getDynamicFile(icon)" ) </template> Здесь всё совсем просто! У нас есть кнопка, при клике на которую мы вызываем метод changeColorMode и меняем нашу тему. Внутри кнопки мы показываем изображение выбранной темы. Компонент на Github. Остается только добавить этот компонент на главную страницу нашего приложения. После этого шаблон страницы должен выглядеть так: <template lang="pug">
.page section-header( title="Nuxt blog" subtitle="The best blog you can find on the global internet" ) app-options post-list </template> Управление переменными Как вы, возможно, помните из первой части, для определения всех цветов в приложении мы использовали scss переменные, и теперь всё, что нам остаётся сделать, это изменять значения этих переменных в зависимости от выбранной темы. Но проблема в том, что scss переменные задаются один раз при сборке приложения и в дальнейшем мы не можем переопределять их при изменении темы. Это ограничение можно обойти с помощью js, но есть решение намного проще: мы можем использовать нативные css переменные. Сейчас в нашем файле с переменными assets/styles/variables.scss секция с цветами выглядит следующим образом: // colors
$text-primary: rgb(22, 22, 23); $text-secondary: rgb(110, 109, 122); $line-color: rgb(231, 231, 233); $background-color: rgb(243, 243, 244); $html-background-color: rgb(255, 255, 255); Давайте для начала в этом же файле определим две цветовые схемы — светлую и темную — с помощью css переменных: :root {
// light theme --text-primary: rgb(22, 22, 23); --text-secondary: rgb(110, 109, 122); --line-color: rgb(231, 231, 233); --background-color: rgb(243, 243, 244); --html-background-color: rgb(255, 255, 255); // dark theme &.dark-mode { --text-primary: rgb(250, 250, 250); --text-secondary: rgb(188, 187, 201); --line-color: rgb(45, 55, 72); --background-color: rgb(45, 55, 72); --html-background-color: rgb(26, 32, 44); } } Мы определили css переменные в селекторе :root. По стандарту css переменная задается и используется с помощью префикса --. О css псевдоклассе :root можно прочесть на MDN и W3Schools. Цитата с MDN: css псевдокласс :root находит корневой элемент дерева документа. Применимо к HTML, :root находит тег html и идентичен селектору по тегу html, но его специфичность выше. Как мы видим, те цвета, которые раньше были прописаны напрямую в scss переменные, сейчас указаны в css переменных как значения по умолчанию, а при наличии класса .dark-mode эти значения переопределяются. Теперь наши scss переменные с цветами будут выглядеть следующим образом: $text-primary: var(--text-primary);
$text-secondary: var(--text-secondary); $line-color: var(--line-color); $background-color: var(--background-color); $html-background-color: var(--html-background-color); При переключении темы цветовая схема будет меняться в соответствии с заданными значениями и нам не нужно ничего менять в уже реализованных компонентах. Заключение Благодаря этой статье мы научились реализовывать темную тему для приложения на Nuxt.js. Удалось выполнить все шаги? Как вы думаете, темная тема — это просто хайп или все-таки необходимость? Делитесь мыслями в комментариях. Ссылки на необходимые материалы: =========== Источник: habr.com =========== Похожие новости:
Блог компании Timeweb ), #_javascript, #_vuejs |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:32
Часовой пояс: UTC + 5