Подготовка
Работа с Git Установка Vue CLI Client-server Примеры боевого кода
ECommerce
Работа с корзиной Работа с заказами
Пользователи
Работа с избранным Пользователи
Каталог
Работа с каталогом
Общее
Поиск Обратная связь Работа со стилями Классы для GTM
  • 1 PrologueClient
  • 2 Правила кодирования
  • 3 Жизненный цикл
  • 4 loadApp
  • 5 getApp
  • 6 loadPage
  • 7 Запрос на сервер
  • 8 ping
  • 9 middleware
  • 10 Темы интерфейса

PrologueClient

В качестве клиента, для работы связки клиент-сервер, будем использовать PrologueClient laugh

Установка:

NPM


npm i prologue-client


import prologueClient from 'prologue-client'

Инициализация и конфигурация:

prologueClient.init(
    {
        'mode': 'demo',
        'servers': {
            'demo': '/api/',
            'work': '/api/site/v1/'
        },
        'appRoutes': {
            'mainPage': '/',
            'authorizationPage': '/login/',
            'userPersonalPage': '/personal/',
        }
    }
);


Параметры:

Параметр Описание Возможные значения
mode Режим работы клиента
demo Демо-режим. Будет использован демо-сервер.
work Рабочий режим. Будет использован реальный back-end сервер.
servers Сервера
demo http путь к демо-серверу.
work http путь к реальному back-end серверу.
appRoutes Ключевые маршруты приложения
mainPage Путь к главной странице Обязательно
authorizationPage Путь к странице авторизации Если есть
userPersonalPage Путь к странице после успешной авторизации Если есть

 

Правила кодирования

enlightened enlightened enlightened 

Читаемый код важнее быстрого

 

1. Переменные

Для именования переменных используйте существительные на английском языке (ТРАНСЛИТ ИСПОЛЬЗОВАТЬ ЗАПРЕЩЕННО, ТАКИХ СЛОВ ПРОСТО НЕ СУЩЕСТВУЕТ) . Имя переменной должно быть осмысленным. Используем translate.google.com для перевода незнакомых слов.

Переменные не должны содержать цифр, подчеркиваний и русских символов и транслита.

Переменные должны именоваться в стиле lowerCamelCase

В переменных не должно быть орфографических ошибок. IDE подсказывает иногда и это сильно выручает. 

Верно:


$generalService = {};

Не верно:


$glavnayaUslyga = {};


2. Маршруты

Маршруты бывают 2-х типов: Статические и динамические.

Статические:


/contacts/

Динамические:


/catalog/:categoryCode/:productCode

Динамические маршруты состоят из двух составляющих:

Статическая часть, например: /catalog/ и динамические переменные: :categoryCode , :productCode

Переменные нужно именовать по правилу нейминга переменных.

Статическую часть маршрута нужно именовать по следующим правилам:

Для именования маршрутов используйте существительные на английском языке (ТРАНСЛИТ ИСПОЛЬЗОВАТЬ ЗАПРЕЩЕННО, ТАКИХ СЛОВ ПРОСТО НЕ СУЩЕСТВУЕТ) . Имя переменной должно быть осмысленным. Используем translate.google.com для перевода незнакомых слов.

Маршруты не должны содержать цифр, подчеркиваний и русских символов и транслита. ( транслит может присылать бек-енд в переменные, это нормально, так как это виртуальная часть маршрута, она берется из админок и в коде нигде не фиксируется  )

Маршруты всегда должны иметь нижний регистр.

Маршруты должны именоваться в стиле "слово-слово" например: /products-catalog/

Если есть вложенность, то нужно использовать слеши: /about/history/

Верно:


/login/
/blog/
/blog/:articleCode
/personal/orders-history/

Не верно:


/vhod/
/novosti/
/blog/:kodStati
/lichnyj-kabinet/zakazy/


Жизненный цикл

cool

 Современные web приложения - это динамичные модели взаимодействия клиента и сервера.

Цикл:
  1. Запуск http соединения
  2. Загрузка фронтенда
  3. Вызов метода loadApp
  4. Загрузка страницы
  5. Загрузка динамических компонентов
  6. Вызов метода ping
  7. Вызов методов взаимодействия
  8. Закрытие http соединения, утилизация

Схема жизненного цикла


 

Запуск http соединения

Самый первый этап взаимодействия с приложением, наступает когда уходит http запрос на сервер

Загрузка фронтенда

После того, как запрос http  ушел на сервер, сервер возвращает содержимое html файла, в котором подключаются скрипты, стили и т.п.

Когда js файл загрузился, загружается front-end приложения

Вызов метода loadApp

