
1. 从零配置Less/Sass开发环境刚开始接触Vue3项目时样式预处理器总是让我又爱又怕。爱的是它们提供的变量、嵌套等特性确实能提升开发效率怕的是配置过程总会出现各种奇怪问题。经过多个项目的实战我总结出一套最稳定的配置方案。在Vite项目中安装Less/Sass只需要两步# 安装Less npm install less -D # 安装Sass注意包名是sass不是node-sass npm install sass -D安装完成后在单文件组件中直接声明即可使用!-- 使用Less -- style langless primary-color: #1890ff; .container { background: primary-color; } /style !-- 使用Sass -- style langscss $primary-color: #1890ff; .container { background: $primary-color; } /style这里有个新手容易踩的坑Sass的安装包名已经从早期的node-sass改为sass。我去年迁移项目时就因为没注意这个细节导致样式一直不生效调试了半天才发现问题。另外建议在团队项目中统一预处理器选择混用Less和Sass会增加维护成本。2. Scoped样式的原理与实战技巧第一次看到组件样式自动加上data-v-xxx属性时我觉得这简直是黑魔法。后来研究源码才发现Vue的Scoped样式是通过PostCSS实现的转换。当你在style标签添加scoped属性时style scoped .button { color: red; } /styleVue会做三件事给组件模板的每个DOM元素添加唯一的data属性如data-v-7ba5bd90将CSS选择器转换为带属性约束的形式如.button[data-v-7ba5bd90]生成最终的CSS样式表在后台管理系统开发中我常用这种方式避免组件样式冲突。比如同时使用多个第三方组件库时给自定义组件加上scoped能有效防止样式污染。但要注意Scoped样式不能替代CSS Modules对于需要动态切换的样式类还是推荐用CSS Modules的方案。3. 样式穿透的四种方案对比实际项目中总会遇到需要覆盖第三方组件样式的情况。有次我需要修改Element Plus的弹窗样式发现普通的类名选择器根本不生效这才深入研究了样式穿透的各种方案/deep/ 选择器Vue2推荐.wrapper /deep/ .el-dialog { border-radius: 8px; } 选择器某些预处理器不支持.wrapper .el-dialog { border-radius: 8px; }::v-deep 伪元素Vue3推荐.wrapper ::v-deep(.el-dialog) { border-radius: 8px; }:deep() 函数最新规范.wrapper :deep(.el-dialog) { border-radius: 8px; }经过实测在Vue3Sass环境下::v-deep的兼容性最好。但要注意这些方法都会破坏Scoped样式的隔离性建议控制在必要的最小范围内使用。4. 用Sass实现BEM架构实战第一次看到BEM的__和--符号时我觉得这种写法既啰嗦又难看。直到接手一个大型后台项目看着满屏的.card、.title、.content类名才明白BEM的价值所在。下面分享我用Sass实现的BEM架构方案首先定义基础mixin// bem.scss $namespace: xm !default; $element-separator: __ !default; $modifier-separator: -- !default; mixin b($block) { .#{$namespace}-#{$block} { content; } } mixin e($element) { at-root { #{}#{$element-separator}#{$element} { content; } } } mixin m($modifier) { at-root { #{}#{$modifier-separator}#{$modifier} { content; } } }然后在vite.config.js中全局引入export default defineConfig({ css: { preprocessorOptions: { scss: { additionalData: import /styles/bem.scss; } } } })实际组件中的使用示例template div classxm-header div classxm-header__left button classxm-header__btn xm-header__btn--primary提交/button /div /div /template style langscss scoped include b(header) { height: 60px; include e(left) { float: left; } include e(btn) { padding: 8px 16px; include m(primary) { background: blue; } } } /style这种架构下即使项目规模扩大样式也不会陷入命名冲突的泥潭。我在最近的后台管理系统项目中用这套方案管理了200组件协作开发时大家都觉得结构清晰。5. 后台管理系统布局实战结合前面所有技术点我们来实现一个典型的后台管理布局。这个布局包含三个核心组件Header、Menu和Content区域。首先创建布局容器!-- Layout.vue -- template div classxm-layout Header / div classxm-layout__main Menu / Content / /div /div /template style langscss scoped include b(layout) { display: flex; flex-direction: column; height: 100vh; include e(main) { display: flex; flex: 1; overflow: hidden; } } /styleHeader组件实现!-- Header.vue -- template div classxm-header div classxm-header__logo管理系统/div div classxm-header__useradmin/div /div /template style langscss scoped include b(header) { height: 60px; background: #001529; color: white; display: flex; align-items: center; padding: 0 20px; include e(logo) { font-size: 20px; font-weight: bold; } include e(user) { margin-left: auto; } } /style这种架构下每个组件的样式都自成体系既保持了模块化又避免了命名冲突。我在实际项目中发现配合Vue3的Composition API使用开发效率能提升30%以上。