文章目录
- [Vue 2 中使用 Less 和 SCSS](#Vue 2 中使用 Less 和 SCSS)
-
- 一、安装依赖
- [二、配置 vue.config.js](#二、配置 vue.config.js)
- [三、在 .vue 文件中使用](#三、在 .vue 文件中使用)
- [Vue 3 中使用 Less 和 SCSS](#Vue 3 中使用 Less 和 SCSS)
-
- 一、安装依赖
- [二、配置 vite.config.js](#二、配置 vite.config.js)
- [三、在 .vue 文件中使用](#三、在 .vue 文件中使用)
- [Vue 2和Vue 3使用差异](#Vue 2和Vue 3使用差异)
- 样式穿透
- less、scss语法
Vue 2 中使用 Less 和 SCSS
Vue 2 项目通常基于 Vue CLI 构建,其内部封装了 Webpack,因此配置预处理器需通过 vue.config.js 文件进行
一、安装依赖
bash
# 安装 SCSS 支持
npm install sass sass-loader --save-dev
# 安装 Less 支持
npm install less less-loader --save-dev
二、配置 vue.config.js
javascript
module.exports = {
css: {
loaderOptions: {
sass: {
additionalData: `@import "@/styles/variables.scss";` // 全局导入变量
},
less: {
additionalData: `@import "@/styles/variables.less";`
}
}
}
}
三、在 .vue 文件中使用
html
<style lang="scss">
.container {
color: $primary-color; // 引用全局变量
background: lighten($secondary-color, 10%);
}
</style>
<style lang="less">
.header {
font-size: @font-size-large;
}
</style>
Vue 3 中使用 Less 和 SCSS
Vue 3 推荐使用 Vite 作为构建工具,其配置更轻量、响应更快,且直接基于原生 ES 模块,无需 Webpack 复杂配置。
一、安装依赖
bash
# SCSS
npm install sass -D
# Less
npm install less -D
二、配置 vite.config.js
javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/variables.scss";`
},
less: {
additionalData: `@import "@/styles/variables.less";`
}
}
}
})
三、在 .vue 文件中使用
与 Vue 2 完全一致
Vue 2和Vue 3使用差异
| 维度 | Vue 2 (Vue CLI) | Vue 3 (Vite) |
|---|---|---|
| 构建工具 | Webpack | Vite |
| 预处理器依赖 | sass-loader + sass | 仅 sass / less |
| 配置文件 | vue.config.js | vite.config.js |
| 配置路径 | css.loaderOptions | css.preprocessorOptions |
| 性能 | 较慢,打包时间长 | 极快,热更新秒级 |
| 全局变量导入 | 支持,但需手动配置 | 支持,更稳定 |
| 社区支持 | 逐渐减少,官方停止维护 | 官方主力推荐 |
样式穿透
常见使用场景
- 修改第三方组件样式
- 修改子组件内部元素样式
- 覆盖默认主题样式
样式穿透
- vue2
使用 >>> 操作符使用 /deep/使用 ::v-deep
- vue3
:deep():slotted():修改插槽样式:global():添加全局样式
Vue2 中的样式穿透
html
<!-- 1. 使用 >>> 操作符 -->
<style scoped>
.parent >>> .child {
color: red;
}
</style>
<!-- 2. 使用 /deep/ -->
<style scoped>
.parent /deep/ .child {
color: red;
}
</style>
<!-- 3. 使用 ::v-deep -->
<style scoped>
.parent ::v-deep .child {
color: red;
}
</style>
Vue3 中的样式穿透
html
<style scoped>
/* 方式1:直接作用于子元素!推荐写法 */
:deep(.child) {
color: red;
}
/* 方式2:从父元素开始 */
.parent :deep(.child) {
color: red;
}
/* 多层级选择器 */
.parent {
:deep(.level-1) {
.level-2 {
.level-3 {
color: blue;
}
}
}
}
/* 修改插槽内容的样式 */
:slotted(.slot-class) {
color: red;
}
:global(.global-class) {
color: blue;
}
</style>
less、scss语法
1、变量
变量声明用@,写法:@width: 10px;
变量声明用$,写法:$width: 10px;
css
//less
@width:10px;
width:@width;
//scss
$width:10px;
width:$width;
2、运算
less、scss用法同
css
@var: 50vh/2;
width: calc(50% + (@var - 20px));
3、注释
less、scss用法同
css
/* 一个块注释,源文件与编译后正常默认文件都保留。
* style comment!
*/
@var: red;
// 这一行被注释掉了,仅保留源文件中!
@var: white;
4、嵌套
less、scss用法同
css
#header {
color: black;
width: 600px;
.logo {
width: 300px;
}
&:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
&-bottom {
background-image: url("header-bottom.png");
}
}
5、混入(Mixin)
less:直接在要混入的元素中调用
scss:使用@mixin注册,@include调用
css
// Less
// .bordered 类所包含的属性就将同时出现在 #menu a 和 .post a 中了。
// 注意,你也可以使用 #ids 作为 mixin 使用。
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu a {
color: #111;
.bordered();
}
.post a {
color: red;
.bordered();
}
/* ------------------------------ */
// Sass
@mixin bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu a {
color: #111;
@include bordered;
}
.post a {
color: red;
@include bordered;
}
6、函数
css
// Less
.test(@a, @b) {
@width: @a + @b;
}
@my-radius: 10px;
.border_radius(@v, @h, @radius: @my-radius){
box-@{v}-@{h}-radius: @my-radius;
}
.good{
.test(20px, 30px);
.border_radius(top, left);
.border_radius(bottom, right, 5px);
width: @width;
}
/* ------------------------------ */
// Sass
@function double($n) {
@return $n * 2;
}
#sidebar {
width: double(5px);
}
7、继承
css
// Less
nav ul {
&:extend(.inline);
background: blue;
}
.inline {
color: red;
}
//scss
.class1 {
border: 1px solid #ddd;
}
.class-sub {
@extend .class1;
font-size: 120%;
}
8、if-else、for、while、each
less
css
// if-else
.max (@foo) when (@foo > 0) {
width: @foo;
}
.mixin (@foo) when (default()) {
width: 0;
}
.max(10px);
// 编译后
.max {
width: 10px;
}
//循环
loop(@counter) when (@counter > 0) {
// 递归调用自身
.loop(@counter - 1);
// 每次调用时产生的样式代码
width: (10px - * @counter);
}
.container {
// 调用循环
.loop(5);
}
// 编译后
.container {
width: 10px;
width: 20px;
width: 30px;
width: 40px;
width: 50px;
}
scss
css
//if-else
$color: red;
p {
color: $color;
@if $color == red {
background-color: #000;
} @else {
background-color: #fff;
}
}
//for、while、each
@for $i from 1 to 10 {
.border-#{$i} {
border: #{$i}px solid blue;
}
}
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
@each $member in a, b, c, d {
.#{$member} {
background-image: url("/image/#{$member}.jpg");
}
}
9、导入
js
// Less
@import "library"; // .less 可以省略后缀
@import "test.css";
//scss
@import 'foo.scss';
@import 'foo.css';
10、作用域
变量继承 :先在本地找变量,没有,则从父级继承
使用说明:
- 不用事先声明变量,同一作用域内,可随时随地定义变量(因为会找整个本地作用域)
- 优先查找同作用域下变量
- 子作用域可访问父作用域变量,反之,不行