Developer guidelines
In this document is described some guidelines and best practices for the front-end.
Field
Form field
Every form Field.vue be wrapped inside the <FieldWrapper> component.
If this is ignored, you will have to manage everything yourself (label, validation, tooltip etc.).
It is important that your field respect some defaults. For example, let's take a look at TextField:
<InputText
v-model="localValue"
@input="$emit('update:modelValue', localValue)"
v-bind="inputProps"
v-focus="config.autofocus"
/>
Important here is the inputProps, which looks something like this:
const inputProps = computed(() => {
return {
id: `field_${props.config.name}`, // Makes clicking on the label focus the input
invalid: fieldErrors.fieldHasValidationMessages.value, // Adds a red border
class: {
'w-full': true // Makes it full width
},
...props.config.attributes // Adds any other attributes
}
})
General elements
Route links
In front-end v1 (Quasar) you had the option to pass on a :to property to q-btn.
This is not possible in the Button component of PrimeVue. Instead, you should do it like this:
<RouterLink class="router-link" :to="{ name: 'login' }">
{{ $t('auth.Back to login') }}
</RouterLink>
You could optionally put a <Button> inside the <RouterLink> if you want to style it like a button.
Tabs
Keep in mind that tabs are not "lazy", by default. Meaning, the Vue component will be mounted even when the tab view
is not active/clicked on. You can put the lazy prop on it to avoid this.
When using PrimeVue TabView, keep in mind that there is horizontal padding for the content.
This horizontal padding is unnecessary for mobile (small screens) in most cases. You can remove it:
<TabView :pt="{ panelContainer: { class: $q.ui.screen.lt.md ? 'px-0' : '' } }">
Theming
Widths, heights, margins and paddings
The ui store exposes multiple properties for widths, heights, margins, paddings and states like sideBarDesktopOpen etc:
state: () => ({
darkMode: false,
themeName: 'lara-light',
scale: 14,
windowWidth: 800,
windowHeight: 600,
sideBarWidth: 17,
topBarHeight: 4,
menuTabsHeight: 3.5,
fieldsGap: 4,
fieldLabelGap: 2,
sideBarDesktopOpen: true,
sideBarMobileOpen: false
})
It is good practise to apply consistency throughout the application. For example, when you display a set of fields below each other:
<div class="flex flex-col gap-4">
<TextField />
<TextField />
<TextField />
</div>
It is better to use the ui store for the gap:
<div :class="`flex flex-col gap-${$q.ui.fieldsGap}`">
<TextField />
<TextField />
<TextField />
</div>