十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Stylus @block 代码块变量:定义、传递与插值渲染完全指南

Stylus @block 代码块变量:定义、传递与插值渲染完全指南 Stylus block 代码块变量定义、传递与插值渲染完全指南【免费下载链接】stylusExpressive, robust, feature-rich CSS language built for nodejs项目地址: https://gitcode.com/gh_mirrors/st/stylusblock 是 Stylus 中一项独特的能力它允许把一段完整的代码块当作普通变量赋值、传递、复用并在任意位置通过插值语法渲染成 CSS。本文以官方文档 docs/docs/block.md 为主线结合仓库源码与测试用例完整讲解 block 的两种定义语法、插值渲染方式、与 block mixins 的关系以及函数返回、参数传递、哈希/列表存储等高阶实战用法。block 是什么让代码块成为一等公民变量在绝大多数 CSS 预处理器中代码块只能依附于选择器、mixin 或 rule 存在。而 Stylus 的 block 特性打破了这一限制——它允许将任何一段代码块赋值给一个变量之后这个变量可以像普通变量一样被调用、作为参数传入函数、存入对象或列表甚至由函数返回然后再以插值形式渲染到任意位置。官方文档对它的定位非常明确You can assign any block of code in Stylus to a variable and then call it, pass as an argument or reuse in any other way.即Stylus 中的任意代码块都可以赋值给变量随后被调用、作为参数传递或以任何其他方式复用。从源码结构看Stylus 为此专门实现了Atblock节点见 lib/nodes/atblock.js其内部持有一个完整的block本质上是一个可变量化的代码片段容器。定义代码块两种等价语法Stylus 提供两种完全等价的方式把一个代码块绑定到变量。方式一赋值号 缩进块在赋值号之后以增加的缩进书写代码块foo width: 20px height: 20px这里的foo即被赋值为一个代码块变量其内容是两条属性声明。方式二block关键字 花括号使用block关键字配合花括号语法语义与上面完全一致foo block { width: 20px height: 20px }两种写法在解析阶段都会被归一到同一个Atblock节点。从解析器实现看lib/parser.js 中的atblock()方法会创建nodes.Atblock随后调用this.block(node, false)解析整个块体atblock(node) { if (!node) this.expect(atblock); node new nodes.Atblock; this.state.push(atblock); node.block this.block(node, false); this.state.pop(); return node; }而缩进赋值写法则通过同一解析器内的assignAtblock()见 lib/parser.js在表达式为空时自动补上atblock()从而两条路径殊途同归。词法层面block关键字在 lib/lexer.js 中被识别为atblocktokencase block: return new Token(atblock);渲染代码块在插值中调用变量将代码块变量绑定好后只需把它放进插值{}中即可渲染。例如.icon {foo}会被编译输出为.icon { width: 20px; height: 20px; }注意这里的{foo}是 Stylus 的插值语法interpolation它会将foo所代表的整个代码块原样展开到当前上下文中。这一机制与文档 docs/docs/interpolation.md 中讲解的插值能力一脉相承也是当前版本唯一官方支持的渲染方式。值得一提的是块内还可以引用该上下文中的已有属性。例如c width: 100px height: (width / 2) .foo {c}输出结果为.foo { width: 100px; height: 50px; }其中width通过属性查找property lookup取到了同块内上一条声明的值这说明 block 并非机械的字符串拼接而是保留 Stylus 语义的活代码。与 block mixins 的关系文档明确指出这也是使用传给 block mixins 的代码块的同一方式this is the same way you can use the blocks passed to the block mixins。也就是说mixin 中通过block关键字接收到的调用方代码块本质上就是一个 block同样可以通过插值渲染出来。关于 block mixins 的详细定义与传参方式可参阅 mixins 文档中的 Block Mixins 章节。高阶用法从测试用例看 block 的完整能力仓库测试用例 test/cases/atblock.styl 及其期望输出 test/cases/atblock.css 覆盖了远超文档示例的场景可以作为实战参考逐一验证。1. 块内支持选择器与流程控制block 内部不仅能写属性还能写嵌套选择器、if条件等完整 Stylus 结构a block { .bar { color: red if true { width: 200px } } } {width: 0} {height: 0}其输出为.bar { color: #f00; width: 200px; }2. 函数返回值作为代码块函数可以return一个 block调用后拿到的变量同样可渲染func() return block { color: red } b func() .foo {b}输出.foo { color: #f00; }3. 作为函数参数传递block 变量可以像普通参数一样传给 mixin/函数在函数内部通过插值渲染对应文档所述pass as an argumentbar(b, c) .foo {b} .bar {c} .baz { bar(block{ .raz { width: 20px } }, block{ height: 20px }) }输出.baz .foo .raz { width: 20px; } .baz .bar { height: 20px; }4. 存入哈希对象与列表block 可以存入哈希对象通过属性访问或下标访问以及列表再取出来渲染a {} a[foo] .bar color: red b a.foo {b}以及a () a[0] .bar color: red b a[0] {b}两种方式输出一致.bar { color: #f00; }这证实了 block 变量与普通值类型一样具有完整的可存储、可检索能力。5. 顶层直接渲染代码块变量也可以在文件顶层无任何外层选择器直接通过{a}渲染作为根级 CSS 输出测试用例中多次使用了这一形式。源码视角block 的完整生命周期结合仓库源码可以梳理出 block 从解析到输出的完整链路词法分析lib/lexer.js 将block关键字识别为atblocktoken缩进写法不经过此路径。语法解析lib/parser.js 的atblock()构造Atblock节点并解析块体lib/parser.js 的assignAtblock()负责在expr.isEmpty时补全 block 赋值同时 lib/parser.js 在处理属性值与表达式时也调用了assignAtblock从而同时支持缩进与花括号两种写法。节点建模lib/nodes/atblock.js 定义了Atblock类nodesgetter 直接返回内部block.nodes并实现了clone()用于深拷贝——这让代码块变量被多次渲染时彼此独立、互不干扰。求值求值lib/visitor/evaluator.js 的visitAtblock()对块内节点递归求值包括if条件、属性查找、表达式计算等返回求值后的 block。规范化与输出lib/visitor/normalizer.js 在根级遍历时跳过atblock节点本身因为它已被赋给变量不应直接输出最终由插值展开将其内容渲染进目标上下文。这条链路解释了文档中只能在插值中渲染的限制block 本质上是一个待展开的块对象插值是其唯一的展开入口。使用限制与注意事项官方文档明确给出当前版本的能力边界Right now you can only pass the variable as any other variable and render it inside an interpolation. In future we would provide more ways of handling it.即目前 block 变量只能像普通变量一样传递并借助插值渲染暂无其他处理方式。实际使用中还需注意渲染时必须使用{变量名}插值语法直接书写变量名不会输出代码块缩进写法的块体必须比赋值行有更大的缩进否则不会被识别为块代码块内部会保留 Stylus 的完整语义嵌套、条件、属性查找等因此渲染结果会随上下文变化而非静态文本。参考资料官方文档Block 章节、Interpolation 章节、Mixins 章节Block Mixins节点实现lib/nodes/atblock.js解析实现lib/parser.js词法实现lib/lexer.js求值实现lib/visitor/evaluator.js测试用例test/cases/atblock.styl、test/cases/atblock.css【免费下载链接】stylusExpressive, robust, feature-rich CSS language built for nodejs项目地址: https://gitcode.com/gh_mirrors/st/stylus创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表