useOptionLabel
Panoramica
useOptionLabel è la utility che i componenti *Remote di @pzeta/vue-form usano internamente per estrarre la stringa visualizzata da un oggetto opzione. È esposto pubblicamente perché serve in componenti custom che ricevono opzioni eterogenee — ad esempio una tabella che mostra la "label utile" di un record lookup, o un componente di anteprima che riusa lo stesso pattern optionLabel / optionTemplate adottato dai wrapper remote.
Strategia di risoluzione, in ordine:
- Se
optionTemplateè definito → compila il template (es.${nome} - ${cognome}). - Altrimenti → legge
item[optionLabel]. - Fallback →
item[optionValue]. - Ultimo resort →
String(item).
API
import { useOptionLabel } from '@pzeta/vue-form'
export function useOptionLabel(
options?: UseOptionLabelOptions,
): UseOptionLabelReturn
Tipi
export interface UseOptionLabelOptions {
optionLabel?: MaybeRefOrGetter<string | undefined> // default: 'label'
optionTemplate?: MaybeRefOrGetter<string | undefined> // pattern ${campo}
optionValue?: MaybeRefOrGetter<string> // default: 'value' — fallback
}
export interface UseOptionLabelReturn {
compileTemplate: (template: string, item: Record<string, unknown>) => string
resolveOptionLabel: (item: Record<string, unknown>) => string
getNestedValue: (item: Record<string, unknown>, path: string) => unknown
}
MaybeRefOrGetter<...>: puoi passare valori statici, ref(...) o getter, e la risoluzione resta reattiva agli aggiornamenti.Esempi
Campo singolo
import { useOptionLabel } from '@pzeta/vue-form'
const { resolveOptionLabel } = useOptionLabel({ optionLabel: 'descrizione' })
const items = [
{ id: 1, descrizione: 'Opzione A' },
{ id: 2, descrizione: 'Opzione B' },
]
items.map(resolveOptionLabel)
// => ['Opzione A', 'Opzione B']
Template con interpolazione
const { resolveOptionLabel } = useOptionLabel({
optionTemplate: '${codice} - ${descrizione}',
})
resolveOptionLabel({ codice: 'IT', descrizione: 'Italia' })
// => 'IT - Italia'
Campi annidati (dot notation)
const { resolveOptionLabel, getNestedValue } = useOptionLabel({
optionTemplate: '${user.name} (${user.email})',
})
const item = {
id: 1,
user: { name: 'Mario', email: 'mario@example.com' },
}
resolveOptionLabel(item)
// => 'Mario (mario@example.com)'
getNestedValue(item, 'user.name')
// => 'Mario'
Valori reattivi
import { ref } from 'vue'
const labelField = ref('nome')
const { resolveOptionLabel } = useOptionLabel({ optionLabel: labelField })
resolveOptionLabel({ nome: 'Mario', cognome: 'Rossi' }) // => 'Mario'
labelField.value = 'cognome'
// resolveOptionLabel ora estrae 'cognome'
compileTemplate standalone
Il template engine è esposto e usabile fuori dal contesto opzione:
const { compileTemplate } = useOptionLabel()
const template = 'Benvenuto ${nome}, hai ${messaggi} nuovi messaggi'
compileTemplate(template, { nome: 'Mario', messaggi: 5 })
// => 'Benvenuto Mario, hai 5 nuovi messaggi'
Comportamento dei placeholder
| Scenario | Esempio | Output |
|---|---|---|
| Valore presente | compileTemplate('${nome}', { nome: 'Mario' }) | 'Mario' |
Valore null | compileTemplate('${nome}', { nome: null }) | '' (stringa vuota) |
| Campo mancante | compileTemplate('${eta}', { nome: 'Mario' }) | '${eta}' (mantiene il placeholder) |
| Path nested non risolto | compileTemplate('${u.x}', { u: {} }) | '${u.x}' |
La distinzione tra null (intenzionale → stringa vuota) e campo mancante (errore di chiavi → placeholder visibile) è voluta: aiuta a individuare nomi di campo errati nei template durante lo sviluppo.
Quando usarlo direttamente
Nella maggior parte dei casi non serve invocarlo: i wrapper *Remote (SelectRemote, ListboxRemote, TreeRemote, ecc.) accettano già le prop option-label / option-template e applicano internamente questo composable.
Usalo direttamente quando:
- Stai costruendo un componente custom che mostra liste di opzioni e vuoi la stessa semantica di
optionLabel/optionTemplatedei wrapper. - Devi renderizzare la label di un valore selezionato fuori dal componente (es. in un riepilogo, una toolbar, una cella di tabella).
- Ti serve
compileTemplatecome template engine leggero per stringhe basate su oggetti, senza dipendere da librerie esterne.
Vedi anche
- SelectRemote — prop
option-template - ListboxRemote — prop
option-template - useRemoteSetup — pattern di setup unificato per i wrapper
*Remote