前端UI组件【免费下载链接】fastThe adaptive interface system for modern web experiences.项目地址https://gitcode.com/gh_mirrors/fa/fast点击查看免费下载导读本文围绕 API 文档 AttributeDefinition.name property 展开深入剖析microsoft/fast-element中AttributeDefinition.name属性的定义、产生方式与运行机制。name是连接「组件类属性」与「HTML 属性」的枢纽它以组件属性property名字符串的形式存在是AttributeDefinition元数据中区分「属性名」与「HTML attribute 名」的关键字段。读完本文你将掌握name的签名与语义、它与attribute、Owner、mode、converter等兄弟字段的关系以及它如何通过attr()装饰器、AttributeDefinition.collect()静态方法进入FASTElementDefinition的propertyLookup/attributeLookup双向映射表最终驱动observedAttributes的注册与属性变化回调。AttributeDefinition.name属性签名与语义官方签名的精确含义在 sites/website/src/docs/1.x/api/fast-element.attributedefinition.name.md 中该 API 文档给出了完整的定义readonly name: string;文档描述为The name of the property associated with the attribute.——即与属性相关联的组件属性property名称。注意这里的关键措辞readonly该字段在AttributeDefinition实例创建后不可再被修改它属于不可变元数据类型为string它就是一个普通的字符串保存的是组件类上属性的名字例如count、userName或fooBar语义上它是「property name」而非「HTML attribute 名」。为什么必须区分 name 与 attribute在实际 DOM 中HTML 属性attribute名与组件属性property名并非总是相同。常见的命名差异包括对比项含义典型示例nameproperty组件类上定义的 JavaScript 属性名userName、fooBar、countattributeHTML attribute暴露到 HTML 标签上的属性名user-name、foo-bar、countOwner拥有该属性的类构造函数class MyComponent extends FASTElement正是name与attribute的分离使得 fast-element 能够在保持 JS 端 camelCase 属性风格的同时遵循 HTML 规范中 kebab-case短横线attribute 命名约定。源码实现name 在 AttributeDefinition 类中的位置在 attributes.ts 中AttributeDefinition类的实现完整展示了name的声明与初始化export class AttributeDefinition implements Accessor { private readonly fieldName: string; private readonly callbackName: string; private readonly hasCallback: boolean; private readonly guards: Setunknown new Set(); /** * The class constructor that owns this attribute. */ public readonly Owner: Function; /** * The name of the property associated with the attribute. */ public readonly name: string; /** * The name of the attribute in HTML. */ public readonly attribute: string; public readonly mode: AttributeMode; public readonly converter?: ValueConverter; public constructor( Owner: Function, name: string, attribute: string name.toLowerCase(), mode: AttributeMode reflectMode, converter?: ValueConverter, ) { this.Owner Owner; this.name name; this.attribute attribute; this.mode mode; this.converter converter; this.fieldName _${name}; this.callbackName ${name}Changed; this.hasCallback this.callbackName in Owner.prototype; if (mode booleanMode converter void 0) { this.converter booleanConverter; } } // ... }从构造函数可以提炼出name的三个核心用途直接存储this.name name将传入的属性名原样保存为公开只读字段派生私有存储字段this.fieldName \_${name}生成内部存储槽如_count用于保存属性在元素实例上的实际值派生变更回调名this.callbackName \${name}Changed生成观察回调名如countChanged并立即检查Owner.prototype上是否存在该回调hasCallback 标志。这三个用途说明name不仅是一段文档字符串而是整个属性响应式链路的命名基准。默认值规则构造函数中attribute: string name.toLowerCase()展示了一条重要约定当未显式指定 HTML attribute 名时fast-element 默认使用属性名的小写形式作为 attribute 名。因此属性count默认映射到 attributecount属性userName默认映射到 attributeusername全部小写。如果希望显式采用 kebab-case如user-name则需要在配置中显式指定attribute字段或依赖attr()装饰器配置。name 的产生attr() 装饰器与 AttributeDefinition.collect()装饰器层面的录入name的源头是组件类上的attr()装饰器。在 attributes.ts 中attr()支持两种调用形式// 形式一直接用于属性非调用形式 attr class MyComponent extends FASTElement { count 0; // 等价于 attr() count } // 形式二带配置调用形式 attr({ attribute: data-count, mode: fromView }) class MyComponent extends FASTElement { count 0; }装饰器内部通过AttributeConfiguration.locate($target.constructor).push(config)把配置写入AttributeConfiguration元数据定位器中基于createMetadataLocator实现见 platform.ts。当以非调用形式使用时arguments.length 1分支装饰器会把被装饰属性的名字自动写入config.property $prop这个property字段正是后续name的输入来源。collect()将配置组装为 AttributeDefinition静态方法AttributeDefinition.collect()见 attributes.ts负责把装饰器收集到的AttributeConfiguration以及FASTElementDefinition中手写的attributes数组统一组装成AttributeDefinition实例public static collect( Owner: Function, ...attributeLists: (ReadonlyArraystring | AttributeConfiguration | undefined)[] ): ReadonlyArrayAttributeDefinition { const attributes: AttributeDefinition[] []; attributeLists.push(AttributeConfiguration.locate(Owner)); for (let i 0, ii attributeLists.length; i ii; i) { const list attributeLists[i]; if (list void 0) continue; for (let j 0, jj list.length; j jj; j) { const config list[j]; if (isString(config)) { attributes.push(new AttributeDefinition(Owner, config)); } else { attributes.push( new AttributeDefinition( Owner, config.property, // ← 这里成为 name config.attribute, config.mode, config.converter, ), ); } } } return attributes; }两种输入形态都清晰可见字符串形态直接以字符串作为namenew AttributeDefinition(Owner, config)此时attribute自动取name.toLowerCase()mode取默认值reflect配置对象形态config.property成为name其余字段attribute、mode、converter可分别定制。继承层次中的聚合在 attributes.pw.spec.ts 中有专门针对继承聚合的测试BaseElement声明attributeOneComponentA声明attributeTwoComponentB覆盖attributeTwo为 getter。测试断言ComponentA收集到 2 个属性attributeOneattributeTwoComponentB收集到 1 个属性attributeOne因为其attributeTwo是 getter装饰器不会为其生成定义。这验证了collect()通过createMetadataLocator沿原型链向上聚合配置、再结合每个类的实际属性形态去重的能力——每个生成的AttributeDefinition的name都是该链上被去重后的唯一属性名。name 在 FASTElementDefinition 中的流向propertyLookup 与 attributeLookupAttributeDefinition实例最终进入 FASTElementDefinition 的构造过程。其中关键代码如下const attributes AttributeDefinition.collect(type, nameOrConfig.attributes); const observedAttributes new Arraystring(attributes.length); const propertyLookup {}; const attributeLookup {}; for (let i 0, ii attributes.length; i ii; i) { const current attributes[i]; observedAttributes[i] current.attribute; propertyLookup[current.name] current; // name → AttributeDefinition attributeLookup[current.attribute] current; // attribute → AttributeDefinition Observable.defineProperty(proto, current); } Reflect.defineProperty(type, observedAttributes, { value: observedAttributes, enumerable: true, }); this.attributes attributes; this.propertyLookup propertyLookup; this.attributeLookup attributeLookup;这里name扮演了键角色propertyLookup[current.name] current以nameproperty 名为键建立「属性名 → AttributeDefinition」映射observedAttributes数组则填充current.attribute最终通过Reflect.defineProperty挂到类静态属性上供浏览器 custom element 机制调用attributeChangedCallbackObservable.defineProperty(proto, current)用AttributeDefinition作为Accessor在原型上定义响应式 getter/setter其内部调用Observable.track(source, this.name)见 attributes.ts用name作为可观察依赖的追踪键。由此形成完整的双向查询能力查询方向入口用法已知 property 名 → 取定义definition.propertyLookup[userName]模板绑定、代码内访问属性元数据已知 HTML attribute 名 → 取定义definition.attributeLookup[user-name]attributeChangedCallback分发、SSR 水合浏览全部属性definition.attributes调试、遍历、扩展机制name 在模板绑定中的可观察性name直接参与 fast-element 的模板编译与响应式系统getValue中Observable.track(source, this.name)意味着模板里任何对{{count}}等绑定值的读取都会以name为标识建立依赖记录当setValue写入新值时见 attributes.ts会通过((source as any).$fastController as Notifier).notify(this.name)以同样的name触发通知。读与写两侧使用同一个name字符串是属性级响应式能够精确工作的前提。name 与 attribute 的命名策略kebab-case 映射运行时默认映射如前文构造函数所示运行时attr()默认把name.toLowerCase()作为 attribute 名。例如属性firstName在未指定attribute时其 HTML attribute 为firstname。如果团队希望遵循 Web Components 社区更常见的 kebab-case 约定first-name应显式配置attr({ attribute: first-name }) firstName ;声明式模板中的 attribute-name-strategyfast-element 还通过扩展机制见 attribute-map.ts为声明式模板提供了attribute-name-strategy配置camelCase默认绑定键视为 camelCase 属性名HTML attribute 名由 kebab-case 转换推导fooBar→foo-barnone绑定键直接同时用作属性名与 attribute 名不做任何归一化。该扩展在运行时通过Observable.getAccessors(this.classPrototype).map(a a.name)attribute-map.ts读取所有 accessor 的name再按策略生成AttributeDefinition并合并进definition.attributeLookup与observedAttributes。这印证了name不仅服务于装饰器定义属性也是声明式模板/扩展体系读取「属性清单」的标准接口。name 的典型使用场景与最佳实践场景一在组件代码中获取属性元数据通过FASTElementDefinition的公开字段可以按 property 名反向查询属性定义import { FASTElementDefinition } from microsoft/fast-element; const def FASTElementDefinition.getByType(MyComponent); const countDef def.propertyLookup[count]; // → AttributeDefinition console.log(countDef.name); // count console.log(countDef.attribute); // count默认小写 console.log(countDef.mode); // reflect | boolean | fromView场景二在属性变更回调中区分触发源name派生的回调名${name}Changed可用于实现依赖联动class TemperatureWidget extends FASTElement { attr({ mode: fromView }) celsius 0; celsiusChanged(oldValue: number, newValue: number) { // 依据 name 派生回调触发处理单位换算 console.log(celsius: ${oldValue} → ${newValue}); } }最佳实践小结命名即契约name是 camelCase 的 property 名应保持语义清晰HTML attribute 名attribute另设字段管理二者不要混用显式指定 attribute 名当默认的小写映射不符合 kebab-case 团队约定时使用attr({ attribute: kebab-name })显式声明利用回调派生${name}Changed回调名由name自动派生无需额外声明监听器即可实现属性联动只读不可变name是readonly不要在运行时改写定义元数据如需扩展属性应走AttributeDefinition.collect()或声明式扩展机制。总结AttributeDefinition.name表面上只是readonly name: string一行签名实际上它是 fast-element 属性系统的「命名轴心」由attr()装饰器或AttributeConfiguration提供输入经AttributeDefinition.collect()组装为实例后同时驱动私有存储字段_name、变更回调nameChanged、可观察依赖追踪Observable.track/notify的键、propertyLookup反向索引以及默认 attribute 名推导name.toLowerCase()。理解name与attribute的区分及name在整个定义-注册-响应式链路上的流转是深入掌握 microsoft/fast-element 自定义元素属性体系的关键一步。相关源码可继续研读 attributes.ts、fast-definitions.ts 与 attributes.pw.spec.ts。赞分享前端UI组件【免费下载链接】fastThe adaptive interface system for modern web experiences.项目地址https://gitcode.com/gh_mirrors/fa/fast点击查看免费下载相关推荐在 Svelte 项目中通过 sv 社区插件 shadcn-svelte/sv 一键接入 shadcn-svelte在 Svelte 项目中通过 sv 社区插件 shadcn svelte/sv 一键接入 shadcn svelte shadcn svelte/sv 是前端UI组件深入掌握 typespec/xml 装饰器从属性映射到 XML 命名空间的完整实战指南深入掌握 typespec/xml 装饰器从属性映射到 XML 命名空间的完整实战指南 导读 typespec/xml 是 TypeSpec 官方提供的编程语言编译器后端FAST Element 的 attr() 装饰器自定义元素 HTML 属性声明的完整指南FAST Element 的 attr 装饰器自定义元素 HTML 属性声明的完整指南 导读 attr 是 FAST Element 中用于声明自定义元素 H前端UI组件上一篇ESP32开发板终极入门指南从零开始掌握Arduino编程下一篇Honey Select 2游戏优化与错误修复完全指南从环境检测到性能调优创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
5个坑位避开建建建设网站公司电话被黑免费工具指南 5个坑位避开建建建设网站公司电话被黑免费工具指南 备案流程一头雾水,后台密码泄露,网站瞬间变马?别慌,这不只是运气差,是安全底座没打牢。很多老板在找“建建建设网站公司电话”咨询时,只盯着价格和上线速度,忽略了最致命的隐患:… · 2026/9/28 3:07:07
STM32引脚不够用?74HC595级联驱动6位数码管实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 3:07:07
如何 4 步快速完成 Buzz Mac 安装?芯片架构选对,GPU 加速不白搭 如何 4 步快速完成 Buzz Mac 安装?芯片架构选对,GPU 加速不白搭 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/… · 2026/9/28 3:07:01
Spingboot启动预热的实现 启动预热的适用场景启动预热适合以下情况:数据主要来自第三方接口,无法直接从本地数据库读取。第三方接口响应较慢,首次访问容易超时。一个页面需要调用多个第三方接口或逐项查询。数据读取频繁,但变化不频繁。希望服务启动后&… · 2026/9/28 3:40:12
学Java别走弯路,这5个方向最吃香 学Java的人很多,但学明白的人不多。有人学了半年还在写控制台程序,有人一年就能独当一面。差别不在天赋,而在方向。Java生态太庞大了,什么都学等于什么都没学。选对方向,事半功倍。今天盘点当前最吃香的5个Java方向&am… · 2026/9/28 3:32:15
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
制作网页比较方便的软件怎么选?一文搞懂避坑指南 制作网页比较方便的软件怎么选?一文搞懂避坑指南 很多老板一上来就问:做个网站多少钱?但我反问他:你的域名买了吗?服务器租了吗?他一脸懵。这就是典型的“域名服务器搞不懂”。别急,今天咱们不聊虚的,直接 一文搞懂 那些让你头秃的技术名词。… · 2026/9/28 0:00:06
婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 找婚恋网站建站公司,最怕的就是被坑高价。很多同行跟我吐槽,报价单上写得模棱两可,功能栏里全是“高级定制”、“专属UI”,结果落地全是套壳。今天不聊虚的,直接甩几个我经手的 实战案例… · 2026/9/28 0:00:19
济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 上周济南一个做建材的老板找我,脸都绿了。他的官网首页弹出了赌博广告,后台被植入了挖矿脚本。他慌得问我:“网站被黑挂马不知道怎么办?能不能直接找之前的外包公司要源码下载,看看哪里被动了手脚?… · 2026/9/28 0:00:25