HTML原生无组件化能力,真组件必须由JS接管状态、渲染与生命周期;<template>仅是静态DOM容器,@media只是CSS条件开关,二者均不自动更新或管理状态。

HTML 本身不支持组件化,所谓“响应式组件”是 JS 运行时 + CSS 规则共同作用的结果;<template>只是离线 DOM 容器,@media只是样式开关,二者都不带状态、不自动更新、不管理生命周期。
为什么直接用 <template> 写不出真组件
很多人把 <template> 当成 Vue 的 <template> 或 React 的 JSX 模板,结果改了数据页面不动、事件没绑定、样式漏隔离——因为原生 <template> 只是浏览器不渲染的 DOM 片段,克隆后仍是静态结构。
- 把字符串塞进
<template>的innerHTML→ 丢失“未激活”特性,script 可能提前执行,图片提前加载 - 克隆后手动填值但没清理旧节点 → 多次渲染产生重复 DOM,内存泄漏风险明显
- 在
<table>里写<template>→ 浏览器解析时会把它移出表格上下文,最终渲染位置错乱 - 正确做法:把
<template>放在<body>顶部或<script>前,用content.cloneNode(true)克隆,再逐个赋值(如row.querySelector('.name').textContent = item.name),最后appendChild到目标容器
@media 不是响应式逻辑的执行者,只是 CSS 规则的条件开关
媒体查询只决定“哪套样式生效”,它不感知数据变化、不触发重绘、不控制 DOM 显示/隐藏。你不能靠 @media (max-width: 768px) 让导航栏自动折叠 —— 那需要 JS 控制类名或属性,CSS 只负责映射视觉效果。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 漏写
<meta name="viewport" content="width=device-width, initial-scale=1.0">→ 移动端强制缩放,@media完全失效 - 用
px写断点(如@media (max-width: 768px))→ 高 DPR 设备(如 iPhone 15 Pro)上实际视口宽度远小于 768px,断点错判 - 在同一个选择器里混用
px和%→ 流式计算被固定值覆盖,小屏下内容溢出或塌陷 - 推荐写法:移动优先,基础样式用
%/rem/clamp(),再用@media (min-width: 768px)逐步增强,避免!important和嵌套过深
真组件必须由 JS 接管:状态、渲染、交互、更新调度
React 的 <MyButton>、Vue 的 <MyButton>、Svelte 编译后的 MyButton 函数,本质都是运行时构造的 JavaScript 对象,带状态、生命周期和 diff 策略。HTML 标签只是它们输出的“序列化快照”。
立即学习“前端免费学习笔记(深入)”;
- 原生 HTML 中写
<MyButton>Click</MyButton>→ 浏览器当未知标签处理,不报错但无行为 - JSX 中写
<MyButton>Click</MyButton>→ 编译为React.createElement(...),由 React 运行时接管 - 哪怕是最轻量的组件封装,也要有明确的初始化入口(如
renderCard({ title, img }))、DOM 插入点(如container.appendChild(el))、以及更新机制(如updateCard(el, { title })) - 没有 JS 的“组件”,只是带样式的 HTML 片段,不具备复用性、状态同步能力、或跨项目可移植性
真正卡住多数人的不是技术选型,而是混淆了“结构容器”和“运行时实体”——<template> 是容器,@media 是开关,而组件是活的 JS 对象。漏掉其中任意一环,所谓“响应式组件”就只剩下一具 HTML 尸体。


















