A Better Way To Organize Components In Vue

Поделиться
HTML-код
  • Опубликовано: 5 июн 2024
  • The base component pattern is an amazing way to organizer your components in your app. In this video I'll explore how this component pattern works, and what to look out for! We'll look at refactoring components, updating components, and how to use presentational components. With Vue and React.
    👉 Check out my last video on Nuxt UI
    • This Tailwind UI Compo...
    👉Sign up for my mailing list and get neat stuff!
    bit.ly/3Umk7sW
    👉 Need some help with a project, level up your skills, React, Next, Vue, or Nuxt? Check out my 1-on-1 mentoring!
    mentors.to/erik
    Links:
    / 1742486867327516928
    x.com/erikch
    0:00 Base component pattern
    0:53 Refactor to component
    01:54 Icon refactor
    02:27 Slot refactor
    03:27 Seperator slot refactor
    06:22 Base component refactor
    07:37 Brief Button abstraction
    08:02 Disabled button abstraction
    09:00 Why you shouuld use this?

Комментарии • 55

  • @ProgramWithErik
    @ProgramWithErik  4 месяца назад +3

    What patterns do you use?

    • @user-sj7tf2yv3m
      @user-sj7tf2yv3m 4 месяца назад

      FSD methodology

    • @hejloldetermig3850
      @hejloldetermig3850 4 месяца назад +5

      This is inheritance over composition, which goes against the design principle "composition over inheritance". What happens when you want a `` and you also want it to be disabled? Would you create a ``? What happens when your button has 5 props? Would you create 3125 different button components to support all combinations? I think this pattern is OK for some specific use cases, but this example kind of misses the mark. In our application, we have a button, which is used to reset filters in different places on a page. It is displayed with the same icon, the same text and the same color on 50+ pages - here the pattern makes sense. We create a `` component. I feel like such a scenario is a better use case for this pattern, but for the actual UI component itself, I want it to be as flexible as possible through composition of different props and slots.

    • @jondoe79
      @jondoe79 4 месяца назад

      CVA + Props + Attributes
      And a clean attribute which strips everything except exposed methods yet the user can set the slot.
      Never had an issue so far, 1 year and counting

    • @goosydev
      @goosydev 4 месяца назад

      @@hejloldetermig3850 Exactly as you said, this feels much more complicated when it comes to usage so I would be careful with components that have alot of variations and are used alot. I think this pattern would only really be useful with very complex components that have 2-3 variations that differ from each other a lot.

    • @marcusunivers
      @marcusunivers 4 месяца назад

      I guess the next logical thing will be to combine all 3 buttons into one but with the 3 buttons as subcomponents inside the button and a prop that switches between the components.
      Something like Test Button and then inside the button the component becomes visible with a if statement. The functionality what the button does is inside the sub button component. This is how I would do it.

  • @wwizer
    @wwizer 4 месяца назад +24

    we have this issue at work. We start with a basic component and it eventually turns into a swiss army knife

  • @user-hi4rx1vj9n
    @user-hi4rx1vj9n 4 месяца назад +4

    This is definitely an improvement from the initial component. I like to have my cake and eat it too by making the normal use case be as simple as possible while allowing full customizability when needed. In my Vue components, this generally takes the form of a prop, with a sensible default value, which is rendered as the default slot content. This way, I can either pass nothing and use the default value, pass a prop to override, or take full advantage of the slot. You can take this further and apply similar patterns to make really robust components with simple, intuitive interfaces. My personal favorite model for great component design is the FormKit library

  • @mathiasokafor7318
    @mathiasokafor7318 4 месяца назад +5

    thanks alot for all you do for the vue community

  • @epiphanyatnight8732
    @epiphanyatnight8732 4 месяца назад

    Love this video and would be great to see more!

  • @Kingside88
    @Kingside88 4 месяца назад +2

    Thank you for this video. I like this pattern. However, I would prefer the naming to ButtonBase, ButtonBrief, ButtonDisabled. 1. The IDE would show them next to each other and 2. while programming my first thought is always I need a button and second which button do I need.

  • @SaschaFuchs
    @SaschaFuchs 4 месяца назад

    I do it by creating a Button Element that is able to display states like disabled, plus various Color Styles. Then there is the basic style such as Border, Rounded Edges. This is stored in a style prop as the default. The font size as well as the spacing within is also stored as a layout prop.
    The labeling as well as optional icons are passed on to the button via a slot. Icon left, right or in the middle without wording.
    If you are building a large number of buttons that can be grouped visually, we build a superordinate component. There we store the style as a map, literal or JSON and switch the respective variant via prop.

  • @todpale
    @todpale 4 месяца назад +3

    The SRP on the maximal level. But it makes things more complicated. This approach works pretty well with functions or even classes. But components should have consistency and work almost like those in an abstract Vuetify or any other UI library. There might be tons of scenarios for tables or modals, popups, etc.

  • @mahdirashidi5104
    @mahdirashidi5104 3 месяца назад +1

    Hi erik , good point that you mention but i get confuse , when you create a disable button , it is just for breif button not base button and if we have a various of buttons type, we have to create their disabled button??

  • @chiquito.y.panzon
    @chiquito.y.panzon Месяц назад

    I like how shadcn solves it, using CVA. A file to define the variants and then a slot. That gives a lot of versatility and keeps things clean. What variants does it allow? Just look at the file.

  • @yoanestradablanco1608
    @yoanestradablanco1608 2 месяца назад

    amazing video!!!

  • @erezbenkimon3899
    @erezbenkimon3899 8 дней назад

    Hi Eric , I think this is not a good pattern for this use case
    because a single relatively simple AppBtn cmp can take all of the needed
    use cases very easily including : loading , disable , color , size & icons.
    It's better to create a single button with not much of a code.
    the icons are just props because I'm holding all of them as and the svg that contain all of them is in the app root.
    each Icon is with currentColor value and there is really not much code to get all of those use cases .
    this is for a button!
    for other components which are more complex I think the pattern that u suggested will work better.

  • @Shuyinz
    @Shuyinz 4 месяца назад

    Kinda Reminds me a bit of Liskov Subtituiton Principle which is part of the SOLID principle, but not 100% since the button doesn't have the same emit name consistently with 3 buttons. I would say this pattern aren't necessarily wrong. It could feel redundant for sure 🙂

  • @rayanazzam7225
    @rayanazzam7225 4 месяца назад +1

    I really like those kinds of abstractions, and i am using them in my daily coding, but when it comes to performance, i have a case where i have to render list of more than 10000 items it comes to an issue when using multiple nested components inside this list.
    What do you think about this case

    • @goosydev
      @goosydev 4 месяца назад

      sounds like a case of pagination

    • @rayanazzam7225
      @rayanazzam7225 4 месяца назад

      @@goosydev the usecase prevents me from using pagination

  • @user-tb4nn8jz8w
    @user-tb4nn8jz8w 4 месяца назад +1

    Hi, nice idea. Maybe the example with disabled btn is not suitable.
    I usually want the disabled button in dynamic.
    If I will do ButtonDisabled I will have to add "if statements" for the disabled case.

    • @ProgramWithErik
      @ProgramWithErik  4 месяца назад

      Yeah it’s a little contrived but it works

  • @russpalermo
    @russpalermo 4 месяца назад

    ok - so where did you tore the abstracted button variants? In nuxt particularly I am having similar issue with folders and subfolders and increasingly longer....and longer component names.

    • @russpalermo
      @russpalermo 4 месяца назад +2

      ah I see your head was covering - you put BriefButton in root of components. I can see that getting very disorganized and good-names-dependent as yor projects and variants grow. For smaller projects I would recommend putting BreifButton in the Base folder where it would assume the name BaseBriefButton when using. Larger projects where you have several variants of several components...stilll looking for a good pattern.

    • @ProgramWithErik
      @ProgramWithErik  4 месяца назад

      That is a good point! I was thinking about putting it in the Base folder, but then I wanted only the fundamental components (BaseButton) in the base folder. Good point in larger projects, I'd probably have to rethink the directory structure.

  • @lidtatech
    @lidtatech 4 месяца назад

    I would argue that is better still to use an object prop and parse the icon, divider,text ,color and state to the button component. That way I won't scratch my head finding the exact variance. for every use case.

  • @pepinogdev
    @pepinogdev 4 месяца назад +4

    i prefer use props for disabled states

  • @Norfeldt
    @Norfeldt 4 месяца назад

    This a very common issue and I'm still looking for the golden solution for this. In react you can collect all of your logic and keep it separate (like your video suggest) by named exports. I really like that but is that even possible in Vue?

    • @ProgramWithErik
      @ProgramWithErik  4 месяца назад

      Not really for named exports

    • @Norfeldt
      @Norfeldt 4 месяца назад

      @@ProgramWithErik so no option to have multiple components in the same file?

  • @SXsoft99
    @SXsoft99 4 месяца назад

    in a way i miss the old days when you used 2-4 bootstrap classes(also have utility classes) not 20 and we didn't have to define a component
    most of the time you define utility small html components because of styling not because of functionality. For the functionality ones or you want to break your component into partials that's a different story

  • @aleksandrstaetskiy5687
    @aleksandrstaetskiy5687 4 месяца назад +3

    It would be MUCH easier and better organized to keep all logic inside of the component. ‹BaseButton variant="primary" outline disabled /›. And inside of the component you keep computed property which applies all needed classes and does all logic. This approach is mostly used in UI libraries.

    • @ProgramWithErik
      @ProgramWithErik  4 месяца назад

      That is one way. I like this pattern though

    • @duncandejong
      @duncandejong 4 месяца назад

      I agree, inthis button case certainly… else everyone will do a different approach. With a bit of documentation it is not hard. With the other way maybe harder.
      With a form, and form elements, yes…

  • @peteremad5228
    @peteremad5228 4 месяца назад +2

    is it only me ,this way to write code in your app not good nor flexible ...?? i think if you need to create a base component it should handle all things and have flexible api ..at least for me i should able to change ( icon ,label ,loading,disabled,custom classes)
    and going further with some extra functionlity like ( varaint,colort, as) and to be more flexible icons(trailing and leading ) and labels can be customized with specifc slots if needed

    • @sivuyilemagutywa5286
      @sivuyilemagutywa5286 4 месяца назад

      I also feel like a base button should do most things a button is expected to do, click, loading, disabled, custom classes ,etc and then variants can be ButtinIcon

  • @hyperprotagonist
    @hyperprotagonist 4 месяца назад +1

    Slightly confused why DisabledButton is a component. Perhaps it was a bad example.

  • @dvdrtrgn
    @dvdrtrgn 4 месяца назад +1

    Looks awkward with the template at the top. I'm now so used to having the setup first.

  • @user-sj7tf2yv3m
    @user-sj7tf2yv3m 4 месяца назад +1

    Он предлагает использовать v-if DisabledButton, BaseButton.
    А не пропсы.
    Пример очень не удачный

    • @aceracer5556
      @aceracer5556 4 месяца назад

      Может и не удачный, но проблему классификации кнопок решает

    • @ProgramWithErik
      @ProgramWithErik  4 месяца назад +1

      Hello! I think the translation says here, that I'm using v-if. I'm not using a v-if, I'm showing a way to refactor a button component to be more re-usuable using the base pattern.
      Привет! Кажется, здесь в переводе сказано, что я использую v-if. Я не использую v-if, я показываю способ рефакторинга компонента кнопки, чтобы его можно было более повторно использовать, используя базовый шаблон.

    • @PaulloClara
      @PaulloClara 4 месяца назад +1

      ​I believe his intention was to explain that, in the presented example, there are two types of buttons: the base button and the disabled button. To manage these states, it would be necessary to use a `v-if` directive instead of just passing a property to the base component.

    • @user-sj7tf2yv3m
      @user-sj7tf2yv3m 4 месяца назад

      @@ProgramWithErik I have no questions for you. I was talking about Michael Thyssen. Some of his examples in X sometimes seem strange

  • @k-yo
    @k-yo 4 месяца назад +1

    I really thought this was the norm.

  • @DarlenCodename
    @DarlenCodename 4 месяца назад

    I don't think this is good. It bloats the code too much using "v-if" to render two different components, for example, if you want a disabled button, instead of just passing a prop, you'll have to use "v-if" or "Component" to dynamically render the component.
    I think a good approach would be to create a BaseButton, then create other ones, but all in one component, and you change it inside the component accordingly to the prop changes.
    If you think a component is getting too big, always decouple it in more small components.

    • @lavanyamishra5049
      @lavanyamishra5049 19 дней назад

      Using dynamic components is better than using v-if for your use case. See the dynamic components part in the documentation.

  • @reiahead
    @reiahead 2 месяца назад +1

    Don't really see this pattern useful.
    Creating component for each state of button is not good.
    We prefer to add multiple props for single button component, that can change its color, size, view and so on.

  • @xayeso
    @xayeso 3 месяца назад +1

    This is a bad approach. Just stick to the props, and if internally you need more space, make internal components that don't get exposed to the developers.

    • @ProgramWithErik
      @ProgramWithErik  3 месяца назад

      Hard disagree. This is a great way of handling components