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>