تخطَّ إلى المحتوى

pt —— دمج الخصائص الممررة مباشر

يحتوي المكوّن على عناصر متعددة في داخله (العنصر <button>와 <span> داخله في الزر، و<input> وأيقونة <i> الأمامية في حقل الإدخال)، فما العمل إذا أراد المستخدم ضبط أحدها من الخارج؟ إجابة lh-ui هي حزمة خصائص PT (PassThrough): يُعرِض المكوّن prop باسم pt ليمرر class / style / attrs لكل عنصر داخلي باسمه. ويتكفل mergePt بدمجها مع أسماء الأصناف الأساسية للمكوّن.

  • داخل مكتبة المكوّنات: يستدعي كل عنصر داخلي mergePt(props.pt?.icon, 'lh-button__icon') فيحصل على class / style / attrs الواجب تعليقها.
  • جانب المستخدم يتوغل داخل المكوّن للضبط الدقيق عبر prop اسمه pt، دون الحاجة إلى اختراق :deep().

لا ينبغي استخدامه: التخصيص على مستوى السمة (استخدم themeVars)؛ أو إضافة صنف بسيط (استخدم prop اسمه class).

import { mergePt, type LhPtAttrs } from '@lh-ui/share/core/shared/pt'
export interface LhPtAttrs {
class?: string | string[] | Record<string, boolean>
style?: Record<string, string>
attrs?: Record<string, any>
}
الدالة التوقيع الدور
mergePt (pt: LhPtAttrs | undefined, baseClass: string) => { class: string[]; style: Record<string, string>; attrs: Record<string, any> } دمج خصائص PT مع اسم الصنف الأساسي

يأتي baseClass دائمًا في رأس المصفوفة، وما يأتي بعده أصناف المستخدم:

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'] —— لا يُؤخذ من الكائن إلا المفاتيح ذات القيم الصادقة
mergePt({ class: 'a b ' }, 'lh-button__icon')
// class: ['lh-button__icon', 'a', 'b'] —— تُقطع السلسلة وفق المسافات، وتُستثنى السلاسل الفارغة

ولماذا يتقدم baseClass: حتى لا تطغى خصوصية اسم الصنف الأساسي BEM على أصناف المستخدم (فعند تساوي الأصناف في الخصوصية يغطي المتأخر المتقدم). فلا بد أن يبقى مُعدِّل --primary الخاص بالمكوّن قادرًا على تغطية صنف المستخدم my-icon.

mergePt(undefined, 'lh-button__icon')
// { class: ['lh-button__icon'], style: {}, attrs: {} } —— عندما يكون pt فارغًا يكون الكل فارغًا
mergePt({ style: { color: 'red' }, attrs: { 'data-x': '1' } }, 'lh-button__icon')
// { class: ['lh-button__icon'], style: { color: 'red' }, attrs: { 'data-x': '1' } }

تنبيه: يتم تمرير style / attrs بالمرجع، بلا نسخ. فما على طبقة واجهة المستخدم بعد استلامها سوى v-bind="merged.attrs" / :style="merged.style"؛ ولا تُجرِ تعديلًا على القيمة المُعادة داخل المكوّن.

داخل المكوّن (عنصر الأيقونة في الزر)

Section titled “داخل المكوّن (عنصر الأيقونة في الزر)”
// مكوّن button
const 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>
<lh-button
:pt="{
icon: { class: 'text-lg', style: { marginRight: '4px' } },
$root: { attrs: { 'data-test': 'submit' } },
}"
>
إرسال
</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>
)
  • دمج سطحي، بلا deepMerge: class يُوصَل على مستوى المصفوفة، وstyle / attrs يُستبدلان كحزمة كاملة. ولا دلالة للدمج العميق هنا (فclass قائمة لا شجرة).
  • pt الفارغ يُعيد كائنًا فارغًا: يمكن لطبقة واجهة المستخدم تفكيكه دون تفكير، بلا حاجة لفحص الفراغ.
  • class المُعادة مصفوفة: يقبل Vue :class مصفوفة، أما React فيحتاج .join(' ').
  • لا يُستغنى عن اسم الصنف الأساسي: mergePt(pt, '') يُنتج مصفوفة أول عنصر فيها سلسلة فارغة—فاسم الصنف الأساسي BEM هو مرساة الأنماط، ولكل عنصر داخلي أن يكون له واحد.
@lh-ui/share/core/pt → mergePt( )
返回值
(填好参数后点运行)

Copyright © 2024-2026 FengMo WenXue