Метод loadApp - загружает основные данные приложения, которые в дальнейшем не нужно запрашивать, либо пере-запрашивать в редких случаях.

Загрузка страницы

После того, как приложение загружено, необходимо загрузить страницу для текущего маршрута, например для главной страницы / или для страницы Контакты /contacts/

Загрузка динамических компонентов

Часто бывает что страницу нельзя загружать полностью, так как она слишком сложная и если все компоненты поместить в loadPage() - то страница будет грузится от нескольких секунд, до нескольких десятков секунд что является неприемлемо.

К примеру есть детальная страница товара на этой странице есть очень много разных компонентов таких как:

  • Слайдер с изображениями ( 0.04 секунды )
  • Цены  ( 0.02 секунды )
  • Описание  ( 0.05 секунды )
  • Компонент покупки  ( 0.07 секунды )
  • Календарь с доступными месяцами покупки  ( 1 секунда )
  • Отзывы  ( 0.5 секунды )

Получаем суммарное время загрузки: 1,68 секунды - это много. Выходи что из за тяжелого календаря мы не увидим изображения, цены, описания сразу, придется ждать загрузки календаря.

Для того, чтобы пользователь моментально увидел полезный контент, нужно разбить запросы на такой вид:

loadPage - загружает:

  • Слайдер с изображениями
  • Компонент покупки
  • Описание 
  • Цены 

Как только loadPage вернет данные, вызываем метод loadCalendar() - пока человек изучает первый экран с ценами, описанием и фото, ниже работает прелоадер и фоново подгружается календарь. 

После календаря есть компонент Отзывы, но не нужно спешить его загружать, так как человек попросту может не проскроллить вниз.

Метод loadReviews() стоит вызвать только тогда, когда мы доскроллили до календаря и смотрим его, а ниже будет фоново подгружен компонент с отзывами.

 

 

Вызов метода ping

Метод поддерживает связь с сервером отправляя Ping через установленные промежутки времени.

Вызов методов взаимодействия

Когда приложение и страница загружена, пользователь может не только читать информацию с экрана, а еще и взаимодействовать с интерфейсом. 

Например:

Пользователь открыл страницу с товаром, страница загрузилась.

2 минуты пользователь изучал товар, смотрел фото, читал описание. Потом пользователь нажимает на кнопку Добавить в корзину.

В этот момент по клику на кнопку front-end вызывает метод addProductToCart() и на сервер уходит запрос с id товара и его количеством. И подобных вызовом различных компонентов может быть огромное количество. В сложных сервисах люди находятся на страничках несколько часов подряд и постоянно взаимодействуют с приложением. Пример соц-сети или мессенжеры.

Закрытие http соединения, утилизация

Когда пользователь прекратил использование приложения, закрыл вкладку или приложение, то связь с клиентом потеряна. 

Происходит закрытие http соединения и утилизация сеанса.

 

loadApp

Метод загружает основные данные приложения, которые в дальнейшем не нужно запрашивать, либо пере-запрашивать в редких случаях.

Клиент

Вызов метода:


prologueClient.loader.loadApp({
    'route': 'MainModule:loadApp'
}, (appData) => {
    // App is load! Use appData
});

Параметры:

Параметр Описание Значение по умолчанию
route Маршрут запроса MainModule:loadApp
timeOut Время через которое будет отправлен запрос 1000
 
Сервер

В ответе сервера обязательно должен содержаться объект app и вложенный объект app.userData

 


{
  "app": {
    "access": {
      "isLoginSuccess": 1,
      "tokens": {
        "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
        "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
      }
    },
    "userData": {
      "id": 1,
      "isAuth": 1
    }
  }
}

В объект app могут быть вложены любые данные, которые понадобятся приложению

Пример


{
    "app" : {
       "userData" : {
            "id" : 0,
            "isAuth" : 0
        }, 
        "logo" : {
            "src" : "logo.svg",
            "link" : "/"
        }, 
        "menu" : [
            {
                "id" : 1,
                "title" : "Главная",
                "link" : "/"
            },
            {
                "id" : 2,
                "title" : "Каталог товаров",
                "link" : "/catalog/"
            }
        ]
    }
}

Обязательные вложения объекта app:

Ключ Описание Возможные значения
access Доступ
isLoginSuccess 0 - не авторизован, 1 - авторизован
tokens Токены доступа
userData Состояния пользователя
id Id пользователя
isAuth 0 - не авторизован, 1 - авторизован

 

Метод loadApp сохранит данные приложения в память. Получить доступ к данным можно в любой момент используя метод prologueClient.loader.getApp()

getApp

