How to create specialised/sub-classed components ?



  • Hi. Seeking advice …

    I would like to create specialised/sub-classed versions of components (think object-oriented inheritance).

    As a concrete example, consider a specialised version of q-dialog that is always maximised on small devices (other use cases may need to add functionality).

    I’ve seen a Vuejs ‘trick’ to bind aspects between parent an child and declaring a custom component (say MaxDialog) with the following gives me what I want:

    <template>
    <q-dialog v-bind="$attrs" v-on="$listeners" :maximized="$root.$q.screen.lt.sm">
    </template>

    My questions:

    1. Are there other aspects I need to ‘bind’?
    2. Is the approach defensible/advisable?

    I’m aware Vuejs has ‘extends’, ‘mixins’ and ‘slots’ but I don’t understand them enough to decide whether they provide a preferred solution.



  • Ok it seems that object-oriented inheritance is a pinch-point in Vuejs with no widely-accepted solution. Achievable within scripts using ‘extends’ but within templates requires switching to a language that supports inheritance (e.g. pug, which implies templates in external file) or use of slots. There are also ‘transparent’ components (https://zendev.com/2018/05/31/transparent-wrapper-components-in-vue.html) but ultimately it’s a Vuejs debate not Quasar.



  • @rab well, specialization is achievable rather by composition than inheritance. Of course, it could vary between developers, solutions etc. What I propose is just make anything what works in your specific project in this time, let it do what you need, and in future, when you will find a better solution then you can change your code to perfection. Now is better then never 🙂

    Yes, those specialized components are OK - for example - in terms of version 0.17 Quasar it is something I had somewhere:

    <template>
      <q-field>
        <q-input v-bind="$attrs" ref="ifMyField" :float-label="label" :value="value" @input="updateValue" :after="getAfter">
          <q-autocomplete ref="acMyField" :max-results="123" :min-characters="minSearchCharacters" :static-data="staticSearch" @search="searchMyField" v-if="issearchable" />
        </q-input>
      </q-field>
    </template>
    

    As you can see, it is a q-field wrapper with emedded autocomplete. Very useful at times and it worked OK.

    Ach, about dynamic composition - maybe this would be helpful also:
    https://vuejs.org/v2/guide/components.html#Dynamic-Components



  • Yep agree about just getting it done rather than seeking perfection. The generic proposals I’ve seen are non-obvious and I will run with what I have. Thanks for the example.



  • @rab also pass the slots

    <template
          v-for="(_, slot) of $scopedSlots"
          v-slot:[slot]="scope"
        >
          <slot
            :name="slot"
            v-bind="scope"
          />
        </template>
    


  • @rab can also use Vue.extend if you want to add some functionality. using your case maximized="$q.screen.lt.sm. https://codepen.io/metalsadman/pen/MWYXGzO



  • Nice. This is more like what I expected to find. Thanks.


Log in to reply