Задать вопрос

Какой вариант компонента объективно лучше?

Доброго вечера.
Сделал компонент аккордеона с использованием именованных слотов (не говорите, что есть лучше, просто на моей текущей галере принципиально пилят свои велосипеды). На мой взгляд, получилось очень удобно и красиво. Код реализации опущу (в рамках вопроса не суть важно), использование выглядит так:
<v-accordion
  :items="addresses"
>
  <template v-slot:item="{ item }">Item {{ item.id }}</template>

  <template v-slot:content>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit
  </template>
</v-accordion>

Все просто и прозрачно. Передаем массив элементов, имеем возможность установить произвольный элемент и его контент. Однако тимлид принял резко в штыки и предложил свой вариант.
<v-accordion>
  <v-accordion-item v-for="item in items">
    <div v-slot="title">
      {{ item.title }}
    </div>
    
    <div>{{ item.content }}</div>
  </v-accordion-item>
</v-accordion>

При этом плюсов в его решении не вижу в упор, а минусов масса:
- лишний импорт (v-accordion-item в каждом месте, где аккордион будет юзаться, и никак не обойти), в моем варианте v-accordion-item инкапсулирован в слот
- вытекает из п.1, лишние строчки в components компонента (у нас компоненты не регаются глобально)
- постоянно придется писать v-for, и в целом задавать тело аккордиона явно - разве не излишне?
- наверняка возникнет проблема стилизации контента. Поскольку там внутри дефолтного слота стоит эта кочерга "div item.content div", это значит, что нам придется либо обращаться к этому диву через nth-child (будем зависеть от структуры DOM, нехорошо), либо лепить каждый раз нужный класс (повторение кода, нехорошо), либо заводить v-accordion-content и импортировать еще и третий компонент. Три компонента, Карл, вместо одного! Разве это хорошо?

В общем, хочется понять, чем решение 2 объективно лучше решения 1, и лучше ли? Потому что пока, походу, подтверждается теория о том, что тимлид !== хороший программист. Аргументы самого тимлида звучат так: "ну можно же так сделать, и работает, правда? зачем чего-то городить?" и "я всегда так делал, мы так привыкли".

Заранее спасибо.
  • Вопрос задан
  • 513 просмотров
Подписаться 4 Простой 1 комментарий
Пригласить эксперта
Ответы на вопрос 3
profesor08
@profesor08
Лично я в упор не вижу аккордеона. В примере тимлида он есть, в твоем нет. Что если у одного слайда одна разметка, а у другого другая?

В примере тимлида есть компонент аккордеона и компонент для слайдов, слайды выводятся в цикле. Как это работает меня не волнует, моя задача лишь вывести разметку для слайдов. В итоге получится чистый и понятный код.

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

Твой аккордеон должен отвечать только за функционал аккордеона, а не стилизацию всего и вся.
Ответ написан
@UnformedVoid
Разработчик ПО
Аргументы вашего тимлида непрофессиональны и не подкреплены рациональной аргументацией. Ваш подход поддерживает компонентную структуру приложения. В то время как то, что предложил ваш тимлид обязывает слишком много помнить о том, как нужно писать код, увеличивает количество повторяющегося кода, в целом делает его более императивным, что плохо совместимо с идеями стоящими за Vue. В общем советую вам настоять на своём и описать почему ваш подход лучше. «я всегда так делал, мы так привыкли» — не аргумент. Ваш тимлид явно не видит абстрактную сторону и плохо понимает работу фреймворка, а может и как вы говорите, не очень-то и профессионален.

UPD.
Я исследовал комментарии тут, подумал и пришёл к дополнительным выводам, которые опишу тут:

1) Ваш подход имеет минус — он избыточен, так как содержит два слота, что делает логику неясной. Дело в том, что у вас не понятно к чему относится второй слот content. Читающий может подумать, что это контент, который выводит сам аккордеон — один раз, а не для каждого элемента. Мне такая логика особо знакома из фрейморвка WPF. Там всё так и работает, но судя по вашему примеру этот слот относится к слоту item, то есть используется не для аккордеона, а для его элементов, что неправильно, так как нарушает инкапсуляцию. Это минус вашего подхода, но он легко исправляется.

