Честно говоря, не думал, что только знакомство с системой затянется аж на 10 заметок. Мне-то оно всё давно привычно и понятно, а вот когда пытаешься внятно об этом рассказать...
В общем, сегодня мы заканчиваем вводную часть, и дальше будет настоящая работа по постройке магазина VespShop.
На нужно посмотреть, какие еще компоненты я написал для удобной работы на Vesp, и начнём с переключателя языка - vesp-change-locale
(по клику откроется GIFка)
Как я уже упоминал, мультиязычность админки работает при помощи модуля @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
в таком случае не имеет смысла, потому что переключать нам нечего.
Дальше у нас идут различные способы ввода, которые дополняют (а иногда и расширяют) имеющиеся в BootstrapVue.
Например, компонент выбора цвета:
При вызове нужно просто указать v-model
, в который будет записан выбранный цвет:
<vesp-input-color-picker v-model="record.color" />
При редактировании модели, если какой-то цвет уже указан, он будет сразу выставлен в компоненте.
Это компонент для поиска и выбора 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')) {
// ...
}
Этот компонент я использую постоянно, например при написании этой заметки для выбора раздела:
Хотя в BootstrapVue и есть свой собственный date-picker, меня он по ряду причин не устраивает. В первую очередь, он не умеет работать с диапазоном дат.
Поэтому, если вы указываете v-model массивом, даже пустым, то будет диапазон.
А если строкой - то обычная дата
Здесь внизу я вывел реальное значение v-model
, чтобы вы заметили, что там может быть массив или строка. Это значение и улетит на сервер, где вы сможете проверить тип присланных данных.
Выбор времени даты определяется наличием параметра type="datetime"
, по умолчанию там type="date"
<vesp-input-date-picker v-model="record.date" type="datetime" />
Это обычное поле ввода пароля, которое при нажатии на кнопочку показывает или скрывает набранное.
<vesp-input-password v-model="record.password" />
Этот очень интересный компонент предназначен для сохранения разных ссылок в одном массиве. Бывает очень полезно в разных проектах прицепить модели JSON колонку и хранить в ней ссылки на соц.сети.
Здесь я тоже внизу показываю реальное значение поля ввода.
<vesp-input-remote-links
v-model="record.links"
:services="{facebook: 'Facebook', instagram: 'Instagram', twitter: 'Twitter'}"
/>
Как видите, на Vue можно создавать очень интересные компоненты ввода для форм.
И последний компонент очень полезен, если нам нужно ограничить ввод текстовой маской. Например, для российских телефонов
Как видите, истиное значение 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.
Комментариев не много, вероятно всем все понятно. Прошу заранее простить - Slim4, Eloquent, VueJS, NuxtJs, Phinx это новые слова в моем лексиконе, поэтому спасибо за подробную детализацию уроков. Исходя из выше написаного, задам глупый вопрос - NuxtJs имеет более 200 модулей, означает ли это, что для их интеграции необходимо писать отдельный компонент Vesp?
Нет, конечно - это уже готовые модули, их нужно только подключить, как мы подключаем модуль авторизации или BootstrapVue.
Я же постарался написать свой модуль для Nuxt и сейчас рассказал какие в него входят компоненты.
Но дальше мы будем писать и свои уникальные компоненты для работы, это очень легко и удобно, когда разберёшься.
Ну как понятно :) Я иногда по раза 2-3 статью читаю. Честно говоря разработка на вот этих фреймворках vue, react и т.п. Мне кажется очень сложной, компоненты, контроллеры и прочее ерунда. Дочитав до этой статьи я все равно половины немного не понимаю особенно синтаксис, много чего нового. Но как говорится - через тернии к звездам!
Прекрасно тебя понимаю, я когда сам в этом разбирался - голова дымилась.
Но зато теперь прямо-таки получаю удовольствие от разработки!
Василий, добрый день!
Решил на сайте сделать форум "Заказать обратный звонок" в модульном окне с отправкой сообщения в Телеграмм.
Взял я у BootstrapVue модальное окно и добавил туда vesp-input-text-mask в итоге получаю ошибку: "Cannot read property 'phone' of undefined", пишу в script:
ошибка пропала, но поля input нет. Все тоже самое и с другими полями vesp-input я их не могу активировать.
Вот код :
Пересмотрел все варианты с применением vesp-input, те, что есть в VESP SHOP, так и не понял, почему у меня не работает.
В DOM дереве у меня:
Выходит, что движок не обработал. В nuxt.config.js у меня так:
Config.modules = ['bootstrap-vue/nuxt', '@nuxtjs/axios', '@nuxtjs/pwa', '@vesp/frontend']
Где я что-то не так сделал?
На сайте компоненты Vesp по умолчанию не подключены, нужно поменять вот эту настройку:
Понял, спасибо!