Как стать автором
Обновить

Комментарии 16

Ну вот я вижу, в примере формы используются компоненты fvephone, fvetext итд. Почему не сделать фабричный инпут и передавать пропс типа поля? Всё равно на компоненте 3-4 пропса уже висит, но не будет такого умножения одинаковых компонентов. Глобальные изменения так же проще сделать в одной фабрике, чем в череде компонентов.

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

Давайте наверно начнем с того что fvephone это обертка для vue-phone-mask-input. По этому не очень корректно их сравнивать. Корректнее наверно будет ответить на FveText и к примеру FveUrl (FveText + детали по валидации). Собственно приведу как выглядит реализация FveUrl:

import FveText from "./FveText";
export default {
  mixins: [ FveText ],
  methods: {
    validateFunction(str) {
      // насчет корректности регулярки не уверен.
      const urlRegex = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
      if( !urlRegex.test(str) ){ return 'Не верный формат ссылки'; }
      return 'SUCCESS'; // это не круто, но как есть 
    },
  }
};

поля email, password, time, login, number - строятся примерно таким же образом. Тут больше вопрос как это реализовано под капотом. И теперь вы можете спокойно использовать FveUrl где угодно без боязни что надо будет поменять валидацию. Отдельный момент это понимание какой тип ожидает v-model, дебаг + мне удобнее так).

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

Отдельно дополню ссылкой на гит для тех кто хочет взглянуть под капот. Develop ветку штормит, но она будет по интереснее. И пока что это наброски, качующие из проекта в проект...

Я конечно утрирую, но обычно 4-5 свойства присутствует всегда и это копипаститься по всем элементам формы.

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

Когда пришлось собирать более-мене серьёзную форму, ужаснулся от этого и сделал генератор форм "налету". Не являюсь экспертом в Vue и не уверен, что это производительное решение, но оно работает и помогает создавать формы быстрее.

Выносите формы в отдельный компонент

А так же в обязательном порядке диалоги (v-dialog) и карточки (v-card), если они содержат что-то длиннее трех строк.

А еще рекомендую вспоминать, что компоненты можно создавать локально в виде объектов со свойством template или функцией render, и это бывает удобно для маленьких элементов, применяемых многоразово, но только в рамках одного компонента.

 и зачастую копипаста из 4-5 пропсов расползается по всему проекту.

Да да, я про эту боль). По поводу форм генераторов у меня двоякое мнение (разработка с ними гораздо быстрее), но как только надо сделать что то за рамками - наступает боль (обычно такое бывает редко, но это очень не приятно).

И с этим успел столкнуться тоже) Просто сделал так, чтобы генератор принимал в слот кастомную разметку. Слоты Vue - это вообще потрясающее средство от головной боли))

Мне видится некоторое противоречие в пунктах "Бесполезное DTO" и "Формы для разных сущностей не должны пересекаться". В первом пункте возникает зацепление между фронтом и бэком как раз таки по имени атрибута (full_name). IMHO, в общем случае это всё-таки разные сущности (DTO фронта и DTO бэка). Первое - для ввода-вывода информации, второе - для хранения (или транспортировки). Во втором пункте сказано: "Обычно в начале, все формы однотипны, а может даже похожи и хочется использовать одну и туже форму." Я бы подобную логику применял бы и к DTO: "Обычно в начале все DTO однотипны, а может даже похожи...".

Чтоб всем было понятно по поводу DTO.
Бек отдал { first_name : "" , last_name : "" } , фронт это получил и говорит мне так не удобно и конвертирует в { fName : "" , lName : "" } (имеется в виду такой кейс). Я не против преобразования данных полей (было {create_at: "string"} стало {create_at: Date} ) - так стоит делать, но переименовывать по причине того, что так привычнее - это плохо. Рано или поздно вы пойдете к беку и спросите, а что там с полем fName (а бек это делал месяц назад и f_name у него ассоциируется совсем с другим).

Дальше вы хотите отдать { fName : "" , lName : "" } на сервер и преобразуете в { first_name : "" , last_name : "" }. Бек говорит ошибка в поле last_name . Мы идем и конвертируем поле с ошибкой last_name => lName.

Если есть причины, по которым вы готовы это делать - то ок.

Возможно не корректен заголовок про DTO и стоит назвать по мягче - минимизация конвертаций...

Часто бывает так, что на фронте принят camelCase, на бэке snake_case. В частности, в таких случаях используют преобразователи названий свойств. Не составит труда в таком кейсе юзать какие нибудь готовые преобразователи из lodash. Перед отправкой данных из запроса в компонент фронта и обратно. Кейс с удобным названием fName вместо firstName, который вместо first_name действительно лучше избегать вовсе ​

Вроде же vue не любит, когда из дочернего компонента редактируются свойства родительского, даже в консоли пишется, что так делать не хорошо. Поправьте, если я не прав

Конкретно тут об этом написано

Я не совсем понял, где вы это увидели, но могу предположить что это адресовано к этой строке

<ClientEditForm
 :formData="client"
/>

Отдается formData. работа внутри формы происходит с form. Изменений props нет, ошибок нет. Стоит заметить что в PageClientAdd.vue - formData вообще не передается.

Спасибо, выглядит не плохо, возможно кому то пригодиться. По общавшись с народом, я понял что мне не нужен форм генератор (в 99%). Лишь только в одном моем проекте есть реальная нужда в нем. Он самописный и заточен под проект, а количество полей на 1 форму 50+ (и эти поля взаимодействуют между собой, используют данные других полей для ajax, используют фильтрацию и тд). Готовым решением я б не обошелся... Но каждый решает сам, на сколько достаточно того или иного решения.

async save() {
    let formData = this.$refs.clientEditForm.formSubmitGetData();
}

вызов формы по рефу выглядит костыльно, достаточно перенести кнопку внутрь формы и слушать @submit

зачем в форме миксин - не понятно, идея "давайте напишем читаемый код" к концу статьи опять вернулась к "давайте добавим еще больше магии", композиция компонентов бы решила проблему намного лучше

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

Я не настаиваю использовать $refs (мне так удобно), можно и перенести, ток что делать если вам надо 2 кнопки к примеру или кнопка должна быть за пределами формы.

Холевар про миксины.... давайте не будем использовать ничего и напишем тонну кода) Вы берете тот же форм генератор или vuetify или другое решение и вообще не смотрите что там под капотом - знаете что это работает, примерно как и этого достаточно.

В целом есть жизненный пример "чистой архитектуры" - когда 1 простой метод api пишется часов 8 (без тестов). Нет магии, везде интерфейсы, все по феншую (Только есть одно но, метод нужен для теста и завтра может поменяться). И рядом с магией, но за пол часа. Тут каждый сам выбирает грань магии.

композиция компонентов бы решила проблему намного лучше

Я не против увидеть пример лучшего кода (если это не вкусовщина)...

По последнему пункту, уже давал пояснения в коментах выше "Чтоб всем было понятно по поводу DTO. ..."

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации