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:
- Are there other aspects I need to ‘bind’?
- 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.