应将导航样式拆分为\_nav.scss模块,仅含变量、mixin和根选择器,通过@use导入依赖,限制嵌套≤4层,用mixin封装flex布局与响应式断点,动画采用max-height过渡保障可访问性。

用 _nav.scss 单独拆分导航组件,别塞进 main.scss 里
把导航栏样式硬写在主文件里,等于给后续维护埋雷:改个断点要翻几十页,加个暗色模式适配得全局搜 background-color。Sass 的模块化价值就体现在这里——每个视觉单元对应一个局部文件。
必须以下划线开头命名:_nav.scss,否则 Sass 会尝试单独编译它,造成重复 CSS 输出。这个文件只放三类东西:变量(如 $nav-height)、mixin(如 @mixin nav-item-base())、以及根选择器(如 .nav 及其直接子元素)。
-
@use "variables" as v;显式导入颜色/断点等基础变量,避免直接读$color-primary报错 - 不写
@import—— 它已弃用,且无命名空间,两个模块都定义$spacing会冲突 - 所有嵌套不超过 4 层;比如
.nav__list > .nav__item > a就到顶了,再深就该拆出_dropdown.scss
用 @mixin nav-flex-base() 封装 flex 布局逻辑,别每处都手写
反复敲 display: flex; align-items: center; list-style: none; 不仅费时,还容易漏掉关键防护项。比如 Safari 下 flex-shrink: 0 缺失会导致小屏上菜单项被压缩变形,min-width: 0 缺失会让文字撑破容器。
一个稳定可用的 mixin 至少覆盖这几点:
- 统一设
flex-wrap: wrap和justify-content: space-between,适配不同数量菜单项 - 给直接子
li加flex-shrink: 0,防止被 flex 压缩 - 给内部
a设white-space: nowrap和text-decoration: none,避免断行或下划线干扰 - 调用时一行搞定:
@include nav-flex-base();,不用再记哪几行不能少
响应式断点统一用 $nav-breakpoint: 768px 变量控制,别散落在各处
硬编码 @media (max-width: 768px) 在五个地方,以后想调成 580px 就得手动改五次。更糟的是,如果导航项文字变多,实际换行点可能早于 768px,导致桌面端就折行。
正确做法是收口到变量,并按内容驱动:
- 定义
$nav-breakpoint: 768px在_variables.scss中 - 在
_nav.scss里写@media (max-width: $nav-breakpoint) { ... } - 若某项目导航项特别长,可局部覆盖:
$nav-breakpoint: 580px !global;(慎用),或另起$nav-breakpoint-wide - 必须用
max-width而非min-width:小屏设备加载时不会先闪桌面版再跳转,旧版 Safari 也不会解析延迟
折叠菜单动画用 max-height 过渡,别碰 height: auto 或 display
height: auto 根本无法 transition,display: none 会切断 DOM 流、让屏幕阅读器跳过、JS 焦点管理失效——这是无障碍和可访问性的硬伤。
可行方案只有 max-height + overflow: hidden:
- 收起状态:
max-height: 0; overflow: hidden; - 展开状态:
max-height: 480px;(实测够盖 8 个菜单项,太小会截断动画,太大收起有延迟) - 过渡写死:
transition: max-height 0.3s ease-in-out;,别用 JS 控制 transform,更轻量也更好测 - 注意:这个值不是猜的,得根据真实菜单项高度 × 数量算出来,写进 mixin 里传参更稳妥
真正难的不是写出能动的导航栏,而是让它的结构经得起三个月后的修改——变量在哪改、mixin 怎么扩、断点怎么调、动画怎么延展,这些路径必须清晰可追溯。否则再“丝滑”的效果,也会在第一次需求变更时崩成一地碎片。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











