Поиск по сайту:

Как опубликовать приложение 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 с помощью этой команды:

  1. sudo npm install -g @vue/cli

Далее подтвердите версию:

  1. vue --version

Последней версией, на момент написания этого руководства, была 5.0.8:

Output
@vue/cli 5.0.8

Теперь, когда вы установили @vue/cli, вы можете использовать его для создания приложения vuejs. В этом руководстве приложение будет называться vuetify-meets-nginx-app, но вы можете изменить имя на любое другое.

Чтобы создать приложение, выполните эту команду:

  1. vue create vuetify-meets-nginx-app

Эта команда является интерактивной и имеет несколько параметров. Для этого руководства выберите параметр Default для Vue 2:

Output
Vue 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, вы увидите эту ошибку:

Output
Error: 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: этот файл также необходим для компиляции приложения. Например, этот файл задает для версии кода Javascript ECMAScript 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:

  1. cd vuetify-meets-nginx-app

Чтобы запустить приложение в режиме разработки, выполните следующую команду:

  1. npm run serve

Ваш вывод будет выглядеть так:

Output
INFO 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. Пока сервер разработки все еще работает, откройте другой терминал на локальном компьютере и введите следующую команду, чтобы инициировать переадресацию портов:

  1. 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:

  1. 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)

Через несколько минут можно снова запустить сервер разработки:

  1. npm run serve

Перейдите к localhost:8080, где вы можете увидеть приложение с новым стилем vuetified:

На данный момент вы создали базовое приложение и добавили Vuetify для стилизации. Далее вы создадите приложение с дополнительными функциями.

Шаг 3 — Создание приложения To-Do Vuetify

На этом шаге вы создадите приложение для работы. Приложение to-do — это список задач, для выполнения которых потребуются некоторые базовые функции:

  • Способ добавления новых задач.
  • Способ пометить их как выполненные.
  • Метод их отображения, позволяющий пользователям видеть, что ожидается.

Чтобы добавить эти функции в свое приложение, вы измените файл App.vue, который является компонентом верхнего уровня приложения. Все остальные компоненты будут находиться внутри компонента, определенного здесь.

Примечание:

Перейдите к src/App.vue и откройте его для редактирования с помощью nano или вашего любимого текстового редактора:

  1. cd src
  2. 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>

Сохраните и закройте файл.

Если у вас еще не запущен сервер разработки, запустите его снова:

  1. 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.

В том же терминале перейдите в каталог проекта:

  1. cd vuetify-meets-nginx-app

Запустите команду build:

  1. npm run build

Когда сборка завершится, у вас будет готовая к работе версия приложения в каталоге dist.

Далее вы настроите Nginx в качестве обратного прокси-сервера для развертывания и доступа к приложению.

Шаг 5 — Настройка Nginx в качестве обратного прокси

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

Обратный прокси-сервер – это приложение или служба, которая работает на сервере и перенаправляет внешние запросы в другое место. В вашем случае каждый раз, когда пользователь посещает ваш домен в браузере, Nginx будет обрабатывать этот запрос, отвечая файлом из вашего приложения. Он вернет файл, потому что когда вы создаете приложение, создаются файлы HTML, JS и CSS, которые Nginx будет обрабатывать как любые другие статические файлы или веб-сайты, которые могут быть на вашем сервере.

Nginx работает с сайтами. Каждый сайт — это отдельный веб-сайт, сконфигурированный в одном файле. Все файлы конфигурации по умолчанию размещаются в /etc/nginx/sites-available/. Перейдите в этот каталог:

  1. cd /etc/nginx/sites-available/

Создайте файл с именем vuetify-meets-nginx-app:

  1. 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, с помощью следующей команды:

  1. ps -fea | grep nginx

Команда ps с флагами -fea выводит список всех текущих процессов в полноформатном списке. Вывод этой команды затем фильтруется, чтобы отображались только процессы, соответствующие nginx.

Вывод будет похож на следующий:

Output
root 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/ с помощью этой команды:

  1. ls -l /home/sammy/vuetify-meets-nginx-app/dist/

Вывод будет выглядеть примерно так:

Output
total 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:

  1. sudo cp -r /home/sammy/vuetify-meets-nginx-app/dist /var/www/vuetify-meets-nginx-app

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

  1. 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;
}

Сохраните и закройте файл.

Теперь, когда файл вашего сайта готов, вам нужно включить его. Для этого перейдите по пути к включенным сайтам:

  1. cd /etc/nginx/sites-enabled/

Отключите сайт по умолчанию, чтобы убедиться, что у вас нет двух включенных сайтов, прослушивающих один и тот же порт (порт 80):

  1. sudo rm default

Наконец, создайте файл simlink в файле конфигурации вашего приложения:

  1. sudo ln -s /etc/nginx/sites-available/vuetify-meets-nginx-app

Nginx будет учитывать только те файлы сайта, которые находятся во включенном каталоге. Вы можете напрямую скопировать файл конфигурации, но дублировать файлы не рекомендуется, так как это может привести к несоответствиям. Вот почему simlink, ярлык файла для доступного файла, является лучшим подходом.

Протестируйте, чтобы убедиться, что в ваших файлах Nginx нет синтаксических ошибок:

  1. sudo nginx -t

Ваш вывод будет выглядеть так:

Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

Чтобы применить изменения, перезапустите службу Nginx:

  1. sudo systemctl restart nginx

Теперь вы можете перейти к своему домену (или IP-адресу вашего сервера), чтобы просмотреть готовое и опубликованное приложение для списка дел.

На этом шаге вы настроили Nginx в качестве обратного прокси-сервера для публикации вашего приложения.

Заключение

В этом руководстве вы создали приложение Vue.js, а также установили и настроили Vuetify. Затем вы создали статическую версию своего приложения, готовую к работе, и, наконец, настроили службу Nginx для ее публикации.

Для более подробного ознакомления с файлами проекта посетите репозиторий Github.

В качестве следующего шага попробуйте настроить Nginx для обслуживания вашего приложения через HTTPS. Чтобы начать работу, следуйте нашему руководству «Как защитить Nginx с помощью Let’s Encrypt в Ubuntu 20.04».

Чтобы узнать больше о Vuetify, ознакомьтесь с расширенной проверкой поля формы Vuetify.