После запуска метода prologueClient.loader.loadApp() можно получать доступ к данным приложения используя метод:


prologueClient.loader.getApp()

Пример:


let App = PrologueClient.loader.getApp();

let menu = App.menu;

 

loadPage

Метод реализует загрузку данных для шаблонизации страницы.

Как правило, метод вызывается при смене url адреса приложения.

enlightenedenlightenedenlightened

Перед вызовом метода, рекомендуется запустить локальный прелоадер, так как загрузка страницы может занять некоторое время, как правило от 0.1 сек, до 1-2 секунд в зависимости от back-end загрузки.

В колбек функции метода, после шаблонизации данных,  необходимо отключить локальный прелоадер.

Клиент

Загрузить страницу без параметров


prologueClient.loader.loadPage(
    {
        'route': 'Contacts:loadPage',
        'params': {}
    }, (response) => {
        // use response
    }
);

Загрузить страницу с параметрами

cool

В данном случае categoryCode будет браться из маршрута /catalog/:categoryCode


prologueClient.loader.loadPage(
    {
        'route': 'Catalog:loadCategoryPage',
        'params': {
            'categoryCode': 'dresses'
        }
    }, (response) => {
        // use response
    }
);

ВАЖНО!

Для того, чтобы метаданные установились корректно, в разметке обязательно должен быть заголовок страницы в теге h1

 

Сервер

В ответе сервера обязательно должен содержаться объект metaData


{
    "metaData" : {
        "title" : "Заголовок окна браузера",
        "description" : "Описание страницы",
        "h1" : "Заголовок страницы"
    }
}

В объекте metaData содержится базовая информация о странице

В ответе сервера обязательно должен содержаться объект content


{
  "content": {

  }
}


В объекте content сервер помещает весь контент который нужно предоставить клиенту

В итоге ответ должен быть таким:



{
  "metaData" : {
      "title" : "Заголовок окна браузера",
      "description" : "Описание страницы",
      "h1" : "Заголовок страницы"
  },
  "content": {

  }
}

Response:

Ключ Описание Возможные значения
metaData Метаданные
title Заголовок окна браузера
description Описание страницы
h1 Заголовок страницы
content Контент Объекты контента страницы

Запрос на сервер

Для реализации запроса на сервер используется метод:

prologueClient.queryToServer(Маршрут, Параметры, Колбек)

Маршрут - http путь к back-end endpoint

Маршрут строится по следующему правилу: домен + маршрут. Домен используется из параметров инициализации: 

servers.demo или servers.work

Существует два типа маршрутов: Типизированные и не типизированные

Типизированные маршруты строятся по шаблону Модуль:метод

Примеры:

Маршрут http запрос Описание
MainModule:loadApp /MainModule/?action=loadApp

Вызвать метод 

loadApp который находится в главном модуле

Cart:addProductToCart /Cart/?action=addProductToCart

Вызвать метод 

addProductToCart который находится корзине

ContactsPage:getPage /ContactsPage/?action=getPage

Вызвать метод 

getPage который находится на странице контактов

 

Не типизированные маршруты строятся без шаблона, указывается прямой endpoint

Примеры:

Маршрут http запрос Описание
/main/load-app/ /main/load-app/ Загрузить приложение
/cart/add-product-to-cart/ /cart/add-product-to-cart/ Добавить товар в корзину
http://contacts/get-page/ /contacts/get-page/ Получить страницу Контакты

Параметры - объект данных который будет передан на сервер


{
"productId" : 1,
"quantity" : 1
}

Колбек - функция которая будет вызвана после того, как ответит сервер. Внутри функции будет доступен объект response


(response) => {
    // use response
}

Использование


prologueClient.queryToServer('MainModule:sampleRequest', {
    'id': 1,
}, (serverData) => {
    // use serverData
});

Пример:

Получить пользователя по его id


prologueClient.queryToServer('Users:getUser', {
    'userId': 5,
}, (serverData) => {
    
    let user = serverData.uerData;
    
});

Прелоадер:

Перед отправкой запроса зачастую требуется включать прелоадер для определенного блока.

Это можно сделать с помощью функции: prologueClient.preload(блокКоторыйНужноПрелоадить)

После выполнения запроса необходимо убрать прелоадер. 

Это можно сделать с помощью функции: prologueClient.unPreload()

Пример использования встроенного прелоадера:


prologueClient.preload('.loginForm');

prologueClient.queryToServer('Users:login', {'login': '9783674485', 'password': 'ty3452'}, (res) => {

  prologueClient.unPreload();

});

Обработка ошибок

Сервер будет присылать ошибки, их нужно обрабатывать и выводить пользователю.

