Ir al contenido

Cómo consume cada plataforma

El core de share son funciones puras, sin nada de reactividad. Cada biblioteca UI hace una sola cosa: vincular la salida de las funciones puras a la plantilla y devolver la entrada del usuario a las funciones puras. Estas son las cuatro formas de cableado.

El cableado de cada componente siempre son tres pasos:

  1. La capa del framework mantiene un state (ref / useState / data reactivo)
  2. Interacción del usuario → se llama a la función pura de core para calcular el nuevo state → se escribe de vuelta
  3. La plantilla llama a las funciones puras de clases / paquete de atributos aria para renderizar
// lado core (independiente del framework, este repositorio)
export function getSwitchClasses(state: LhSwitchState): string
export function getSwitchAria(state: LhSwitchState): Record<string, string>
export function toggleSwitch(state: LhSwitchState, checked: boolean): LhSwitchState
<script setup lang="ts">
import { ref, computed } from 'vue'
import { getSwitchClasses, getSwitchAria, toggleSwitch } from '@lh-ui/share/core/switch'
const checked = ref(false)
const classes = computed(() => getSwitchClasses({ checked: checked.value, disabled: false }))
const aria = computed(() => getSwitchAria({ checked: checked.value }))
function onToggle() {
checked.value = toggleSwitch({ checked: checked.value }, !checked.value).checked
}
</script>
<template>
<button :class="classes" v-bind="aria" @click="onToggle">
<span class="lh-switch__handle" />
</button>
</template>
<style lang="scss">
@use '@lh-ui/share/styles/switch';
</style>

Los estilos se inician totalmente por side-effect en la entrada de la biblioteca, así que normalmente no hace falta importarlos dentro del componente (véase Estrategia de inyección).

<script lang="ts">
import { getSwitchClasses, getSwitchAria, toggleSwitch } from '@lh-ui/share/core/switch'
export default {
name: 'LhSwitch',
data() {
return { checked: false }
},
computed: {
classes() {
return getSwitchClasses({ checked: this.checked, disabled: false })
},
aria() {
return getSwitchAria({ checked: this.checked })
},
},
methods: {
onToggle() {
this.checked = toggleSwitch({ checked: this.checked }, !this.checked).checked
},
},
}
</script>

El usuario importa los estilos a demanda:

import '@lh-ui/vue2/theme.css'
import '@lh-ui/vue2/style/switch'

useMemo sustituye a computed; el cambio de state desencadena el re-render, que de por sí es reactividad:

import { memo, useMemo, useState } from 'react'
import {
getSwitchClasses,
getSwitchAria,
toggleSwitch,
} from '@lh-ui/share/core/switch'
import '@lh-ui/react/style/switch'
export const LhSwitch = memo(function LhSwitch() {
const [checked, setChecked] = useState(false)
const classes = useMemo(
() => getSwitchClasses({ checked, disabled: false }),
[checked],
)
const aria = useMemo(() => getSwitchAria({ checked }), [checked])
return (
<button
type="button"
className={classes}
{...aria}
onClick={() => setChecked((c) => !c)}
>
<span className="lh-switch__handle" />
</button>
)
})

En uniapp no se pueden vincular attributos aria arbitrarios a <view> / <text>: la salida de getSwitchAria se filtra en la plataforma de miniprogramas; en cambio sigue siendo usable en app / h5. La vinculación de clases se hace con :class en forma de string o array:

<template>
<view :class="classes" @tap="onToggle">
<view class="lh-switch__handle" />
</view>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { getSwitchClasses, toggleSwitch } from '@lh-ui/share/core/switch'
const checked = ref(false)
const classes = computed(() => getSwitchClasses({ checked: checked.value }))
function onToggle() {
checked.value = !checked.value
}
</script>

Internacionalización: un mismo emitter, cuatro suscripciones

Sección titulada «Internacionalización: un mismo emitter, cuatro suscripciones»

LhLocale es un emisor de eventos puro; version se incrementa con cualquier cambio de idioma. Cada plataforma lo convierte en su propia señal de re-render:

Plataforma Cableado
vue2 / vue3 / uniapp ref(lhlocale.version) + lhlocale.subscribe(v => version.value = v)
react useSyncExternalStore(lhlocale.subscribe, () => lhlocale.version)
import { lhlocale } from '@lh-ui/share/locales'
lhlocale.setLocale('en-US') // cambia de idioma; version se incrementa y se emite
const text = lhlocale.t('input.placeholder')

Hay una demostración en vivo en Referencia de internacionalización.

Enlace local: modifica el código fuente de share y surte efecto al instante

Sección titulada «Enlace local: modifica el código fuente de share y surte efecto al instante»

Con la disposición de la familia, la configuración dev / test de cada biblioteca UI aplica un alias al lh-ui-share/ del directorio hermano, de modo que en dev se usa el código fuente TS / SCSS y no los artefactos. Un archivo profundo nuevo (por ejemplo core/foo/bar.ts) está disponible de inmediato en dev, pero si no se ha ejecutado sync-exports no existe la clave exports correspondiente en el lado npm — antes de publicar hay que ejecutar sí o sí el pnpm build completo, si no el pnpm up de quien depende dará MODULE_NOT_FOUND.

Copyright © 2024-2026 FengMo WenXue