pt —— fusión de atributos de passthrough
Un componente tiene varios elementos en su interior (el <button> del botón y el <span> que contiene; el <input> del campo de entrada y el icono delantero <i>): ¿cómo hacer cuando alguien quiere ajustar uno de ellos desde fuera? La respuesta de lh-ui es el paquete de atributos PT (PassThrough): el componente expone una prop pt que transmite class / style / attrs por separado, según el nombre del elemento interior. mergePt se encarga de fusionarlo con los nombres de clase propios del componente.
Cuándo usarlo
Sección titulada «Cuándo usarlo»- En el interior de la biblioteca de componentes: cada elemento interior llama a
mergePt(props.pt?.icon, 'lh-button__icon')y obtiene el class / style / attrs que le toca. - Desde el lado de quien usa el componente, para un ajuste fino de un elemento interior concreto a través de la prop
pt, sin necesidad de perforar con:deep().
Cuándo no usarlo: personalización a nivel de tema (usar themeVars); añadir un simple nombre de clase (usar la prop class).
Importación
Sección titulada «Importación»import { mergePt, type LhPtAttrs } from '@lh-ui/share/core/shared/pt'Tipos y funciones
Sección titulada «Tipos y funciones»export interface LhPtAttrs { class?: string | string[] | Record<string, boolean> style?: Record<string, string> attrs?: Record<string, any>}| Función | Firma | Acción |
|---|---|---|
mergePt |
(pt: LhPtAttrs | undefined, baseClass: string) => { class: string[]; style: Record<string, string>; attrs: Record<string, any> } |
Fusiona los atributos PT con el nombre de clase base |
Reglas de la fusión
Sección titulada «Reglas de la fusión»baseClass va siempre el primero del arreglo y el class del usuario detrás:
mergePt({ class: 'my-icon' }, 'lh-button__icon')// { class: ['lh-button__icon', 'my-icon'], style: {}, attrs: {} }
mergePt({ class: ['a', 'b'] }, 'lh-button__icon')// class: ['lh-button__icon', 'a', 'b']
mergePt({ class: { active: true, disabled: false } }, 'lh-button__icon')// class: ['lh-button__icon', 'active'] —— del objeto solo se toman las claves con valor verdadero
mergePt({ class: 'a b ' }, 'lh-button__icon')// class: ['lh-button__icon', 'a', 'b'] —— la cadena se corta por espacios y se filtran las vacíasPor qué baseClass va primero: la especificidad del nombre de clase base BEM no debe quedar por debajo de la del class del usuario (siendo ambos nombres simples, el que se escribe después prevalece sobre el primero). El modificador --primary del componente debe poder seguir cubriendo el my-icon del usuario.
style / attrs
Sección titulada «style / attrs»mergePt(undefined, 'lh-button__icon')// { class: ['lh-button__icon'], style: {}, attrs: {} } —— con pt vacío, todo vacío
mergePt({ style: { color: 'red' }, attrs: { 'data-x': '1' } }, 'lh-button__icon')// { class: ['lh-button__icon'], style: { color: 'red' }, attrs: { 'data-x': '1' } }Nota: style / attrs pasan por referencia, sin copia. La capa UI puede hacer directamente v-bind="merged.attrs" / :style="merged.style"; no mute el valor de retorno dentro del componente.
Ejemplos de uso
Sección titulada «Ejemplos de uso»Interior del componente (el elemento icono del botón)
Sección titulada «Interior del componente (el elemento icono del botón)»// Componente buttonconst iconPt = computed(() => mergePt(props.pt?.icon, 'lh-button__icon'))<template> <button class="lh-button"> <i v-if="icon" v-bind="iconPt.attrs" :class="iconPt.class" :style="iconPt.style" /> <span><slot /></span> </button></template>Lado de quien lo usa
Sección titulada «Lado de quien lo usa»<lh-button :pt="{ icon: { class: 'text-lg', style: { marginRight: '4px' } }, $root: { attrs: { 'data-test': 'submit' } }, }"> Enviar</lh-button>const iconPt = mergePt(pt?.icon, 'lh-button__icon')
return ( <button className="lh-button"> {icon && <i className={iconPt.class.join(' ')} style={iconPt.style} {...iconPt.attrs} />} </button>)Advertencias
Sección titulada «Advertencias»- Fusión superficial, sin deepMerge:
classse concatena a nivel de arreglo;style/attrsse sustituyen enteros. Aquí una fusión profunda no tendría semántica (class es una lista, no un árbol). - Con
ptvacío devuelve un objeto totalmente vacío: la capa UI puede desestructurar sin más, sin comprobación de nulos. - El class devuelto es un arreglo: el
:classde Vue admite arreglos; React necesita.join(' '). - El nombre de clase base no puede omitirse:
mergePt(pt, '')devolvería un arreglo cuyo primer elemento es la cadena vacía: el nombre de clase base BEM es el anclaje del estilo y cada elemento interior debe tener el suyo.
@lh-ui/share/core/pt → mergePt( )(填好参数后点运行)Copyright © 2024-2026 FengMo WenXue