2) Минусы подхода вашего тимлида остаются теми же — многословность, императивность. Он нарушает принцип DRY.

Так вот, требуется подход, который не будет нарушать лучших практик — гибридный подход. Для начала нужно разделить понятия аккордеона и элемента аккордеона — теперь это два слабосвязанных компонента. У нас должна быть возможность менять компонент элемент аккордеона на новый, при этом не трогая сам аккордеон. Это решается очень просто. Мы просто берём ваш подход и оставляем в нём только один слот item. Этот слот будет позволять пользователю аккордеона создавать разметку по своему усмотрению. Слот content убираем за ненадобностью. В дальнейшем мы можем аккордеону добавлять ещё слоты и они будут менять его структуру, например добавлять ему заголовок или что-то ещё, но при этом никак не трогая то, как отображается внутренность его элементов (помним об инкапсуляции)! Этим должен заниматься слот items. Теперь, у нас есть возможность создать разметку его элементов. Мы можем это сделать с помощью простых HTML тегов, если у нас аккордеон в одном месте и забыть о дальнейшем (помним о принципах YAGNI и KISS). Если же у нас аккордеон в нескольких местах, причём, разметка его элементов каждый раз одинаковая, то стоит задуматься о компоненте элемента аккордеона. Его структура не важна, так что ударяться в детали я не буду. Далее мы просто создаём ещё один компонент, который будет оборачивать наш аккордеон и подставлять в его слот item соответствующий компонент элемента аккордеона (и, возможно, добавлять ещё какую-то функциональность, разметку) — типа создаём подкласс. Таким образом мы не пишем v-for каждый раз, то есть не повторяемся (помним о DRY), и имеем полный контроль над тем, что происходит в приложении. Если понадобится что-то поменять у всех, мы просто зайдём и поменяем это в нашем последнем компоненте-обёртке. Если нужно будет реализовать что-то новое, то мы создадим новую обёртку или вовсе используем наш базовый аккордеон на нужной странице (помним о YAGNI). Некоторым может показаться это избыточным. Так и есть, этим надо пользоваться с умом. Если у вас один аккордеон на всё приложение, то и думать о переиспользовании — бессмысленно. Если же компонент требуется в нескольких местах, то приведённый мною подход прекрасно подойдёт, так как основан на лучших практиках взятых из ООП.

P.S. С подходом-обёрткой мы можем даже не писать отдельные компоненты для элементов аккордеона, так как, в принципе, нам не нужны элементы аккордеона отдельно от него. Достаточно лишь создать аккордеон-потомок с нужной разметкой в слоте item.
Ответ написан
zoonman
@zoonman
⋆⋆⋆⋆⋆
А разве нельзя написать это по-человечески?
Я Vue не знаю, но из предложенных вариантов представляю себе это как-то так

<accordion :items="items">
  <!-- add your content layout,
  in our case this is div  -->
  <div>{{item.content}}</div>
</accordion>


Я понятия не имею, но с моей точки зрения абсолютно логично использовать некоторого рода публичный интерфейс, строго декларирущий структуру items.
Главный дочерний элемент становится шаблоном для отрисовки содержимого внутри аккордиона.

Шаблон тимлида мне абсолютно понятен без каких-либо знаний Vue. Ваш шаблон напоминает какую-то вуду магию. Надо лезть в документацию и разбираться, что к чему.

Могу предложить альтернативный вариант с прямым декларированием структурных элементов.

<v-accordion :items="items">
  <v-title>{{title}}</v-title>
  <v-content>{{content}}</v-content>
</v-accordion>


Я не знаю, можно ли обойтись без всего того мусора, но его наличие меня раздражает.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы