Остальные компоненты админки

Честно говоря, не думал, что только знакомство с системой затянется аж на 10 заметок. Мне-то оно всё давно привычно и понятно, а вот когда пытаешься внятно об этом рассказать...
В общем, сегодня мы заканчиваем вводную часть, и дальше будет настоящая работа по постройке магазина VespShop.
На нужно посмотреть, какие еще компоненты я написал для удобной работы на Vesp, и начнём с переключателя языка - vesp-change-locale (по клику откроется GIFка)

vesp-change-locale

Как я уже упоминал, мультиязычность админки работает при помощи модуля @nuxtjs/i18n, который в свою очередь использует популярнейший Vue i18n.
Все лексиконы хранятся в src/admin/lexicons и загружаются через index.js, где происходит соединение стандартных и пользовательских словарей. Вам просто нужно добавлять соответствующие значения в файлы ru.js, en.js и de.js.
Я в своей работе обычно использую только 2 словаря: английский и немецкий, поэтому мой конфиг в nuxt.config.js выглядит так:
// Меняем всего 2 параметра:
// - файл с загрузкой лексиконов
Config.i18n.vueI18n = '@/lexicons/index.js'
// - и доступные языки
Config.i18n.locales = [
  {code: 'en', title: 'English'},
  {code: 'de', title: 'Deutsch'},
]
Именно массив из Config.i18n.locales будет использован в vesp-change-locale для вывода и переключения языков.
Файл src/admin/lexicons/index.js будет выглядеть следующим образом:
import merge from 'deepmerge'
import vespDe from '@vesp/frontend/lexicons/de'
import vespEn from '@vesp/frontend/lexicons/en'
import localDe from './de'
import localEn from './en'

// Здесь возвращается именно функция, чтобы при изменении словарей
// во время разработки работало обновление страницы через hot reload
export default () => {
  return {
    // Словарь по умолчанию
    fallbackLocale: 'en',
    // Доступные словари
    messages: {
      de: merge(vespDe, localDe),
      en: merge(vespEn, localEn),
    },
  }
}
Библиотека deepmerge позволяет нам рекурсивно соединить 2 объекта со словарями.
Если вам мультиязычность не нужна, то я всё равно рекомендую использовать лексиконы. Во-первых, их всё равно будут использовать компоненты Vesp, а во-вторых это просто удобно для работы.
Если вы хотите оставить только один язык, например, русский, то нужно поменять настройки таким образом:
// Заменяем весь стандартный конфиг своим
Config.i18n = {
  defaultLocale: 'ru', // Оставляем 1 язык
  strategy: 'no_prefix',
  vueI18n: '@/lexicons/index.js',
}
Ну а в lexicons/index.js оставляем только один словарь.
import merge from 'deepmerge'
import vespRu from '@vesp/frontend/lexicons/ru'
import localRu from './ru'

export default () => {
  return {
    fallbackLocale: 'ru',
    messages: {
      ru: merge(vespRu, localRu),
    },
  }
}
Использование компонента vesp-change-locale в таком случае не имеет смысла, потому что переключать нам нечего.

vesp-input-color-picker

Дальше у нас идут различные способы ввода, которые дополняют (а иногда и расширяют) имеющиеся в BootstrapVue.
Например, компонент выбора цвета:
При вызове нужно просто указать v-model, в который будет записан выбранный цвет:
<vesp-input-color-picker v-model="record.color" />
При редактировании модели, если какой-то цвет уже указан, он будет сразу выставлен в компоненте.

vesp-input-combo-box

Это компонент для поиска и выбора id модели из списка. Он обращается к указанному url методом GET, и рассчитывает на обычный ответ от контроллера с полями total и rows.
Вы уже могли видеть его в форме редактирования пользователя, здесь приведу в расширенном виде:
<vesp-input-combo-box 
    v-model="record.role_id" 
    url="admin/user-roles" 
    text-field="title" 
    value-field="id"
    limit="10"
    sort="title"
    dir="asc"
 />
Параметры text-field и value-field указывают, какое поле в ответе от сервера использовать для названия, а какое для значения v-model. Все остальные параметры, полагаю, и так понятны.
При запросе на сервер обязательно передаётся параметр combo=true, чтобы вы могли прописать в контроллере отдельные правила для выборки.
if ($this->getProperty('combo')) {
    // ...
}
Этот компонент я использую постоянно, например при написании этой заметки для выбора раздела:

vesp-input-date-picker

Хотя в BootstrapVue и есть свой собственный date-picker, меня он по ряду причин не устраивает. В первую очередь, он не умеет работать с диапазоном дат.
Поэтому, если вы указываете v-model массивом, даже пустым, то будет диапазон.
А если строкой - то обычная дата
Здесь внизу я вывел реальное значение v-model, чтобы вы заметили, что там может быть массив или строка. Это значение и улетит на сервер, где вы сможете проверить тип присланных данных.
Выбор времени даты определяется наличием параметра type="datetime", по умолчанию там type="date"
<vesp-input-date-picker v-model="record.date" type="datetime" />

vesp-input-password

Это обычное поле ввода пароля, которое при нажатии на кнопочку показывает или скрывает набранное.
<vesp-input-password v-model="record.password" />

vesp-input-remote-links

Этот очень интересный компонент предназначен для сохранения разных ссылок в одном массиве. Бывает очень полезно в разных проектах прицепить модели JSON колонку и хранить в ней ссылки на соц.сети.
Здесь я тоже внизу показываю реальное значение поля ввода.
<vesp-input-remote-links
    v-model="record.links"
    :services="{facebook: 'Facebook', instagram: 'Instagram', twitter: 'Twitter'}"
/>
Как видите, на Vue можно создавать очень интересные компоненты ввода для форм.

input-text-mask

И последний компонент очень полезен, если нам нужно ограничить ввод текстовой маской. Например, для российских телефонов
Как видите, истиное значение v-model оставляет только цифры и знак +:
<vesp-input-text-mask
    v-model="record.phone"
    mask="+7 (XXX) XXX-XX-XX"
    placeholder-char="X"
    :state="!record.phone ? null : record.phone.length === 12"
    :format-value="(value) => value.replaceAll(/[^\d+]/g, '')"
/>
В параметрах можно задать маску ввода, указать какой именно символ в ней является плейсхолдером, и отформатировать получаемое значение собственной функцией.
Параметр state - это стандартная фишка BootstrapVue для полей ввода. При указании false будет ошибка, true - успех, а null ничего не делает.
В этом примере я просто проверяю количество введёных символов, если они вообще есть.

Заключение

На данный момент мы рассмотрели все доступные компоненты Vesp. Напоминаю, что они подключаются в проект добавлением @vesp/frontend в Config.modules файла nuxt.config.js.
По умолчанию компоненты включены только в приложении src/admin, а src/site идёт пустой.
На следующем занятии мы, вооружившись всеми этими значениями, начнём строить наш VespShop.