函数
约 1766 字大约 6 分钟
2025-04-18
Stylus 函数是其强大的特性之一,允许开发者封装可重用的逻辑、进行计算和值转换。下面我将从多个维度全面介绍 Stylus 函数。
注意
由于函数提供了很多极简的写法,我们需要注意他和混入的区别,本文会提到。
一、基础介绍
1、声明与调用
声明
// 基础定义
function-name(params...)
// 函数体
return value // 可选
// 示例
add(a, b)
a + b
调用
虽然混入是一种特殊函数,但是函数在调用时,括号不可以省略。
color-func()
red
$result = add(10px, 20px)
div
margin: result
color: color-func()
3、块级作用域
函数支持块级作用域,外界无法直接获取块级作用域内的信息,因此我们可以在函数内部定义私有的变量、Mixin、函数。
foo()
$x = 10px
return $x
div
margin: foo()
font-size: $x
输出:
div {
margin: 10px;
font-size: $x;
}
4、入参
在 stylus 中,函数的参数可以是一个或多个,并且可以有默认值。可以是显式的命名参数,也可以是不定参数。
1、参数默认值
// 设置默认值
padding-x(top, right = top, bottom = top, left = right)
padding top right bottom left
.box
padding-x(10px) // 10px
padding-x(10px, 20px) // 10px 20px
padding-x(10px, 20px, 30px) // 10px 20px 30px
输出:
.box {
padding: 10px 10px 10px 10px;
padding: 10px 20px 10px 10px;
padding: 10px 20px 30px;
}
2、命名参数 / 关键字参数
这个功能,让你在调用函数时,无需记住参数的顺序,直接指定参数传参,可以提高代码的可读性。
position(pos = static, top = 0, right = 0, bottom = 0, left = 0)
position pos
top top
right right
bottom bottom
left left
.header
position(absolute, 10px, top: 10px, left: 20px)
输出:
.header {
position: absolute;
top: 10px;
right: 0;
bottom: 0;
left: 20px;
}
3、动态参数
在 stylus 中,如果参数的数量是不固定的,可以使用剩余参数 ...
和参数列表arguments
变量来处理。
// 使用 arguments
shadow()
box-shadow arguments
// 使用 ... 语法
sum(nums...)
total = 0
for n in nums
total += n
return total
// 使用
div
shadow(1px, 2px, 3px, rgba(0,0,0,.3))
span
z-index sum(1, 2, 3, 4, 5)
输出:
div {
box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.3);
}
span {
z-index: 15;
}
5、返回值
5.1、显式返回
显式返回是指函数使用 return
语句显式返回一个值。
contrast-color(color)
if lightness(color) > 50%
return black
else
return white
5.2、隐式返回
隐式返回是指函数的最后一个表达式的值作为返回值。
// 最后一个表达式值作为返回值
double(n)
n * 2
5.3、多个返回值
函数可以返回多个值,使用逗号分隔。我们可以等效的理解为返回了一个数组。
// 返回多个值
size-list()
15px 10px 5px
div
font-size size-list()[0]
输出:
div {
font-size: 15px;
}
5.4、返回值含有标识符
我们需要注意一种特殊情况,即返回值中包含标识符,如 color
、font-size
等,此时需要使用 ()
包裹返回值,否则会被当做混入编译,或者编译报错:
code1()
(margin 15px)
code2()
return marin 16px
code3()
margin 17px
div
className1 code1()
className2 code2()
className3 code3()
code3()
输出:
div {
className1: margin 15px;
className2: marin 16px;
className3: margin: 17px;; // 这里会被当做混入编译
margin: 17px;
}
6、未定义的函数
未定义的函数作为字面量输出。因此,例如,我们可以在 CSS 中调用 rgba-stop(50%, #fff),它会按照你的预期输出。我们也可以在助手中使用它。
在下面的示例中,我们简单地定义了函数 stop()
,并未定义rgba-stop-diy()
,它将返回字面量 rgba-stop-diy()
调用。
stop(pos, rgba)
rgba-stop-diy(pos, rgba)
stop(50%, orange)
div
color stop(50%, orange)
输出:
div {
color: rgba-stop-diy(50%, orange);
}
二、高级用法
1、匿名函数
匿名函数是指没有名称的函数,可以直接赋值给变量。有两种写法:
形式
square = @(n) {
return n * n
}
使用
div
z-index square(5)
输出:
div {
z-index: 25;
}
2、使用别名调用
我们可以为函数创建别名,这样可以在代码中更方便地使用。它的实质其实就是将函数赋给一个变量,然后通过变量名来调用函数,表现类似于 JavaScript 中的函数。
// JavaScript 中将函数赋值给变量
function square(n) {
return n * n;
}
const sq = square; // 别名
let result = sq(5);
console.log(result); // 25
示例:
square(n) {
return n * n
}
sq = square// 别名
div
z-index sq(5)
输出:
div {
z-index: 25;
}
3、回调函数
stylus 中的函数也存在回调函数的概念,函数可以作为参数传递给其他函数,这使得函数更加灵活和可重用。
apply(fn, value)
return fn(value)
square(n)
return n * n
.apply-square
width apply(square, 5) // 25px
4、递归调用
函数可以调用自身,这称为递归。递归函数通常用于处理树形结构或重复计算。
// 斐波那契数列
fib(n)
if n <= 1
return n
else
return fib(n - 1) + fib(n - 2)
5、在函数内部定义函数
函数内部可以定义其他函数,这些函数只能在函数内部使用,外界无法访问。
outer()
inner(n)
return n * 2
return inner(10)
result = outer() // 20
6、结合条件语句
函数可以根据条件返回不同的值。
responsive-value(device)
if device == 'mobile'
return 100%
else if device == 'tablet'
return 50%
else
return 25%
三、函数与混入的区别
特性 | 函数 | 混入 |
---|---|---|
目的 | 计算并返回值 | 输出 CSS 样式块 |
返回值 | 必须是一个或者一组值 | 样式块 |
调用方式 | 可以结合插值语法在任何地方调用 | 作为样式块调用 |
括号省略 | 不可以省略括号 | 调用同时传参,可以省略括号 |
输出 | 不会编译到文件中 | 输出 CSS |
典型用途 | 计算、转换值 | 复用样式块 |
四、最佳实践
- 命名规范:使用短横线命名(如
calculate-rem
) - 单一职责:每个函数只做一件事
- 参数验证:对关键参数进行验证
- 注释说明:为复杂函数添加注释
- 性能考虑:避免过度复杂的递归
五、示例
1、响应式断点
// 断点函数
breakpoint(name)
if name == 'mobile'
@media (max-width: 767px)
{block}
else if name == 'tablet'
@media (min-width: 768px)
{block}
// 使用
+breakpoint('mobile')
div
width 100%
输出:
@media (max-width: 767px) {
div {
width: 100%;
}
}
2、CSS 三角生成
triangle(direction = 'down', size = 10px, color = #000)
width 0
height 0
if direction == 'down'
border-left size solid transparent
border-right size solid transparent
border-top size solid color
else if direction == 'up'
border-left size solid transparent
border-right size solid transparent
border-bottom size solid color
div
triangle()
输出:
div {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #000;
}
3、网格布局
grid-column(columns, total = 12)
width (columns / total) * 100%
.col-6
grid-column(6) // 50%
输出:
.col-6 {
width: 50%;
}
六、总结
通过合理使用 Stylus 函数,可以大大提高样式代码的可维护性和复用性,特别是在处理复杂计算和响应式设计时尤为有用。
更新日志
e7112
-1于