I recently ran into the same issue, of wanting to impose consistent style options with multiple Quasar component types throughout my app. For example I might want q-input components to default to dense and outlined, and q-btn components to default to dense and flat. Since Quasar components use props for configuring many aspects of components, you can’t just use CSS for this.
I tried the approach mentioned above of wrapping components, but found this to be problematic. To use QInput
as an example, what I really want is a component with the same API as QInput
, including the same props, events, slots and methods, but just with different defaults for some of the props.
To achieve this by wrapping I would have to make my wrapper forward all of these things to the wrapped component. For props this is simple using v-bind="$attrs"
like this:
// MyInput
<template>
<q-input v-bind="$attrs" .../>
...
However I’m not aware of an equivalently trivial method for forwarding all events, slots and methods to the wrapped component. This means when I write a wrapper, I have to choose between either doing a non-trivial amount of work, or not replicating the API of the wrapped component. For simple components like QInput
this might still not be a big deal, but it adds up when I start wanting to do the same thing for multiple components, and especially for complex components like QTable
.
The approach I came up with instead was to create a defaults.js file with an object for each component I want to customize, like this:
// defaults.js
// default prop values for QInput
export const inputDefaults = {
outlined: true,
dense: true
}
// default prop values for QBtn
export const btnDefaults = {
flat: true
}
// .. Etc for any other components you want to customize
To make it easy to access these defaults I make a boot file like this:
import * as defaults from 'src/defaults'
export default async ({ Vue }) => {
Vue.prototype.$defs = defaults
}
Now in templates I can make a component use the defaults simply by adding a v-bind="$defs.componentTypeDefaults"
attribute, like:
<template>
<div>
<q-input
v-bind="$defs.inputDefaults"
label="The Label"
... other props
/>
<q-btn
v-bind="$defs.btnDefaults"
... other props
/>
</div>
</template>
It’s not quite as convenient to use as custom wrapper components, but on the other hand it’s much easier to customize a large number of components, and I’m not losing access to any of the functionality of the Quasar components. I still have access to all the events, slots and methods of the Quasar components without having to explicitly forward them in my wrappers.
What I wish for is that Quasar would add this functionality so that component prop defaults could be configured in quasar.conf.js. I’d like for there to be a componentDefaults
section in quasar.conf.js that allows configuring component defaults just like I’m doing in defaults.js.