Новые уроки и полировка кода
This commit is contained in:
parent
644a854843
commit
64d0c9568b
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
Copyright (c) 2019 Alexander I. Chebykin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
17
README.md
17
README.md
@ -1,3 +1,18 @@
|
||||
# VueJS
|
||||
|
||||
Самоучитель по VueJS
|
||||
Самоучитель по VueJS
|
||||
|
||||
## Установка
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Компиляция и запуск для разработки
|
||||
```
|
||||
yarn run serve
|
||||
```
|
||||
|
||||
### Сборка финальной версии
|
||||
```
|
||||
yarn run build
|
||||
```
|
||||
@ -8,6 +8,7 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/font": "^3.6.95",
|
||||
"axios": "^0.19.0",
|
||||
"core-js": "^2.6.5",
|
||||
"vue": "^2.6.10",
|
||||
@ -15,6 +16,7 @@
|
||||
"vuetify": "^1.5.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.9.0",
|
||||
"@vue/cli-plugin-babel": "^3.8.0",
|
||||
"@vue/cli-plugin-eslint": "^3.8.0",
|
||||
"@vue/cli-service": "^3.8.0",
|
||||
|
||||
@ -2,25 +2,25 @@
|
||||
<p>
|
||||
Создать проект можно двумя способами: из терминала или при помощи веб-интерфейса. Рассмотрим оба способа.
|
||||
<ol>
|
||||
<li>Из терминала, для этого следует выполнить команду <code>vue create _название_проекта_</code></li>
|
||||
<li>В веб-интерфейсе, запустив его командой <code>vue ui</code></li>
|
||||
<li>Из терминала, для этого следует выполнить команду <kbd>vue create _название_проекта_</kbd></li>
|
||||
<li>В веб-интерфейсе, запустив его командой <kbd>vue ui</kbd></li>
|
||||
</ol>
|
||||
</p>
|
||||
<p>
|
||||
При создании проекта выберите параметры по умолчанию с установкой babel и eslint.
|
||||
</p>
|
||||
<p>
|
||||
Каркас приложения мы создали, можно посмотреть что получилось выполнив команду <code>yarn serve</code> или
|
||||
<code>npm run serve</code>. Вдоволь налюбовавшись результатом, добавим к проекту библиотеку интерфейса
|
||||
Vuetify, выполнив команду <code>vue add vuetify</code>. Установщик задаст вам единственный вопрос - какие
|
||||
Каркас приложения мы создали, можно посмотреть что получилось выполнив команду <kbd>yarn serve</kbd> или
|
||||
<kbd>npm run serve</kbd>. Вдоволь налюбовавшись результатом, добавим к проекту библиотеку интерфейса
|
||||
Vuetify, выполнив команду <kbd>vue add vuetify</kbd>. Установщик задаст вам единственный вопрос - какие
|
||||
предустановки вы хотите выбрать (Choose a preset), нас устроит набо по умолчанию (default).
|
||||
</p>
|
||||
<p>
|
||||
запустив <code>yarn serve</code> сейчас, вы увидите, что внешний вид нашего приложения несколько изменился,
|
||||
запустив <kbd>yarn serve</kbd> сейчас, вы увидите, что внешний вид нашего приложения несколько изменился,
|
||||
в нём появились компоненты библиотеки Vuetify. Этот вариант мы и возьмём за основу нашего приложения.
|
||||
</p>
|
||||
<h2>Клонирование проекта</h2>
|
||||
<p>
|
||||
Текущую версию проекта можно также получить с Git, для этого создайте каталог проекта, перейдите в него
|
||||
и клонируйте командой <code>git clone https://home.cainet.info:3000/cai/VueJS.git</code>.
|
||||
и клонируйте командой <kbd>git clone https://home.cainet.info:3000/cai/VueJS.git</kbd>.
|
||||
</p>
|
||||
@ -6,7 +6,7 @@
|
||||
<p>
|
||||
А ненужное - это компонент HelloWorld и все ссылки на него. Смело удаляйте файл HelloWorld.vue из каталога
|
||||
<code>src/components/</code>, а файл App.vue приведите к следующему виду:
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<template>
|
||||
<v-app>
|
||||
@ -44,13 +44,18 @@
|
||||
</pre>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
Наш компонент будет использовать Material Design Icons, потому начнём с того, что подключим их. Для это выполните команду <kbd>yarn add @mdi/font</kbd>,
|
||||
а после того как пакет установится, добавьте в самое начало файла main.js строку <code>import '@mdi/font/css/materialdesignicons.css'</code>. Всё, теперь
|
||||
можно переходить к написанию самого компонента.
|
||||
</p>
|
||||
<p>
|
||||
Vuetify неплохо документирован и имеет множество примеров, одним из них мы и воспользуемся при создании компонента
|
||||
оглавления. За основу возьмём один из примеров со страницы
|
||||
<a href="https://next.vuetifyjs.com/ru/components/treeview" target="blank">https://next.vuetifyjs.com/ru/components/treeview</a> и
|
||||
приведём его к следующему виду:
|
||||
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<template>
|
||||
<v-card class="mx-auto">
|
||||
@ -88,7 +93,7 @@
|
||||
<template v-slot:prepend="{ item }">
|
||||
<v-icon
|
||||
v-if="item.children"
|
||||
v-text="`mdi-${item.id === 1 ? 'home-variant' : 'folder-network'}`"
|
||||
v-text="`mdi-${open ? 'book-open-variant' : 'book-variant'}`"
|
||||
>
|
||||
</v-icon>
|
||||
</template>
|
||||
@ -142,7 +147,7 @@
|
||||
недоразумение добавлением в блок <code><script></script></code> строки
|
||||
<code>import TOC from './components/TOC'</code> и чуть ниже в <code>components: {},</code> строку
|
||||
<code>TOC</code>. В итоге App.vue должен выглядеть следующим образом:
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<template>
|
||||
<v-app>
|
||||
@ -193,15 +198,15 @@
|
||||
текста. Про двенадцатиточечную систему сеток Vutify можно прочитать тут:
|
||||
<a href="https://vuetifyjs.com/ru/framework/grid" target="_blank">https://vuetifyjs.com/ru/framework/grid</a>.
|
||||
Приведём блок <v-content></v-content> к следующему виду:
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<v-content>
|
||||
<v-container fluid fill-height grid-list-md>
|
||||
<v-layout row wrap full-height>
|
||||
<v-flex sm4>
|
||||
<v-flex sm5 md4 lg3>
|
||||
<TOC/>
|
||||
</v-flex>
|
||||
<v-flex sm8 v-html="text"></v-flex>
|
||||
<v-flex sm7 md8 lg9 v-html="text"></v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-content>
|
||||
@ -219,7 +224,7 @@
|
||||
вылезут за пределы блока меню... Непорядок! К счастью, исправить сиё недоразумение несложно, просто добавьте в
|
||||
наш компонент (TOC.vue) блок стилей:
|
||||
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<style>
|
||||
.v-treeview-node__content, .v-treeview-node__label {
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
<p>
|
||||
Для начала нам понадобится Axios (<a href="https://yarnpkg.com/ru/package/axios" target="_blank">
|
||||
https://yarnpkg.com/ru/package/axios</a>), именно с его помощью мы будем загружать наши json и html файлы.
|
||||
Установим его командой <code>yarn add axios vue-axios</code>, после чего добавим в main.js строки для его
|
||||
Установим его командой <kbd>yarn add axios vue-axios</kbd>, после чего добавим в main.js строки для его
|
||||
подключения. Выглядеть он у вас должен следующим образом:
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
import Vue from 'vue'
|
||||
import Axios from 'axios'
|
||||
@ -32,7 +32,7 @@ new Vue({
|
||||
о разделах, для этого строку items в блоке data приведём к виду <code>items: []</code>, после чего перейдём к
|
||||
App.vue и в секцию export добавим <code>mounted () {}</code>. Здесь мы в дальнейшем добавим код, исполняемый при
|
||||
запуске нашего приложения. Блок <code><script></script></code> должен выглядеть следующим образом:
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<script>
|
||||
import TOC from './components/TOC'
|
||||
@ -63,7 +63,7 @@ new Vue({
|
||||
</p>
|
||||
<p>
|
||||
Итак, добавим в секцию <code>mounted</code> код загрузки оглавления:
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
mounted () {
|
||||
this.axios.get("data/toc.json")
|
||||
@ -88,7 +88,7 @@ mounted () {
|
||||
принципы работы нашего компонента. Каждый раз при выборе элемента, у компонента изменяется свойство active и
|
||||
нам надо отслеживать его изменение в App.vue. Для этого добавим в mounted файла App.vue следующий код:
|
||||
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
this.$watch(
|
||||
"$refs.TOC.active",
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<a href="https://vuetifyjs.com/ru/components/dialogs" target="_blank">https://vuetifyjs.com/ru/components/dialogs</a>,
|
||||
немного его модифицировав:
|
||||
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<template>
|
||||
<v-layout row justify-center>
|
||||
@ -21,7 +21,7 @@
|
||||
<v-card-text>{{ text }}</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="green darken-1" flat @click="dialog = false">Ok</v-btn>
|
||||
<v-btn color="primary" flat @click="dialog = false">Ok</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
@ -48,7 +48,7 @@
|
||||
строку <code>MessageDialog</code>. Начало блока <code><sctipt></script></code> должно выглядеть следующим
|
||||
образом:
|
||||
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<script>
|
||||
import MessageDialog from './components/MessageDialog'
|
||||
@ -68,7 +68,7 @@
|
||||
<code><MessageDialog ref="MessageDialog" /></code>, после чего останется только в коде скрипта добавить
|
||||
в секции .catch каждого обращения к Axios строки вызова нашего диалога с сообщением об ошибке:
|
||||
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
@ -87,7 +87,7 @@
|
||||
том, что оно работает, это нехорошо, давайте выводить при загрузке индикатор. Создадим компонент LoadingDialog.vue
|
||||
как всегда воспользовавшись шаблоном vuetify:
|
||||
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<template>
|
||||
<div class="text-xs-center">
|
||||
@ -139,7 +139,7 @@
|
||||
</p>
|
||||
<p>
|
||||
Справились? Теперь добавим код для отображения и скрытия диалога при загрузке файла в секцию mounted:
|
||||
<div class="grey lighten-2" style="overflow-x: auto; border-radius: 5px;">
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
mounted () {
|
||||
this.$refs.LoadingDialog.dialog = true;
|
||||
@ -203,5 +203,5 @@ mounted () {
|
||||
P.S. Текст данной части можно взять тут: <a href="../data/id304.html" target="_blank">/data/id304.html</a>
|
||||
</p>
|
||||
<p>
|
||||
P.P.S. Финальную версию можно скомпилировать командой <code>yarn build</code>.
|
||||
P.P.S. Финальную версию можно скомпилировать командой <kbd>yarn build</kbd>.
|
||||
</p>
|
||||
190
public/data/id305.html
Normal file
190
public/data/id305.html
Normal file
@ -0,0 +1,190 @@
|
||||
<h1>Цветовые схемы</h1>
|
||||
<p>
|
||||
Наша программа получилась такая светлая-красивая, но в темноте пользоваться ей неудобно, яркий свет от экрана слишком бьёт по глазам, предлагаю
|
||||
<s>перейти на тёмную сторону</s> сделать тёмный вариант интерфейса.
|
||||
</p>
|
||||
<p>
|
||||
Открывайте основной модуль нашего приложения App.vue. В блоке <code><script></code> найдите секцию <code>data ()</code> и добавьте в неё переменную dark
|
||||
со значением по умолчанию равным false, это будет флаг использования тёмной версии интерфейса. После этого в блоке <code><template></code> измените
|
||||
<code><v-app></code> на <code><v-app :dark="dark"></code>, этим мы свяжем наш флаг использования тёмной версии с назначением соответствующего
|
||||
CSS-класса главному элементу программы.
|
||||
</p>
|
||||
<p>
|
||||
Попробуйте изменить в <code>data ()</code> значение переменной dark на true, ваше приложение станет тёмным. Получилось? Теперь прикрутим меню с пунктом для
|
||||
переключения вариантов интерфейса, для этого в конец блока <code><v-toolbar></code> добавим следующий код:
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<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>
|
||||
</pre>
|
||||
</div>
|
||||
Теперь у нас есть переключатель темы, но при каждой повторной загрузке тема всегда включается светлая, реализуем сохранение значения флага в
|
||||
cookies, для этого в блоке <code><script></code> добавим секцию <code>watch</code> с кодом, отслеживающим изменение флага dark и сохраняющим
|
||||
его значение в localSorage:
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
watch: {
|
||||
dark (val) { localStorage.dark = val; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
Сохранение сделали, сделаем и чтение сохранённой информации, добавив в секцию <code>mounted</code> строку
|
||||
<code>this.dark = localStorage.dark ? JSON.parse(localStorage.dark) : false;</code>. После чего наш App.vue должен выглядеть следующим образом:
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<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>
|
||||
</pre>
|
||||
</div>
|
||||
</p>
|
||||
230
public/data/id306.html
Normal file
230
public/data/id306.html
Normal file
@ -0,0 +1,230 @@
|
||||
<h1>Кнопка возвращения</h1>
|
||||
<p>
|
||||
Всё у нас вроде бы красиво, но вот проматывать каждый раз страницу вверх после прочтения урока неудобно, добавим кнопку возвращения к началу страницы.
|
||||
Для этого нам потребуется в блок <code><v-app></v-app></code> добавить код отображения самой кнопки:
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<v-fab-transition>
|
||||
<v-btn
|
||||
v-show="scrolled"
|
||||
color="blue"
|
||||
@click="scrollToTop"
|
||||
dark
|
||||
fixed
|
||||
bottom
|
||||
right
|
||||
fab
|
||||
>
|
||||
<v-icon>keyboard_arrow_up</v-icon>
|
||||
</v-btn>
|
||||
</v-fab-transition>
|
||||
</pre>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
Как вы уже наверное заметили, кнопка у нас привязана к флагу отображения scrolled, это сделано для того чтобы она отображалась только когда требуется,
|
||||
соответственно вам надо добавить данный флаг в блок data скрипта и назначить ему значение false. Сделали? Теперь добавим отслеживание прокрутки и
|
||||
обработчик нажатия на кнопку - scrollToTop:
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
created () {
|
||||
window.addEventListener('scroll', this.onScroll);
|
||||
},
|
||||
|
||||
destroyed () {
|
||||
window.removeEventListener('scroll', this.onScroll);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onScroll () {
|
||||
this.scrolled = window.scrollY > 0;
|
||||
},
|
||||
|
||||
scrollToTop () {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
App.vue должен выглядеть следующим образом:
|
||||
<div class="grey darken-3 white--text" style="overflow-x: auto; border-radius: 5px;">
|
||||
<pre>
|
||||
<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>
|
||||
<v-fab-transition>
|
||||
<v-btn
|
||||
v-show="scrolled"
|
||||
color="blue"
|
||||
@click="scrollToTop"
|
||||
dark
|
||||
fixed
|
||||
bottom
|
||||
right
|
||||
fab
|
||||
>
|
||||
<v-icon>keyboard_arrow_up</v-icon>
|
||||
</v-btn>
|
||||
</v-fab-transition>
|
||||
<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,
|
||||
scrolled: false,
|
||||
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; }
|
||||
},
|
||||
|
||||
created () {
|
||||
window.addEventListener('scroll', this.onScroll);
|
||||
},
|
||||
|
||||
destroyed () {
|
||||
window.removeEventListener('scroll', this.onScroll);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onScroll () {
|
||||
this.scrolled = window.scrollY > 0;
|
||||
},
|
||||
|
||||
scrollToTop () {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</div>
|
||||
</p>
|
||||
37
public/data/id9901.html
Normal file
37
public/data/id9901.html
Normal file
@ -0,0 +1,37 @@
|
||||
<h1>Команды npm, yarn, vue-cli</h1>
|
||||
<p>
|
||||
Здесь я опишу некоторые основные команды, которые понадобятся нам во время обучения.
|
||||
|
||||
<table class="v-datatable v-table elevation-1">
|
||||
<tr>
|
||||
<th>Действие</th>
|
||||
<th>npm</th>
|
||||
<th>yarn</th>
|
||||
<th>vue-cli</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Установка vue-cli</td>
|
||||
<td>npm install @vue/cli -g</td>
|
||||
<td>yarn global add @vue/cli</td>
|
||||
<td> - </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Создание проекта</td>
|
||||
<td>npm init (только инициализация проекта)</td>
|
||||
<td>yarn init (только инициализация проекта)</td>
|
||||
<td>vue create _название_проекта_ или при помощи WebUI: vue ui</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Запуск dev-сервера</td>
|
||||
<td>npm run serve</td>
|
||||
<td>yarn serve</td>
|
||||
<td> - </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Компиляция финальной версии</td>
|
||||
<td>npm build</td>
|
||||
<td>yarn build</td>
|
||||
<td> - </td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
@ -36,6 +36,14 @@
|
||||
{
|
||||
"id": 304,
|
||||
"name": "Шаг 4. Добавление диалогов"
|
||||
},
|
||||
{
|
||||
"id": 305,
|
||||
"name": "Шаг 5. Цветовые схемы"
|
||||
},
|
||||
{
|
||||
"id": 306,
|
||||
"name": "Шаг 6. Кнопка возвращения"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 120 KiB |
69
src/App.vue
69
src/App.vue
@ -13,18 +13,52 @@
|
||||
>
|
||||
<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>
|
||||
<v-flex sm5 md4 lg3>
|
||||
<TOC ref="TOC" />
|
||||
</v-flex>
|
||||
<v-flex sm8 v-html="text"></v-flex>
|
||||
<v-flex sm7 md8 lg9 v-html="text"></v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-content>
|
||||
<v-fab-transition>
|
||||
<v-btn
|
||||
v-show="scrolled"
|
||||
color="blue"
|
||||
@click="scrollToTop"
|
||||
dark
|
||||
fixed
|
||||
bottom
|
||||
right
|
||||
fab
|
||||
>
|
||||
<v-icon>keyboard_arrow_up</v-icon>
|
||||
</v-btn>
|
||||
</v-fab-transition>
|
||||
<LoadingDialog ref="LoadingDialog" />
|
||||
<MessageDialog ref="MessageDialog" />
|
||||
</v-app>
|
||||
@ -48,12 +82,14 @@
|
||||
return {
|
||||
dark: false,
|
||||
docId: 0,
|
||||
scrolled: false,
|
||||
text: ""
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$refs.LoadingDialog.dialog = true;
|
||||
this.dark = localStorage.dark ? JSON.parse(localStorage.dark) : false;
|
||||
|
||||
this.axios.get("data/start.html")
|
||||
.then(response => {
|
||||
@ -103,9 +139,32 @@
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
watch: {
|
||||
dark (val) { localStorage.dark = val; }
|
||||
},
|
||||
|
||||
created () {
|
||||
window.addEventListener('scroll', this.onScroll);
|
||||
},
|
||||
|
||||
destroyed () {
|
||||
window.removeEventListener('scroll', this.onScroll);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onScroll () {
|
||||
this.scrolled = window.scrollY > 0;
|
||||
},
|
||||
|
||||
scrollToTop () {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<v-card-text>{{ text }}</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="green darken-1" flat @click="dialog = false">Ok</v-btn>
|
||||
<v-btn color="primary" flat @click="dialog = false">Ok</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
@ -31,10 +31,10 @@
|
||||
active-class="primary--text"
|
||||
open-on-click
|
||||
>
|
||||
<template v-slot:prepend="{ item }">
|
||||
<template v-slot:prepend="{ item, open }">
|
||||
<v-icon
|
||||
v-if="item.children"
|
||||
v-text="`mdi-${item.id === 1 ? 'home-variant' : 'folder-network'}`"
|
||||
v-text="`mdi-${open ? 'book-open-variant' : 'book-variant'}`"
|
||||
>
|
||||
</v-icon>
|
||||
</template>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import '@mdi/font/css/materialdesignicons.css'
|
||||
import Vue from 'vue'
|
||||
import Axios from 'axios'
|
||||
import VueAxios from 'vue-axios'
|
||||
|
||||
10
yarn.lock
10
yarn.lock
@ -667,6 +667,11 @@
|
||||
lodash "^4.17.11"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@fortawesome/fontawesome-free@^5.9.0":
|
||||
version "5.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.9.0.tgz#1aa5c59efb1b8c6eb6277d1e3e8c8f31998b8c8e"
|
||||
integrity sha512-g795BBEzM/Hq2SYNPm/NQTIp3IWd4eXSH0ds87Na2jnrAUFX3wkyZAI4Gwj9DOaWMuz2/01i8oWI7P7T/XLkhg==
|
||||
|
||||
"@hapi/address@2.x.x":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.0.0.tgz#9f05469c88cb2fd3dcd624776b54ee95c312126a"
|
||||
@ -702,6 +707,11 @@
|
||||
cssnano-preset-default "^4.0.0"
|
||||
postcss "^7.0.0"
|
||||
|
||||
"@mdi/font@^3.6.95":
|
||||
version "3.6.95"
|
||||
resolved "https://registry.yarnpkg.com/@mdi/font/-/font-3.6.95.tgz#0bbde766ca2d94cfa0e469f25523b23d3112bdd3"
|
||||
integrity sha512-wUbkF/RRCIh51TPzAL9qUeRSUFla9I3x1nGq62HkfWzIebRHbDY5HPaYCQuZO7398dWaLHTu4BwnBA58YbhfEA==
|
||||
|
||||
"@mrmlnc/readdir-enhanced@^2.2.1":
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user