Skip to content

Commit

Permalink
добавил комментарии
Browse files Browse the repository at this point in the history
  • Loading branch information
dergunovs committed Mar 16, 2021
1 parent 7aab00b commit 97e758f
Show file tree
Hide file tree
Showing 16 changed files with 177 additions and 50 deletions.
6 changes: 4 additions & 2 deletions app/views/error.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
<title>Ошибка сервера</title>
</head>
<body>
<h1>Шаблон серверной ошибки</h1>
<a href="/">Перейти на главную страницу сайта</a>
<h1>Шаблон страницы с серверной ошибкой</h1>
<p><a href="/">Перейти на главную страницу сайта</a></p>
<p>Вы окажитесь тут, если введёте неправильный URL в разделе с динамическими страницами.</p>
<p>Это отдельный шаблон, который не связан с основным приложением.</p>
</body>
</html>
1 change: 0 additions & 1 deletion assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ body {

main {
padding: 16px;
text-align: center;
}

button {
Expand Down
2 changes: 2 additions & 0 deletions assets/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Папка для хранения динамического контента.
Например, при production сборке в CSS файлах будут автоматически удаляться пробелы и пустые строки.
31 changes: 25 additions & 6 deletions components/PageForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,22 @@

<script>
export default {
name: "PageForm",
// Это переиспользуемый компонент с формой для создания/редактирования/удаления страницы.
// В зависимости от поступаемых пропсов меняется отображение кнопок.
// При редактировании данных в пропсах передаётся контент конкретной страницы.
props: { page: { type: Object, default: () => ({}) }, action: { type: String } },
// Нам потребуется текущий URL страницы, которые не будет связан с input формы.
data() {
return {
currentUrl: "",
};
},
methods: {
createPage() {
// Создаём новую страницу.
this.$axios
.post(`/api/page`, this.page)
.then(() => {
Expand All @@ -40,36 +53,42 @@ export default {
.catch((err) => console.log(err.response.data.message));
},
updatePage() {
// При обновлении текущей страницы нужен исходный URL для запроса в API.
this.$axios
.patch(`/api/page/${this.page.url}`, this.page)
.patch(`/api/page/${this.currentUrl}`, this.page)
.then(() => {
this.$router.push(`/page`);
})
.catch((err) => console.log(err.response.data.message));
},
deletePage() {
// При удалении страницы также используем текущий URL, а не изменяемый URL в форме.
this.$axios
.delete(`/api/page/${this.page.url}`)
.delete(`/api/page/${this.currentUrl}`)
.then(() => {
this.$router.push(`/page`);
})
.catch((err) => console.log(err.response.data.message));
},
},
mounted() {
// Сохраняем текущий URL на стадии mount компонента.
this.currentUrl = this.page.url;
},
};
</script>

<style>
.form {
width: 100%;
max-width: 600px;
margin: auto;
width: 600px;
}
.form-element {
display: flex;
flex-direction: column;
margin: 16px;
margin-top: 16px;
}
.form-element input,
.form-element textarea {
margin-top: 4px;
Expand Down
9 changes: 4 additions & 5 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
export default {
head() {
return {
// Установка rel="canonical" на всех страницах шаблона.
link: [{ rel: "canonical", href: `${process.env.baseUrl}${this.$route.path}` }],
meta: [
{ hid: "og:url", property: "og:url", content: `${process.env.baseUrl}${this.$route.path}` },
{ hid: "og:type", property: "og:type", content: "website" },
{ hid: "og:locale", property: "og:locale", content: "ru_RU" },
],
// Пример установки общих мета-тегов на страницах.
meta: [{ hid: "og:url", property: "og:url", content: `${process.env.baseUrl}${this.$route.path}` }],
};
},
};
Expand Down
3 changes: 2 additions & 1 deletion layouts/error.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<template>
<main>
<h1>Шаблон клиентской ошибки с кодом {{ error.statusCode }}</h1>
<h1>Ошибка с кодом {{ error.statusCode }}</h1>
<nuxt-link to="/">Перейти на главную страницу.</nuxt-link>
</main>
</template>

<script>
export default {
// Шаблон страницы с клиентской ошибкой.
props: ["error"],
layout: "default",
};
Expand Down
22 changes: 19 additions & 3 deletions nuxt.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
// process.env.PORT и process.env.BASE_URL берутся из файла .env

module.exports = {
// Указываем порт, на котором будет работать приложение.
server: {
port: process.env.PORT,
host: "localhost",
},

// Передаём во фронт данные из .env. Эта переменная будет доступна через process.env.baseUrl.
// Важно! Эти данные будут видны в коде сайта. Не передавайте таким образом пароли и т.д.
// Если данные есть в .env, но их не передали на фронт, то их нет в коде сайта, они доступны только в бэкенде.
env: {
baseUrl: process.env.BASE_URL,
},

// Глобальные настройки секции Head. Можно прописать общие мета-теги, атрибуты и прочее.
head: {
htmlAttrs: { lang: "ru" },
meta: [
Expand All @@ -18,22 +25,31 @@ module.exports = {
link: [{ rel: "icon", href: "/favicon.ico", type: "image/x-icon" }],
},

// Включаем автоматическое подключение компонентов.
components: true,

// Отключаем передачу анонимных данных о работе приложения в Nuxt.
telemetry: false,

// Отключаем индикацию загрузки страниц.
loading: false,
loadingIndicator: false,
components: true,

// Отключаем предварительную загрузку контента, на который есть ссылки на текущей страницы.
router: { prefetchLinks: false },

//Подключаем модуль Axios для выполнения запросов к бэкенду.
modules: ["@nuxtjs/axios"],

//Подключаем общий файл со стилями.
css: ["@/assets/css/main.css"],

//Подключаем proxy от axios и прописывам базовый URL для пути /api/
axios: { proxy: true },
proxy: { "/api/": process.env.BASE_URL },

build: {
// Просим стили вырезать в отдельные файлы. Иначе css будет inline.
extractCSS: true,
devMiddleware: { headers: { "Cache-Control": "no-store", Vary: "*" } },
corejs: 3,
},
};
18 changes: 8 additions & 10 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,17 @@

<script>
export default {
data() {
return {
title: "Шаблон Nuxt-Express",
description: "Описание контента главной страницы сайта",
};
},
head() {
// У всех страниц должны быть title и description.
let title = "Шаблон Nuxt-Express";
let description = "Описание контента главной страницы сайта";
return {
title: this.title,
title: title,
meta: [
{ hid: "description", name: "description", content: this.description },
{ hid: "og:title", property: "og:title", content: this.title },
{ hid: "og:description", property: "og:description", content: this.description },
{ hid: "description", name: "description", content: description },
{ hid: "og:title", property: "og:title", content: title },
{ hid: "og:description", property: "og:description", content: description },
],
};
},
Expand Down
6 changes: 6 additions & 0 deletions pages/page/_url.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@

<script>
export default {
// Получаем конкретную страницу с URL, который берётся из params.
async asyncData({ $axios, params }) {
const { data } = await $axios.get(`/api/page/${params.url}`);
return { page: data };
},
data() {
return {
page: { url: "", h1: "", title: "", description: "", content: "" },
// При нажатии на кнопку "Редактировать" показывается форма. По-умолчанию она скрыта.
showPageForm: false,
};
},
head() {
return {
// Title и Description конкретной страницы берутся из данных, которые приходят через asyncData.
title: this.page.title,
meta: [
{ hid: "description", name: "description", content: this.page.description },
Expand Down
19 changes: 9 additions & 10 deletions pages/page/create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@

<script>
export default {
data() {
return {
title: "Создать страницу",
description: "Создать динамическую страницу = запись в базе",
};
},
head() {
let title = "Создать страницу";
let description = "Создать динамическую страницу = запись в базе";
return {
title: this.title,
title: title,
meta: [
{ hid: "description", name: "description", content: this.description },
{ hid: "og:title", property: "og:title", content: this.title },
{ hid: "og:description", property: "og:description", content: this.description },
{ hid: "description", name: "description", content: description },
{ hid: "og:title", property: "og:title", content: title },
{ hid: "og:description", property: "og:description", content: description },
// Указываем роботам поисковых систем, что текущую страницу не нужно индексировать.
{ name: "robots", content: "noindex, nofollow" },
],
};
Expand Down
26 changes: 14 additions & 12 deletions pages/page/index.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
<template>
<main>
<h1>Список страниц</h1>

<nuxt-link :to="`/page/${page.url}`" v-for="page in pages" :key="page.h1">{{ page.h1 }}</nuxt-link>
<ul>
<li v-for="page in pages" :key="page.h1">
<nuxt-link :to="`/page/${page.url}`">{{ page.h1 }}</nuxt-link>
</li>
</ul>
</main>
</template>

<script>
export default {
async asyncData({ $axios }) {
// Получаем список динамических страниц сайта из API.
const { data } = await $axios.get(`/api/page/`);
return { pages: data };
},
data() {
return {
title: "Список страниц",
description: "Список динамических страниц сайта",
};
},
head() {
let title = "Список страниц";
let description = "Список динамических страниц сайта";
return {
title: this.title,
title: title,
meta: [
{ hid: "description", name: "description", content: this.description },
{ hid: "og:title", property: "og:title", content: this.title },
{ hid: "og:description", property: "og:description", content: this.description },
{ hid: "description", name: "description", content: description },
{ hid: "og:title", property: "og:title", content: title },
{ hid: "og:description", property: "og:description", content: description },
],
};
},
Expand Down
54 changes: 54 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Nuxt-Express

Базовый шаблон для работы Nuxt в качестве middleware для Express.
Приложение работает в едином процессе.

### Используемые технологии

Nuxt.js, Express.js, Mongoose.js, MongoDB.

### Установка

Предварительно установите Node.js (https://nodejs.org/en/) и MongoDB (https://www.mongodb.com/try/download/community).
Затем в консоли пропишите:

```bash
npm install
```

### Настройка глобальных переменных

В корневой папке проекта создайте файл ".env". В нём укажите:

- BASE_URL: домен вашего сайта
- PORT: порт, на котором будет работать приложение
- DATABASE: название базы MongoDB, с которой будет работать приложение

Например, для разработки:

```bash
BASE_URL=http://localhost:3000
PORT=3000
SECRET=site
```

Для production:

```bash
BASE_URL=https://site.ru
PORT=3000
SECRET=site
```

### Запуск в режиме разработки

```bash
npm run dev
```

### Запуск в продакшене

```bash
npm run build
npm start
```
9 changes: 9 additions & 0 deletions server/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// Основной файл запуска приложения.

require("dotenv").config();

// Подключаем бэкенд на Express.
const express = require("express");
const app = express();
app.use(express.json());

// Подключаем Mongoose и делаем коннект к базе.
// Прописывает стандартные настройки Mongoose.
const mongoose = require("mongoose");
mongoose.Schema.Types.Boolean.convertToFalse.add("");
mongoose.connect(`mongodb://localhost/${process.env.DATABASE}`, {
Expand All @@ -13,9 +18,12 @@ mongoose.connect(`mongodb://localhost/${process.env.DATABASE}`, {
useUnifiedTopology: true,
});

// Подключаем маршруты для управления моделью Page.
const pageRoutes = require("./routes/page");
app.use("/api/page", pageRoutes);

// Подключаем Nuxt в режиме nuxt.render. В этом примере нет отдельного процесса с Nuxt.
// Nuxt работает в качестве middleware для Express без своего сервера на Connect.
const { loadNuxt, build } = require("nuxt");
const isDev = process.env.NODE_ENV !== "production";
async function start() {
Expand All @@ -27,4 +35,5 @@ async function start() {
app.listen(process.env.PORT);
}

// Запуск приложения.
start();
Loading

0 comments on commit 97e758f

Please sign in to comment.