Перед отпавкой запроса можно использовать метод: prologueClient.setErrorWrapper(селекторБлокаВКоторыйВыводитьОшибки)

Если ошибки придут с сервера, то их содержимое вставится в блок селекторБлокаВКоторыйВыводитьОшибки

Комплексный пример запроса с прелоадером и обработкой ошибок:


prologueClient.preload('.loginForm');

prologueClient.setErrorWrapper('.js-error');

prologueClient.queryToServer('Users:login', {'login': '9783674485', 'password': 'ty3452'}, (res) => {
  

});

cool Стоит заметить, если использовать обработку ошибок, то вызывать prologueClient.unPreload() после ответа, нем смысла, клиент все сделает автоматически.

 

ping

Метод поддерживает связь с сервером отправляя Ping через установленные промежутки времени.

Задача заключается в том, чтобы не потерять связь с сервером.

Ping реализует:

  1. Проверку целостности соединения с сервером
  2. Проверку авторизации пользователя
  3. Обработку холодной перезагрузки
Клиент

prologueClient.loader.ping({
    'route': 'MainModule:ping',
    'timeInterval': 1000,
}, (serverResponse) => {
    // Use serverResponse
});

 

Параметры:

Параметр Описание Значение по умолчанию
route Маршрут запроса MainModule:ping
timeInterval Интервал времени для запросов 30000

 

Сервер

В ответе сервера обязательно должен содержаться объект state


{
  "state": {
    "isHttpConnect": 1,
    "reloadFrontEnd": 0,
    "access": {
      "isLoginSuccess": 1,
      "tokens": {
        "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
        "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
      }
    },
    "userData": {
      "id": 1,
      "isAuth": 1
    }
  }
}

 

Объект state:

Ключ Описание Возможные значения
isHttpConnect Состояние соединения
1 Все корректно
0 Http соединение отсутствует
access Доступ
isLoginSuccess 0 - не авторизован, 1 - авторизован
tokens Токены доступа
userData Состояния пользователя
id Id пользователя
isAuth 0 - не авторизован, 1 - авторизован
authToken Токен авторизации
reloadFrontEnd Холодная перезагрузка
1 Перезагрузить приложение в холодную
0 Не перезагружать приложение

 

Состояние соединения

Если соединение отсутствует, будет выведено сообщение о сетевой ошибке.

Запрос будет повторятся до тех пор, пока соединение не появится.

Состояния пользователя

Состояние пользователя помещается в память, доступ к объекту можно получить используя метод: PrologueClient.passport.getUserData()

Состояние пользователя обрабатывается посредниками middleware для обеспечение аутентификации.

Холодная перезагрузка

Если сервер вернет reloadFrontEnd : 1, то пользователю будет выведено сообщение о перезагрузке и приложение перезагрузится через 10 секунд.

middleware

Middleware - механизм промежуточных взаимодействий между компонентами.

isUserAuth

Данный посредник проверяет авторизован ли пользователь.

Если пользователь не авторизован, то он будет перенаправлен на страницу авторизации.

Используется чтобы закрыть доступ к разделу для неавторизованного пользователя.

Использование:


prologueClient.middleware.isUserAuth();

 
isUserNoAuth

Данный посредник проверяет авторизацию пользователя.

Если пользователь авторизован, то он будет перенаправлен на страницу которая доступна после авторизации, например страница личного кабинета.

Используется чтобы закрыть доступ к разделу авторизации или регистрации для уже авторизованного пользователя.

Использование:


prologueClient.middleware.isUserNoAuth();

Темы интерфейса

blush

Для того, чтобы пользователю было комфортно пользоваться приложением, необходимо дать ему выбор тем.

По умолчанию существуют две общепринятые темы: cветлая и темная.

Список основных тем

Тема Код
Светлая light
Темная dark

 

Получить тему устройства

Используется чтобы получить тему которая задана в ОС устройстве пользователя


let themeCode = prologueClient.appInterface.theme.getDeviceTheme();

Получить тему приложения

Возвращает код темы которое было задано для приложения, по умолчанию возвращает тему устройства


let themeCode = prologueClient.appInterface.theme.getAppTheme();

Установить тему приложения

Устанавливает тему для приложения


prologueClient.appInterface.theme.setAppTheme(
    {
        'themeCode': 'dark'
    }
);

Подписаться на изменение темы

prologueClient.appInterface.theme.listenChangesTheme((themeCode) => {
    // use themeCode
});

Используется для того, чтобы на основе темы установить стили приложения.

Например: 


if(themeCode === 'dark') {

   setDarkStyles();

}