Цветовые схемы

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

Открывайте основной модуль нашего приложения App.vue. В блоке <script> найдите секцию data () и добавьте в неё переменную dark со значением по умолчанию равным false, это будет флаг использования тёмной версии интерфейса. После этого в блоке <template> измените <v-app> на <v-app :dark="dark">, этим мы свяжем наш флаг использования тёмной версии с назначением соответствующего CSS-класса главному элементу программы.

Попробуйте изменить в data () значение переменной dark на true, ваше приложение станет тёмным. Получилось? Теперь прикрутим меню с пунктом для переключения вариантов интерфейса, для этого в конец блока <v-toolbar> добавим следующий код:

<v-menu bottom left>
    <template v-slot:activator="{ on }">
        <v-btn
            flat
            icon
            v-on="on"
        >
            <v-icon>more_vert</v-icon>
        </v-btn>
    </template>

    <v-list>
        <v-list-tile>
            <v-list-tile-action>
                <v-switch v-model="dark" color="blue"></v-switch>
            </v-list-tile-action>
            <v-list-tile-title>Тёмная схема</v-list-tile-title>
        </v-list-tile>
    </v-list>
</v-menu>
        
Теперь у нас есть переключатель темы, но при каждой повторной загрузке тема всегда включается светлая, реализуем сохранение значения флага в cookies, для этого в блоке <script> добавим секцию watch с кодом, отслеживающим изменение флага dark и сохраняющим его значение в localSorage:
watch: {
    dark (val) { localStorage.dark = val; }
}
        

Сохранение сделали, сделаем и чтение сохранённой информации, добавив в секцию mounted строку this.dark = localStorage.dark ? JSON.parse(localStorage.dark) : false;. После чего наш App.vue должен выглядеть следующим образом:

<template>
    <v-app :dark="dark">
        <v-toolbar app>
            <v-toolbar-title class="headline text-uppercase">
                <span>Vue.js:</span>
                <span class="font-weight-light">Самоучитель</span>
            </v-toolbar-title>
            <v-spacer></v-spacer>
            <v-btn
                flat
                href="https://home.cainet.info:3000/cai/VueJS/"
                target="_blank"
            >
                <span class="mr-2">Актуальная версия</span>
            </v-btn>
            <v-menu bottom left>
                <template v-slot:activator="{ on }">
                    <v-btn
                        flat
                        icon
                        v-on="on"
                    >
                        <v-icon>more_vert</v-icon>
                    </v-btn>
                </template>

                <v-list>
                    <v-list-tile>
                        <v-list-tile-action>
                            <v-switch v-model="dark" color="blue"></v-switch>
                        </v-list-tile-action>
                        <v-list-tile-title>Тёмная схема</v-list-tile-title>
                    </v-list-tile>
                </v-list>
            </v-menu>
        </v-toolbar>

        <v-content>
            <v-container fluid fill-height grid-list-md>
                <v-layout row wrap full-height>
                    <v-flex sm4>
                        <TOC ref="TOC" />
                    </v-flex>
                    <v-flex sm8 v-html="text"></v-flex>
                </v-layout>
            </v-container>
        </v-content>
        <LoadingDialog ref="LoadingDialog" />
        <MessageDialog ref="MessageDialog" />
    </v-app>
</template>

<script>
    import LoadingDialog from './components/LoadingDialog'
    import MessageDialog from './components/MessageDialog'
    import TOC from './components/TOC'

    export default {
        name: 'App',

        components: {
            LoadingDialog,
            MessageDialog,
            TOC
        },

        data () {
            return {
                dark: false,
                docId: 0,
                text: ""
            }
        },

        mounted () {
            this.$refs.LoadingDialog.dialog = true;
            this.dark = localStorage.dark ? JSON.parse(localStorage.dark) : false;

            this.axios.get("data/start.html")
                .then(response => {
                    this.text = response.data;
                    this.$refs.LoadingDialog.dialog = false;
                })
                .catch(error => {
                    this.$refs.LoadingDialog.dialog = false;
                    console.log(error);
                    this.$refs.MessageDialog.title = "Ошибка";
                    this.$refs.MessageDialog.text = error;
                    this.$refs.MessageDialog.dialog = true;
                });

            this.$refs.LoadingDialog.dialog = true;

            this.axios.get("data/toc.json")
                .then(response => {
                    this.$refs.TOC.items = response.data;
                    this.$refs.LoadingDialog.dialog = false;
                })
                .catch(error => {
                    this.$refs.LoadingDialog.dialog = false;
                    console.log(error);
                    this.$refs.MessageDialog.title = "Ошибка";
                    this.$refs.MessageDialog.text = error;
                    this.$refs.MessageDialog.dialog = true;
                });

            this.$watch(
                "$refs.TOC.active",
                (newVal, oldVal) => {
                    if (newVal.length) {
                    this.$refs.LoadingDialog.dialog = true;
                    this.axios.get("data/id" + newVal + ".html")
                        .then(response => {
                            this.text = response.data;
                            this.$refs.LoadingDialog.dialog = false;
                        })
                        .catch(error => {
                            this.$refs.LoadingDialog.dialog = false;
                            console.log(error);
                            this.$refs.MessageDialog.title = "Ошибка";
                            this.$refs.MessageDialog.text = error;
                            this.$refs.MessageDialog.dialog = true;
                        });
                    }
                }
            );
        },

        watch: {
            dark (val) { localStorage.dark = val; }
        }
    }
</script>