VueJS wrapping UI toolkits

There are a number of UI toolkits in the JS (and specifically VueJS) space. BootstrapVue, Vuetify, VueStrap, Ionic, Quasar, ElementUI and more. I wrote a post some time ago (which may get recovered at some point!) about some of these, and indicated I’d be diving in to one or more at some point, and… I have.

Through a long and winding set of events, I’ve found myself working with Quasar/Vue3 over the last 7 months. This is a relatively big change from BootstrapVue which I’d used on multiple projects since pre-covid times.

As a side note, I’m generally a fan of these, because there’s typically a lot of work that’s already gone in to providing defaults – default settings, theme/styling, documentation, accessibility concerns, testing, and many other things I may not have thought about up front. I’ve worked with folks that are very against this approach, and prefer to do everything ‘by hand’, but I’ve also found a lot tends to be missed, especially with respect to accessibility, documentation and testing, and often for little upside (yes, you can control the UI 100% to your liking but… I also happen to like the defaults and options available in the bootstrap world, for example).

Moving in to Quasar has been … interesting. I’m not a fan of material design styling, which is their default design language. I think changing *from* it to something else may be too big a lift for the project, and they actually may not care to, although there do seem to be some rumblings from folks in the forums about supporting alternate design languages. We’ll see where that goes.

What I’ve recently started doing is wrapping the framework components in my own super-components. This allows for some ability to do more uniform customizations of, say, input tags.

<q-input
  dense
  stacked-label
  clearable
  v-model="user.email"
/>


This use of Quasar’s q-input component is common, useful but also gets verbose. You may want the same set of attributes on dozens of inputs on a screen. Wrapping in a common custom input component can save a lot of repetition.

// src/components/My/Input.vue
<template>
  <div class="my-input">
    <q-input 
      dense
      stacked-label
      dark
      clearable
      v-bind="$attrs"
    >
      <slot></slot>
    </q-input>
  </div>
</template>

<script>
export default {
  name: "MyInput",
};
</script>

Using this in a project…

// src/components/UserInfo.vue

<template>
  <q-page>
    <q-row>
      <my-input
        autofocus
        v-model="user.name"
        label="Name"
      />
    </q-row>
    <q-row>
      <my-input
        v-model="user.email"
        label="Email"
      />
    </q-row>
    <q-row>
      <my-input
        v-model="phone"
        label="Phone"
      />
    </q-row>
  </div>
</template>

<script>
import MyInput from "src/components/My/Input.vue";
export default {
   components: [MyInput], 
   ....
   ....
};
</script>

Each input now gets ‘dense’, ‘stacked-label’ and ‘clearable’ attributes set to on without the repetition. (FWIW, this is typed from memory – hopefully no major errors in there!).

There may potentially be some benefit if the desire to switch to a new UI toolkit arises, but I suspect that’s probably way too hard of a lift (but I’ve only just considered this a potential benefit this morning!)

I’ve seen this done in other places in the past – this is not claiming the approach is new by any means. I’ve just recently started to incorporate this approach to recent projects. I’ll keep you posted if this proves troublesome later on down the road.

Similar Posts

  • PHP Quality Tools

    Curious about checking out the quality of your PHP project, but don’t know where to start? https://github.com/jakzal/phpqa is a project providing docker images of various tools to help measure aspects of your PHP code. will run the phploc tool on your current folder But… you can alias the tool, then simply run $ phpqa <toolname>…

  • Bad I9 PDF form

    Have been needing to programmatically fill out an I9 PDF, retrieved from gov site. Should be fairly straightforward, right? Well… the field names are… a mess. Field names like topmostSubform[0].Page1[0].U\.S\._Social_Security_Number__Last_4_numbers_[0]topmostSubform[0].Page1[0].expiration_date__if_applicable__mm_dd_yyyy[0] topmostSubform[0].Page2[0].Employers_Business_or_Organization_Address_Street_Number_and_Name[0] and so on make it pretty… not straightforward to create a usable key/value combination to search and replace. But… today, I noticed it got…

  • Laravel down migrations

    I get an email newsletter from Martin Joo every week or so. The newsletters generally have some useful tips around the Laravel framework or sometimes just general development tips. I’ve learned a couple of neat tricks here and there, and will continue to receive. This morning I received an email with a Laravel ‘tip’ regarding…

Leave a Reply

Your email address will not be published. Required fields are marked *