如何使用Material Components Web Foundations的组件基础方法
嘿,我来帮你理清楚Material Components里Foundations层的用法,结合你给出的线性进度条代码来一步步说明~
先搞懂Foundations是什么
Foundations是每个MDC组件的核心逻辑层,它和DOM操作完全解耦,专门负责处理组件的状态管理、业务规则和核心行为;而Adapter层则负责对接DOM,完成实际的元素操作(比如加类名、改样式)。这种分层设计的好处是:你可以自定义DOM结构、适配不同前端框架,只要实现对应的Adapter,就能复用Foundations的核心逻辑。
针对你的线性进度条用Foundations实操
先补全你给出的线性进度条完整HTML结构(你之前的代码截断了):
<div role="progressbar" class="mdc-linear-progress"> <div class="mdc-linear-progress__buffering-dots"></div> <div class="mdc-linear-progress__buffer"></div> <div class="mdc-linear-progress__bar mdc-linear-progress__primary-bar"> <span class="mdc-linear-progress__bar-inner"></span> </div> <div class="mdc-linear-progress__bar mdc-linear-progress__secondary-bar"> <span class="mdc-linear-progress__bar-inner"></span> </div> </div>
1. 初始化:实现Adapter + 创建Foundation实例
首先要写一个Adapter对象,它需要实现MDCLinearProgressFoundation要求的所有方法——这些方法就是Foundation用来和DOM交互的“桥梁”。然后把Adapter传给Foundation实例完成初始化:
// 获取进度条DOM元素 const progressEl = document.querySelector('.mdc-linear-progress'); // 实现Adapter const progressAdapter = { // 给根元素加类名 addClass: (className) => progressEl.classList.add(className), // 移除根元素类名 removeClass: (className) => progressEl.classList.remove(className), // 判断根元素是否有某个类名 hasClass: (className) => progressEl.classList.contains(className), // 设置根元素样式 setStyle: (prop, value) => progressEl.style.setProperty(prop, value), // 设置缓冲条样式 setBufferStyle: (prop, value) => { const bufferEl = progressEl.querySelector('.mdc-linear-progress__buffer'); bufferEl.style.setProperty(prop, value); }, // 设置主进度条样式 setPrimaryBarStyle: (prop, value) => { const primaryInner = progressEl.querySelector('.mdc-linear-progress__primary-bar .mdc-linear-progress__bar-inner'); primaryInner.style.setProperty(prop, value); }, // 设置副进度条样式 setSecondaryBarStyle: (prop, value) => { const secondaryInner = progressEl.querySelector('.mdc-linear-progress__secondary-bar .mdc-linear-progress__bar-inner'); secondaryInner.style.setProperty(prop, value); }, // 获取主进度条样式 getPrimaryBarStyle: (prop) => { const primaryInner = progressEl.querySelector('.mdc-linear-progress__primary-bar .mdc-linear-progress__bar-inner'); return primaryInner.style.getPropertyValue(prop); }, // 获取元素的位置信息 getBoundingClientRect: () => progressEl.getBoundingClientRect(), // 设置根元素属性 setAttribute: (attr, value) => progressEl.setAttribute(attr, value), // 移除根元素属性 removeAttribute: (attr) => progressEl.removeAttribute(attr), }; // 创建Foundation实例并初始化 const progressFoundation = new mdc.linearProgress.MDCLinearProgressFoundation(progressAdapter); progressFoundation.init();
2. 调用Foundations的核心方法控制进度条
现在你可以直接用Foundation提供的方法来操控进度条了,举几个常用的:
- 设置进度值(范围0-1):
progressFoundation.setProgress(0.7) - 设置缓冲值(范围0-1):
progressFoundation.setBuffer(0.9) - 启动进度条动画:
progressFoundation.open() - 停止并隐藏进度条:
progressFoundation.close() - 切换为不确定模式(无限动画):
progressFoundation.setIndeterminate(true)
比如要让进度条显示70%进度、缓冲到90%并启动动画,就这么写:
progressFoundation.setProgress(0.7); progressFoundation.setBuffer(0.9); progressFoundation.open();
3. 监听状态变化(可选)
如果需要监听进度条的状态事件,比如动画结束,可以用Foundation的subscribe方法:
progressFoundation.subscribe('close', () => { console.log('进度条动画已经结束啦'); });
为什么要直接用Foundations?
如果你用MDC提供的MDCLinearProgress组件类,它已经封装好了Adapter和Foundation的绑定,适合快速开发。但如果你需要:
- 自定义DOM结构(比如修改类名、添加自定义元素)
- 把组件集成到Vue/React等框架里(自己封装组件)
- 单独测试组件的核心逻辑(不用依赖DOM)
那Foundations层就特别有用——它把逻辑和DOM操作彻底分开,让你能灵活定制组件的表现。
内容的提问来源于stack exchange,提问作者ErraticFox
相关产品推荐
相关产品推荐

