Как опубликовать приложение Vuetify с помощью Nginx в Ubuntu 20.04
Автор выбрал программу Write for DOnations.
Введение
Компоненты являются ключевой особенностью современной фронтенд-разработки. Компонент – это фрагмент кода, который обычно состоит из двух частей:
- Логика компонента: что может делать компонент.
- Шаблон: как пользователь будет взаимодействовать с веб-приложением.
Организация вашего приложения в виде компонентов помогает вам писать современные и надежные веб-приложения. Vue.js может помочь вам в разработке многих видов компонентов и широко используется разработчиками.
Однако одной из проблем этих фреймворков является то, что вам нужно создавать множество компонентов, даже для таких простых вещей, как текстовое поле ввода. По этой причине более рациональным подходом является использование библиотеки компонентов, в которой есть готовые компоненты, которые вы можете выбирать и использовать по мере необходимости. С библиотекой компонентов вам не нужно беспокоиться о дизайне CSS, цветах, размерах и шрифтах — вы можете сосредоточиться на функциональности.
Для Vue.js существуют принципы Material Design. Vuetify легко настраивается и настраивается. Вы можете изменить компоненты в соответствии со своими потребностями, а также настроить собственную тему, чтобы иметь согласованную библиотеку компонентов в соответствии со стилем вашего бренда.
В этом учебном пособии вы создадите приложение to-do на основе Vuetify
и опубликуете его с помощью Nginx
в качестве обратного прокси-сервера, необходимого для развертывания приложения Vue.
Примечание. Поскольку Vue — это интерфейсная платформа, приложение, которое вы создадите для этого руководства, будет работать в браузере. Однако для дополнительных функций, таких как аутентификация или сохранение данных, вам потребуется серверная часть. Определение или разработка этой внутренней функциональности выходит за рамки этой статьи.
Предпосылки
Чтобы следовать этому руководству, вам понадобится следующее:
- Один сервер Ubuntu 20.04 с пользователем без полномочий root. Чтобы начать работу, следуйте нашему Руководству по начальной настройке сервера для Ubuntu 20.04. В этом руководстве пользователем без полномочий root является
sammy
. - Установлен Nginx, что можно сделать, выполнив шаги 1–3 руководства Как установить Nginx в Ubuntu 20.04.
- Полностью зарегистрированное доменное имя. В этом руководстве будет использоваться
ваш_домен
. Вы можете приобрести доменное имя на Namecheap, получить его бесплатно на Freenom или воспользоваться услугами регистратора домена по вашему выбору. - Установлен Node.js (не ниже версии 14.0.0), что можно сделать, следуя руководству по установке Node.js и созданию локальной среды разработки для вашей операционной системы.
- Знакомство с Vue.js, которое вы можете найти в Vue How To Develop Websites with Vue.js.
Шаг 1 — Настройка вашего приложения Vue
На этом этапе вы настроите свое приложение Vue.js. У Vue.js есть клиент, который вы можете использовать для создания шаблона проекта, что является хорошим способом начать с нуля.
Вы начнете с глобальной установки клиента Vue.js с помощью этой команды:
- sudo npm install -g @vue/cli
Далее подтвердите версию:
- vue --version
Последней версией, на момент написания этого руководства, была 5.0.8
:
Output@vue/cli 5.0.8
Теперь, когда вы установили @vue/cli
, вы можете использовать его для создания приложения vuejs
. В этом руководстве приложение будет называться vuetify-meets-nginx-app
, но вы можете изменить имя на любое другое.
Чтобы создать приложение, выполните эту команду:
- vue create vuetify-meets-nginx-app
Эта команда является интерактивной и имеет несколько параметров. Для этого руководства выберите параметр Default
для Vue 2
:
OutputVue CLI v5.0.8
? Please pick a preset: (Use arrow keys)
Default ([Vue 3] babel, eslint)
❯ Default ([Vue 2] babel, eslint)
Manually select features
Предупреждение. На момент написания этой статьи Vuetify
не поддерживал Vue.js v3
. Если вы попытаетесь добавить Vuetify в Vue.js v3
, вы увидите эту ошибку:
OutputError: you cannot call "get" on a collection with no paths. Instead, check the "length" property first to verify at least 1 path exists.**
Для получения дополнительной информации см. дорожную карту Vuetify.
Как только приложение будет создано, вы заметите, что файлы и каталоги, сгенерированные Vue:
├── README.md
├── babel.config.js
├── jsconfig.json
├── node_modules
├── package-lock.json
├── package.json
├── public/
├── favicon.ico
└── index.html
├── src
...
└── vue.config.js
Вот краткий обзор:
babel.config.js
: Babel — это компилятор Javascript, и этот файл определяет его поведение. Это необходимо для запуска, сборки и создания конечного приложения.jsconfig.json
: этот файл также необходим для компиляции приложения. Например, этот файл задает для версии кода JavascriptECMAScript 2009 (ES5)
версию по умолчанию. Для получения дополнительной информации ознакомьтесь с этой документацией.node_modules
: каталог, содержащий все установленные и настроенные библиотеки.package.json
: основной файл конфигурации вашего приложения. Здесь вы увидите информацию о зависимостях и командах, доступных для запуска или сборки вашего приложения.package-lock.json
: это файл дампа всех зависимостей, используемых вашим приложением. Этот файл особенно полезен, если вы хотите установить приложение на другой ноутбук или сервер с помощьюnpm
.public
: здесь у вас есть базовый код, который нужен командеnpm run serve
для публикации вашего приложения. Он создается командой@vue/cli
.vue.config.js
: файл конфигурацииVue
.
В папке src
вы увидите следующие файлы и каталоги:
src
├── App.vue
├── assets
│ ├── logo.png
│ └── logo.svg
├── components
│ └── HelloWorld.vue
├── main.js
Вот краткий обзор:
App.vue
: компонент верхнего уровня приложения Vue.js. Все остальные компоненты будут внутри компонента, определенного здесь.ресурсы
: сюда должны быть помещены все ресурсы, такие как изображения, файлы CSS и шрифты.components
: содержит все компоненты, которые вы создаете. Команда@vue/cli
сгенерировала файл с именемHelloWorld.vue
.main.js
: основной файл приложения. Если вам нужно настроить библиотеку или плагин, это файл. Он также создал приложение Vue.
Теперь вы можете перейти в каталог vuetify-meets-nginx-app
:
- cd vuetify-meets-nginx-app
Чтобы запустить приложение в режиме разработки, выполните следующую команду:
- npm run serve
Ваш вывод будет выглядеть так:
OutputINFO Starting development server...
DONE Compiled successfully in 27235ms
App running at:
- Local: http://localhost:8080/
- Network: unavailable
Note that the development build is not optimized.
To create a production build, run npm run build.
После запуска сервера разработки перейдите на localhost:8080
, чтобы увидеть приложение:
Примечание. Если вы следуете руководству на удаленном сервере, вы можете использовать переадресацию портов, чтобы увидеть приложение в браузере. Убедитесь, что на вашем сервере открыт порт 8080
. Пока сервер разработки все еще работает, откройте другой терминал на локальном компьютере и введите следующую команду, чтобы инициировать переадресацию портов:
- ssh -L 8080:localhost:8080 your_non_root_user@your_server_ip
После подключения к серверу перейдите по адресу http://localhost:8080
в веб-браузере вашего локального компьютера. Держите второй терминал открытым на протяжении оставшейся части этого руководства.
На этом шаге вы создали свое приложение Vue.js. Далее вы добавите Vuetify в проект.
Шаг 2 — Интеграция Vuetify в приложение Vue
На этом этапе вы добавите Vuetify в свое приложение Vue.js.
Без такой библиотеки компонентов, как Vuetify, вам пришлось бы использовать ввод HTML, например div
и button
, разрабатывать CSS для своего веб-приложения и создавать собственные компоненты, если хотите. некоторые повторно используемые блоки. Но с библиотекой Vuetify вам нужно только импортировать нужные компоненты и добавить их в свой шаблон.
Vuetify также имеет широкие возможности настройки. Например, у вас могут быть темы. Одна тема представляет собой библиотеку CSS, которая включает в себя такие вещи, как цветовые палитры, настраиваемые размеры экрана и шрифты. Например, если ваш основной
цвет — синий
, вы можете настроить Vuetify таким образом, и каждый раз, когда вы используете класс CSS primary
, Vuetify будет использовать синий цвет. Дополнительную информацию о темах можно найти в руководствах по функциям Vuetify.
Чтобы начать добавление Vuetify, завершите работу сервера разработки, который вы запустили на предыдущем шаге, введя CTRL+C
в терминале, где работает сервер разработки.
Затем выполните следующую команду в каталоге vuetify-meets-nginx-app
:
- vue add vuetify
Эта команда устанавливает Vuetify с помощью клиента Vue.js.
Выберите конфигурацию по умолчанию
в списке предустановленных параметров:
Output📦 Installing vue-cli-plugin-vuetify...
added 38 packages, and audited 39 packages in 2s
7 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
✔ Successfully installed plugin: vue-cli-plugin-vuetify
? Choose a preset: (Use arrow keys)
Configure (advanced)
❯ Default (recommended)
Vite Preview (Vuetify 3 + Vite)
Prototype (rapid development)
Vuetify 3 Preview (Vuetify 3)
Через несколько минут можно снова запустить сервер разработки:
- npm run serve
Перейдите к localhost:8080
, где вы можете увидеть приложение с новым стилем vuetified:
На данный момент вы создали базовое приложение и добавили Vuetify для стилизации. Далее вы создадите приложение с дополнительными функциями.
Шаг 3 — Создание приложения To-Do Vuetify
На этом шаге вы создадите приложение для работы. Приложение to-do — это список задач, для выполнения которых потребуются некоторые базовые функции:
- Способ добавления новых задач.
- Способ пометить их как выполненные.
- Метод их отображения, позволяющий пользователям видеть, что ожидается.
Чтобы добавить эти функции в свое приложение, вы измените файл App.vue
, который является компонентом верхнего уровня приложения. Все остальные компоненты будут находиться внутри компонента, определенного здесь.
Примечание:
Перейдите к src/App.vue
и откройте его для редактирования с помощью nano
или вашего любимого текстового редактора:
- cd src
- nano App.vue
Вот код по умолчанию:
<template>
<v-app>
<v-app-bar
app
color="primary"
dark
>
<div class="d-flex align-center">
<v-img
alt="Vuetify Logo"
class="shrink mr-2"
contain
src="https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png"
transition="scale-transition"
width="40"
/>
<v-img
alt="Vuetify Name"
class="shrink mt-1 hidden-sm-and-down"
contain
min-width="100"
src="https://cdn.vuetifyjs.com/images/logos/vuetify-name-dark.png"
width="100"
/>
</div>
<v-spacer></v-spacer>
<v-btn
href="https://github.com/vuetifyjs/vuetify/releases/latest"
target="_blank"
text
>
<span class="mr-2">Latest Release</span>
<v-icon>mdi-open-in-new</v-icon>
</v-btn>
</v-app-bar>
<v-main>
<HelloWorld/>
</v-main>
</v-app>
</template>
<script>
import HelloWorld from './components/HelloWorld';
export default {
name: 'App',
components: {
HelloWorld,
},
data: () => ({
//
}),
};
</script>
Каждый компонент состоит из двух частей: шаблона (обычно HTML-кода) и скрипта с функциональностью, написанной на Javascript.
Шаблон — это то, что конечный пользователь увидит в браузере, и он определяет, как пользователи взаимодействуют с вашим приложением. Как правило, вы должны импортировать компоненты, которые будут использоваться в шаблоне, но поскольку вы установили Vuetify
в качестве подключаемого модуля, все компоненты доступны в шаблоне без их явного импорта.
В блоке шаблона много HTML-тегов v-
. Хотя эти теги нестандартны для HTML, они являются компонентами Vuetify и всегда начинаются с v-
.
В шаблоне у вас в настоящее время есть:
v-app
: основной компонент, прикрепленный к телу веб-сайта.v-app-bar
: боковая панель по умолчанию.v-img
: компонент, загружающий изображения.v-icon
: компонент для отображения значков.v-spacer
: компонент, который выравнивает следующий компонент справа.
Что касается блока script
в файле App.vue
, установка Vuetify не добавляет сюда никакого кода, поэтому у вас есть начальный код, сгенерированный Vue. cli
и минимальный код, необходимый для компонента Vue.
Теперь, когда вы просмотрели код по умолчанию в файле App.vue
, вы готовы приступить к созданию своего приложения для работы со списком дел. Первым шагом будет удаление некоторого кода по умолчанию, который вы не будете использовать.
Очистка файла App.vue
Компонент HelloWorld
по умолчанию не понадобится для вашего приложения, поэтому вы удалите его из файла App.vue
.
Чтобы использовать компонент Vue внутри другого компонента или представления, вы должны импортировать компонент в блок сценария файла. В вашем файле App.vue
у вас есть импорт компонента HelloWorld
в первой строке:
...
import HelloWorld from './components/HelloWorld';
...
Поскольку вы не будете использовать этот компонент, удалите строку import
.
Следующим шагом является удаление компонента из списка зависимостей компонентов на странице App.vue
. В блоке сценария
найдите следующие строки:
...
<script>
...
components: {
HelloWorld,
},
...
</script>
Удалите строку HelloWorld
из списка components
.
Последний шаг — удалить его из блока шаблона:
...
<template>
...
<v-main>
<HelloWorld/>
</v-main>
</v-app>
</template>
...
Удалите строку HelloWorld
.
Теперь, когда компонент HelloWorld
по умолчанию удален, вы можете приступить к созданию своего приложения для работы со списком дел.
Добавление полей данных компонента
Чтобы создать приложение для работы со списком дел, вы добавите поля данных для своего приложения. data
компонента — это функция, которая возвращает все модели данных, которые вы сможете использовать в шаблоне. Все эти модели данных являются переменными Javascript внутри объекта и также будут доступны для методов компонента.
Найдите поле data
в блоке script
:
...
<script>
...
data: () => ({
//
}),
};
</script>
Вы измените функцию data
, чтобы сохранить список задач. Добавьте следующие выделенные строки в функцию data
:
...
<script>
...
data: () => ({
tasks: ['task 1', 'task 2', 'task 3'],
newTask: null
}),
};
</script>
В этом обновлении вы добавили две модели данных: переменную newTask
для хранения имени задачи и tasks
для списка задач. Обе модели данных теперь доступны для использования в шаблоне и в методах.
Примечание. Если вы не знакомы с тем, как Vue.js
делает модели данных доступными для шаблона и методов компонентов, ознакомьтесь с основами реактивности Vue.js в официальной документации.
Добавление функциональности в ваше приложение
Далее вы добавите функциональность. В компонентах Vue.js функциональность находится внутри списка функций, называемых methods
. В блоке script
под моделями data
добавьте выделенные строки, чтобы добавить три функции:
...
<script>
export default {
name: 'App',
data: () => ({
tasks: ['task 1', 'task 2', 'task 3'],
newTask: null
}),
methods: {
addNewTask() {
this.tasks.push(this.newTask);
this.clearNewTask();
},
clearNewTask() {
this.newTask = '';
},
removeTask(i) {
this.tasks.splice(i, 1);
}
}
};
Вы добавили три функции:
addNewTask
: чтобы добавить новую задачу внутри модели данныхnewTask
в списокtasks
.clearNewTask
: чтобы очистить модель данных дляnewTask
.removeTask
: чтобы удалить задачу из спискаtasks
на основе индекса массива.
Теперь вы добавили функциональность для своего приложения для работы со списком дел. Далее вы измените шаблон, чтобы использовать методы.
Обновление шаблона
Последняя часть вашего приложения — это шаблон. В этом разделе вы обновите шаблон, чтобы использовать методы и модели данных, которые вы добавили в предыдущих разделах.
Вам нужно будет удалить некоторые компоненты, которые вам не нужны, из v-app-bar
. Удалите блок v-btn
. Тогда ваш код будет выглядеть так:
<template>
<v-app>
<v-app-bar
app
color="primary"
dark
>
<div class="d-flex align-center">
<v-img
alt="Vuetify Logo"
class="shrink mr-2"
contain
src="https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png"
transition="scale-transition"
width="40"
/>
<v-img
alt="Vuetify Name"
class="shrink mt-1 hidden-sm-and-down"
contain
min-width="100"
src="https://cdn.vuetifyjs.com/images/logos/vuetify-name-dark.png"
width="100"
/>
</div>
<v-spacer></v-spacer>
</v-app-bar>
...
</v-app>
</template>
Далее вы собираетесь добавить некоторые компоненты, чтобы определить базовый макет вашего приложения. Во-первых, это v-container
, который представляет собой компонент, обеспечивающий возможность центрировать и горизонтально дополнять содержимое вашего приложения. Дополнительную информацию об этом компоненте и других контейнерах можно найти в документации по грид-системе от Vuetify.
В v-container
вы добавите компонент v-card
, который является еще одним контейнером Vuetify. Это полезно для организации содержимого на экране, например панели или статического изображения. Дополнительные сведения о компоненте v-card
см. в документации Vuetify по картам.
Найдите блок v-main
в текущем шаблоне и добавьте выделенные строки:
...
<v-main>
<v-container>
<v-card elevation="0">
</v-card>
</v-container>
</v-main>
...
Как видно из кода, в компоненте v-card
есть свойство elevation=0
. Высота — это общее свойство внутри компонентов Vuetify, которое регулирует относительное расстояние по оси z между двумя компонентами. В этом случае вам не нужно никакого расстояния, а 0
— это значение для удаления высоты. Тем не менее, вы можете поиграть с ним, чтобы увидеть различия или посмотреть документацию по высоте.
Далее вы будете использовать два функциональных компонента v-card
: v-card-text
, который будет содержать содержимое карточки. Добавьте выделенные строки в компонент v-card
:
...
<v-main>
<v-container>
<v-card elevation="0">
<v-card-title></v-card-title>
<v-card-text></v-card-text>
</v-card>
</v-container>
</v-main>
...
Функциональный компонент — это компонент, который только отображает шаблон. В нем нет никакой логики, и, поскольку это всего лишь шаблон, он отображается быстрее. Чтобы узнать больше о функциональных компонентах или узнать, как создавать свои собственные, ознакомьтесь с руководством Vue.js по функциональным компонентам.
Теперь, когда у вас есть компонент-контейнер, вы должны добавить компонент v-text-field
для обработки имен новых задач. В только что добавленный компонент v-card-title
вставьте выделенные строки:
...
<v-main>
<v-container>
<v-card elevation="0">
<v-card-title>
<v-text-field
v-model="newTask"
label="Task Name"
prepend-icon="mdi-content-save"
clear-icon="mdi-close-circle"
clearable
filled
type="text"
@click:prepend="addNewTask"
@click:clear="clearNewTask"
></v-text-field>
</v-card-title>
...
</v-card>
</v-container>
</v-main>
...
v-text-field
— обязательный компонент для именования новых задач.
Он имеет следующие свойства:
v-model=newTask
прикрепляет модель данных к компоненту. Любой текст, который вы вводите во входные данные, также будет добавлен в модель данных.label=Имя задачи
– это текст в заполнителе типа ввода.prepend-icon=mdi-content-save
отобразит значок Сохранить в левом углу текстового поля.clear-icon=mdi-close-circle
– это значок кнопки Очистить.clearable
показывает значок Очистить.filled
применяет к компоненту альтернативный стиль ввода с заливкой.type=text
задает тип ввода основного поля ввода HTML. Другие варианты включаютадрес электронной почты
илипароль
.@click: prepend=addNewTask
прикрепляет событие нажатия кнопки Сохранить к функцииaddNewTask
.@click: clear=clearNewTask
связывает событие нажатия кнопки Сохранить с функциейclearNewTask
.
Следующий шаг — показать каждую задачу внутри модели списка задач. Для этого вы собираетесь использовать компонент v-timeline
, который является компонентом отображения для отображения информации на основе времени или порядка. Вы собираетесь добавить его в v-card-text
, который является основным компонентом v-card
. Внутри компонента v-card-text
, который вы уже добавили, вставьте выделенные строки:
...
<v-main>
<v-container>
<v-card elevation="0">
<v-card-title>
...
</v-card-title>
<v-card-text>
<v-timeline
v-if="tasks.length > 0"
dense
></v-timeline>
</v-card-text>
...
</v-card>
</v-container>
</v-main>
...
v-timeline
отображает все задачи в списке. v-if
показывает компонент, только если у вас есть хотя бы одна задача в модели данных. dense
предназначен для уплотнения содержимого (по сути, он удаляет некоторые отступы и поля из стиля CSS компонента).
Теперь, чтобы показать название каждой задачи, вам нужно использовать функциональный компонент v-timeline
: v-timeline-item
. Добавьте следующие строки внутрь компонента v-timeline
:
...
<v-main>
<v-container>
<v-card elevation="0">
<v-card-title>
...
</v-card-title>
<v-card-text>
<v-timeline
v-if="tasks.length > 0"
dense
>
<v-timeline-item
v-for="(t, index) in tasks"
:key="index"
>
{{ t }}
</v-timeline-item>
</v-timeline>
</v-card-text>
</v-card>
</v-container>
</v-main>
...
Этот код использует цикл v-for
для отображения компонента v-timeline-item
для каждой задачи в вашей модели списка задач. Поскольку v-timeline-item
является функциональным компонентом v-timeline
, он будет отображаться в стиле хронологического списка.
Вы добавляете индекс в качестве ключа в цикл v-for
, поскольку он является обязательным для директивы Vue v-for
. Чтобы узнать больше об использовании уникальных ключей с v-for
, ознакомьтесь с документацией по продукту Vue.
Строка {{ t }}
показывает название задачи внутри компонента v-timeline-item
.
Следующим шагом будет добавление кнопки для удаления задачи из списка. Но перед этим вам нужно будет добавить некоторые дополнительные компоненты системы сетки, чтобы упорядочить названия задач и кнопки. Добавьте выделенные строки внутрь компонента v-timeline-item
:
...
<v-main>
<v-container>
<v-card elevation="0">
<v-card-title>
...
</v-card-title>
<v-card-text>
<v-timeline
v-if="tasks.length > 0"
dense
>
<v-timeline-item
v-for="(t, index) in tasks"
:key="index"
>
<v-row class="display-1 text-capitalize">
<v-col cols="7">
{{ t }}
</v-col>
<v-col
class="text-right"
cols="5"
>
</v-col>
</v-row>
</v-timeline-item>
</v-timeline>
</v-card-text>
</v-card>
</v-container>
</v-main>
...
С приведенным выше кодом вы добавили:
- Компонент
v-row
с двумя классами для установки размера текста задачи (display-1
, аналогичный H1 в HTML) и со всеми символы заглавными буквами (text-capitalize
). - Компонент
v-col
внутри строки для отображения имени каждой задачи, для которой потребуется 7/12 частей пространства (свойствоcols=7
). - Еще один компонент
v-col
, размещающий кнопку удаления. Ему требуется 5/12 частей пространства (свойствоcols=5
), и все компоненты внутри выровнены по правому краю, что определяется классомtext-right
.
Наконец, пришло время добавить компонент v-icon
.
Добавьте выделенные строки:
...
<v-timeline
v-if="tasks.length > 0"
dense
>
<v-timeline-item
v-for="(t, index) in tasks"
:key="index"
>
<v-row class="display-1 text-capitalize">
<v-col cols="7">
{{ t }}
</v-col>
<v-col
class="text-right"
cols="5"
>
<v-btn
icon
@click="removeTask(index)"
>
<v-icon color="red lighten-1" large>
mdi-sticker-remove
</v-icon>
</v-btn>
</v-col>
</v-row>
...
</v-timeline-item>
</v-timeline>
В только что добавленном коде свойство icon
компонента v-btn
указывает, что текст не требуется. Он изменяет компонент, чтобы стилизовать только компонент v-icon
.
Событие компонента @click
связывает ваш метод removeTask
с событием нажатия кнопки. Таким образом, каждый раз, когда генерируется базовое событие нажатия кнопки, будет вызываться ваш метод.
Вы использовали индекс, предоставленный циклом v-for
, в качестве параметра для метода removeTask
.
Наконец, цвет v-icon
будет red lighten-1
, размер будет large
, и вы использовали mdi- sticker-remove
значок материального дизайна.
Теперь вы обновили шаблон с некоторыми компонентами Vuetify
, настроили их для использования и отображения содержимого ваших моделей данных и разрешили пользователям вашего приложения взаимодействовать с ними, используя методы вашей страницы.
Вот окончательный код файла App.vue
:
<template>
<v-app>
<v-app-bar
app
color="primary"
dark
>
<div class="d-flex align-center">
<v-img
alt="Vuetify Logo"
class="shrink mr-2"
contain
src="https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png"
transition="scale-transition"
width="40"
/>
<v-img
alt="Vuetify Name"
class="shrink mt-1 hidden-sm-and-down"
contain
min-width="100"
src="https://cdn.vuetifyjs.com/images/logos/vuetify-name-dark.png"
width="100"
/>
</div>
<v-spacer></v-spacer>
</v-app-bar>
<v-main>
<v-container>
<v-card elevation="0">
<v-card-title>
<v-text-field
v-model="newTask"
label="Task Name"
prepend-icon="mdi-content-save"
clear-icon="mdi-close-circle"
clearable
filled
type="text"
@click:prepend="addNewTask"
@click:clear="clearNewTask"
></v-text-field>
</v-card-title>
<v-card-text>
<v-timeline
v-if="tasks.length > 0"
dense
>
<v-timeline-item
v-for="(t, index) in tasks"
:key="index"
>
<v-row class="display-1 text-capitalize">
<v-col cols="7">
{{ t }}
</v-col>
<v-col
class="text-right"
cols="5"
>
<v-btn
icon
@click="removeTask(index)"
>
<v-icon color="red lighten-1" large>
mdi-sticker-remove
</v-icon>
</v-btn>
</v-col>
</v-row>
</v-timeline-item>
</v-timeline>
</v-card-text>
</v-card>
</v-container>
</v-main>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
tasks: ['task 1', 'task 2', 'task 3'],
newTask: null
}),
methods: {
addNewTask() {
this.tasks.push(this.newTask);
this.clearNewTask();
},
clearNewTask() {
this.newTask = '';
},
removeTask(i) {
this.tasks.splice(i, 1);
}
}
};
</script>
Сохраните и закройте файл.
Если у вас еще не запущен сервер разработки, запустите его снова:
- npm run serve
Теперь вы можете перейти к localhost:8080
, чтобы увидеть, как работает ваше приложение.
На этом шаге вы создали приложение для работы. Вы добавили функциональность и обновили интерфейс. Теперь, когда вы написали приложение, вы можете создать версию, готовую к работе. Следующим шагом будет создание приложения для производства.
Шаг 4 — Создание приложения для производства
На предыдущем шаге вы написали свое приложение для работы со списком дел. Но прежде чем опубликовать его с помощью Nginx
, вам необходимо подготовить приложение к производству. Этот шаг называется созданием приложения.
На этапе сборки приложение преобразуется во что-то, что может быть прочитано браузером. Если вы попытаетесь открыть файлы src
в браузере, вы ничего не увидите. Это связано с тем, что это файлы Vue.js, а не файлы HTML
, JS
и CSS
, которые могут читать браузеры. Перед публикацией вашего приложения с помощью Nginx вам необходимо создать приложение для производства, что вы и сделаете на этом шаге.
Вы можете использовать команду build
, чтобы сделать это автоматически. package.json
— это основной файл конфигурации вашего приложения. Он содержит информацию о зависимостях и командах, доступных для запуска или сборки вашего приложения, таких как команда build
, как показано здесь:
{
...
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
...
}
Дополнительные сведения о конфигурации файла package.json
см. в руководстве по package.json
.
Чтобы начать процесс сборки, остановите сервер разработки, нажав CTRL+C
.
В том же терминале перейдите в каталог проекта:
- cd vuetify-meets-nginx-app
Запустите команду build
:
- npm run build
Когда сборка завершится, у вас будет готовая к работе версия приложения в каталоге dist
.
Далее вы настроите Nginx в качестве обратного прокси-сервера для развертывания и доступа к приложению.
Шаг 5 — Настройка Nginx в качестве обратного прокси
Теперь, когда у вас есть работающее приложение, вы должны настроить Nginx в качестве обратного прокси-сервера для обслуживания файлов вашего приложения и подключения его к вашему доменному имени.
Обратный прокси-сервер – это приложение или служба, которая работает на сервере и перенаправляет внешние запросы в другое место. В вашем случае каждый раз, когда пользователь посещает ваш домен в браузере, Nginx будет обрабатывать этот запрос, отвечая файлом из вашего приложения. Он вернет файл, потому что когда вы создаете приложение, создаются файлы HTML, JS и CSS, которые Nginx будет обрабатывать как любые другие статические файлы или веб-сайты, которые могут быть на вашем сервере.
Nginx
работает с сайтами
. Каждый сайт — это отдельный веб-сайт, сконфигурированный в одном файле. Все файлы конфигурации по умолчанию размещаются в /etc/nginx/sites-available/
. Перейдите в этот каталог:
- cd /etc/nginx/sites-available/
Создайте файл с именем vuetify-meets-nginx-app
:
- sudo nano vuetify-meets-nginx-app
Примечание. Вы можете назвать файл как угодно, но принято называть его приложением или веб-сайтом, который вы хотите опубликовать.
В файле vuetify-meets-nginx-app
добавьте следующие строки, обязательно обновив server_name
своей собственной информацией:
server {
listen 80;
listen [::]:80;
server_name your_domain;
autoindex on;
root /home/sammy/vuetify-meets-nginx-app/dist/;
index index.html;
}
В этом руководстве вы настраиваете Nginx
для прослушивания порта 80
, но вы можете использовать любой другой порт. Замените your_domain
своим доменным именем. Вы также можете использовать IP-адрес вашего сервера или localhost
, если вы тестируете это в локальной среде разработки.
С помощью строки root
вы сообщаете Nginx, что все файлы находятся в папке /home/sammy/vuetify-meets-nginx-app/dist/.
, который был создан на предыдущем шаге. Наконец, с помощью строки index
вы сообщаете Nginx, что основным файлом является index.html
.
Сохраните и закройте файл.
Затем вам нужно решить проблему с разрешениями в файле конфигурации Nginx.
Nginx
— это служба, работающая на вашем сервере. Вы можете перечислить все запущенные процессы, связанные с Nginx, с помощью следующей команды:
- ps -fea | grep nginx
Команда ps
с флагами -fea
выводит список всех текущих процессов в полноформатном списке. Вывод этой команды затем фильтруется, чтобы отображались только процессы, соответствующие nginx
.
Вывод будет похож на следующий:
Outputroot 39922 1 0 Jul14 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 39923 39922 0 Jul14 ? 00:00:01 nginx: worker process
sammy 117909 117434 0 21:27 pts/0 00:00:00 grep --color=auto nginx
Как показано в выводе, служба nginx
работает с пользователем www-data
.
Затем проверьте разрешения /home/sammy/vuetify-meets-nginx-app/dist/
с помощью этой команды:
- ls -l /home/sammy/vuetify-meets-nginx-app/dist/
Вывод будет выглядеть примерно так:
Outputtotal 20
drwxrwxr-x 2 sammy sammy 4096 Jul 14 18:54 css
-rw-rw-r-- 1 sammy sammy 4286 Jul 14 18:54 favicon.ico
-rw-rw-r-- 1 sammy sammy 853 Jul 14 18:54 index.html
drwxrwxr-x 2 sammy sammy 4096 Jul 14 18:54 js
Все файлы и папки имеют права доступа для пользователя sammy
. Если вы настроите Nginx
для чтения этих файлов, это не сработает, потому что у пользователя Nginx www-data
нет разрешения на выполнение.
Есть несколько вариантов решения этого вопроса:
- Предоставьте Nginx права на чтение, запись и выполнение для папки
dist
. Однако предоставление службе, доступной из всей сети, разрешений на чтение локальных пользовательских файлов не является безопасным. Кроме того, Nginx потребуется разрешение на доступ ко всем родительским папкам, потому что ему нужно перейти к последней папке, которая в основном откроет миру каталог/home
. Это не рекомендуется. - Запустите
nginx
с помощьюsudo
. Это также небезопасно, так как теперь у вас будет служба с доступом ко всем файлам на вашем сервере. - Переместите содержимое
dist
в место, доступ к которому есть только у Nginx и больше ни у кого. Это самый безопасный вариант.
В этом уроке вы будете использовать третий вариант.
В Ubuntu и некоторых других дистрибутивах на основе Linux общим местом для обмена файлами между службами является путь /var
. Вы скопируете файлы в /var/www
, это путь по умолчанию, который Nginx использует для веб-сайтов.
Из каталога вашего проекта выполните следующую команду, чтобы скопировать файлы по пути /var/www
:
- sudo cp -r /home/sammy/vuetify-meets-nginx-app/dist /var/www/vuetify-meets-nginx-app
Все файлы будут скопированы с теми же разрешениями, что и раньше, то есть для пользователя sammy
, поэтому вам нужно будет добавить пользователя sammy
в ту же группу разрешений, что и www-данные
. Вы можете сделать это с помощью следующей команды:
- sudo usermod -aG www-data sammy
На этом этапе Nginx может безопасно получить доступ к необходимым файлам. Однако вам нужно будет копировать файлы проекта каждый раз, когда вы создаете новую версию приложения, что усложнит авторазвертывание, инструменты CI/CD и так далее. Лучшим решением было бы изменить команду build
для создания файлов непосредственно по правильному пути.
Для этого откройте package.json
для редактирования и добавьте выделенный текст:
...
"build": "vue-cli-service build --dest /var/www/vuetify-meets-nginx-app",
...
Сохраните и закройте файл.
Теперь вы можете завершить настройку Nginx. Откройте файл конфигурации Nginx и обновите его, указав новый путь к приложению:
server {
listen 80;
listen [::]:80;
server_name your_domain OR your_server_IP;
autoindex on;
root /var/www/vuetify-meets-nginx-app;
index index.html;
}
Сохраните и закройте файл.
Теперь, когда файл вашего сайта готов, вам нужно включить его. Для этого перейдите по пути к включенным сайтам:
- cd /etc/nginx/sites-enabled/
Отключите сайт по умолчанию, чтобы убедиться, что у вас нет двух включенных сайтов, прослушивающих один и тот же порт (порт 80
):
- sudo rm default
Наконец, создайте файл simlink в файле конфигурации вашего приложения:
- sudo ln -s /etc/nginx/sites-available/vuetify-meets-nginx-app
Nginx будет учитывать только те файлы сайта, которые находятся во включенном каталоге. Вы можете напрямую скопировать файл конфигурации, но дублировать файлы не рекомендуется, так как это может привести к несоответствиям. Вот почему simlink
, ярлык файла для доступного файла, является лучшим подходом.
Протестируйте, чтобы убедиться, что в ваших файлах Nginx нет синтаксических ошибок:
- sudo nginx -t
Ваш вывод будет выглядеть так:
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is
successful
Чтобы применить изменения, перезапустите службу Nginx:
- sudo systemctl restart nginx
Теперь вы можете перейти к своему домену (или IP-адресу вашего сервера), чтобы просмотреть готовое и опубликованное приложение для списка дел.
На этом шаге вы настроили Nginx в качестве обратного прокси-сервера для публикации вашего приложения.
Заключение
В этом руководстве вы создали приложение Vue.js, а также установили и настроили Vuetify. Затем вы создали статическую версию своего приложения, готовую к работе, и, наконец, настроили службу Nginx для ее публикации.
Для более подробного ознакомления с файлами проекта посетите репозиторий Github.
В качестве следующего шага попробуйте настроить Nginx для обслуживания вашего приложения через HTTPS. Чтобы начать работу, следуйте нашему руководству «Как защитить Nginx с помощью Let’s Encrypt в Ubuntu 20.04».
Чтобы узнать больше о Vuetify, ознакомьтесь с расширенной проверкой поля формы Vuetify.