带参数的混合(Parametric Mixins)
1)混合可以携带参数,在设置样式规则时可以使用传入的参数
参数的值在使用时 必须传入,除非是给了默认值,不然会报错
.testdiv(@radius){
border-radius: @radius;
}
.a{
.border-radius(10px);
}
注意: 1.携带参数后在使用时必须给参数赋值,也可以使用默认值,在定义时给一个值即可
2.只要在选择器后面出现(),不论携带参数的个数是多少个(0/1/…),.testdiv 的样式规则只会应用到 .a 上, .testdiv 则不会出现设置的样式规则
.testdiv(@radius: 20px){
border-radius: @radius;
}
.a{
.border-radius();//不传入值时 默认传入的值为 20px
}
2)选择器只是使用()却不携带任何参数时
.a(){样式规则}
.b{ .a; }
.a 的样式规则只会应用到 .b 上, .a 上不会出现设置的样式规则
3)混合 携带多个参数
可以使用’;‘隔开参数,也可以使用’,‘隔开参数,不过’,'它可以解释为mixin参数分隔符或css列表分隔符。
如果编译器一旦发现 ‘;’ 存在,则会以 ‘;’ 作为参数的分隔符, ‘,’ 则会被当作 css 列表分隔符, 如果全部是 ‘,’, 则编译器会把 ‘,’ 作为参数分隔符
4)混合允许定义多个 相同的名字 不同的参数个数 的混合, 在应用时 less 会使用可以应用的所有属性
5)命名参数(Named Parameters)
在混合 传值的时候给 实参加上参数的名字,这是就不会按照传参的顺序来匹配了 ,而是按照参数的名字
6) @arguments 变量
@arguments 包含所有传过来的参数
//
7)可以携带 可变数量的参数 通过 ‘…’
@rest
emmmmmmmmm 不太会用 , 感觉应该和 javascript 里的差不多
//
8)模式匹配(Pattern-matching)
基于传入参数的不同 来改变混合的行为
除了变量之外的任何东西都只匹配与自身相等的值
.mix(@s, @color){…}
.class{
.mix(@switch, #ccc);
}
.mix(dark, @color){
color: darken(@color, 10%);
}
.mix(light, @color){
color: lighten(@color, 20%);
}
.mix(@_, @color){
opacity: 0.5;
}
@switch: dark;
.class{
.mix(@switch, #ccc);
}
.class{
color: darken(#ccc, 20%);
opacity: 0.5;
}
<template>
<div class="lessParMixins">
<div class="pardiv">
pardiv
</div>
<div class="testdiv">
检测带了参数的样式还能应用到它自身上嘛
</div>
<!-- 结论是不会应用到自身了 -->
<div class="samemixins">
混合名字一样,参数不一样
</div>
<div class="namepar">
命名 的参数
</div>
<div class="pattern">
Pattern-matching 模式匹配
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style lang="less" scoped>
@import './lessParMixins.less';
</style>
.lessParMixins{
.pardiv{
.testdiv(50px);
}
}
// 携带一个参数
// .testdiv(@radius){
// width: 300px;
// height: 300px;
// border: 1px solid fuchsia;
// border-radius: @radius;
// }
// 携带多个参数
.testdiv(@radius;@width: 350px;@height: 200px){
width: @width;
height: @height;
border: 1px solid fuchsia;
border-radius: @radius;
}
// 混合名字一样,参数不一样
.samemixins{
.setsame(red);
}
//没有被调用,因为没有携带参数
.setsame(){
background-color: aqua;
}
// 被调用了
.setsame(@color){
color: @color;
border-top: 2px solid black;
}
// 被调用了
.setsame(@color;@margin: 10px){
border-bottom: 2px solid violet;
margin: @margin;
}
// 没有被调用, 因为 @margin 和 @padding 没给值
.setsame(@color;@margin;@padding){
border-left: 2px solid khaki;
}
// 命名的参数
.namemix(@color: red; @margin: 30px; @radius: 20px){
color: @color;
margin: @margin;
border: 2px solid hotpink;
border-radius: @radius;
}
// 在混合 传值的时候给 实参加上参数的名字,这是就不会按照传参的顺序来匹配了 ,而是按照参数的名字
.namepar{
.namemix(@margin: 100px; @color: green);
.setblur(3px; 5px);
}
// @arguments 包含了传过来的所有参数值
.setblur(@x: 0; @y: 0;@blur: 5px; @color: #000){
box-shadow: @arguments;
}
// 模式匹配Pattern-matching
.setdifcolor(dark, @color){
color: darken(@color, 10%);
}
.setdifcolor(light, @color){
color: lighten(@color, 10%);
}
// 第一个参数为变量的话 都可以匹配到
.setdifcolor(@_, @color){
border: 2px solid saddlebrown;
}
@switch: light;
.pattern{
.setdifcolor(@switch, red);
}
混合函数(Mixins as Functions)
从一个混合里返回变量或者是混合 在一个混合里定义的 变量和混合 是可以在 调用者的 作用域内使用的,除非在 调用者的作用域内 重新定义了重名的变量(包括调用了另一个混合里有同样的重名的变量)
<template>
<div class="lessFunMix">
<div class="functiondiv">
混合函数
</div>
<div class="overwrite">
重写混合函数 里的变量值
</div>
<div class="mixInMix">
混合里定义的混合
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style lang="less" scoped>
@import './lessFunMix.less';
</style>
.lessFunMix{
.functiondiv{
.setWidth(6px);
// 在全局作用域 和 .functiondiv 的作用域 内都没有定义 @width ,却可以使用
// 是因为 在 .setWidth 混合里定义了
width: @width;
height: @width;
// @borderwidth 是混合里定义的经过处理的变量
border: @borderwidth solid hotpink;
}
.overwrite{
// 在调用的混合内定义了 @color 在调用者的作用域內也定义了 @color
// 调用者的作用域内的 @color 覆盖了 混合里的
.rewrite();
color: @color;
// @color: green;
// 在另一个混合里 同样定义了 @color
// 但使用的还是 调用者作用域内的 @color
.rewrite2();
// 当只有两个混合内 定义了 @color 时, 调用者作用域内 采用的是 第一个调用的混合里的 变量 @color
}
.mixInMix{
// 混合里定义的混合
// 定义在混合里的混合也是可以被调用者调用的
// 但在调用混合里的混合时 先要调用 父混合
.mixMix(300px);
.mixone(red);
}
}
.setWidth(@border: 4px){
@width: 300px;
@borderwidth: @border/2;
}
.rewrite(){
@color: red;
}
.rewrite2(){
@color: chocolate;
border: 2px solid chocolate;
}
.mixMix(@width){
width: @width;
height: @width;
margin-top: @width/5;
.mixone(@color){
border: 2px solid @color;
}
}
向混合里传入规则设置(Passing Rulesets to Mixins)
可以向混合里传入规则设置代码,规则集后的’()'是强制的
emm,我的理解是
1.直接使用变量的
定义一个变量里面存放的是规则集(样式规则),然后在调用时在变量后加上’()'即可(像调用混合一样)
2.混合的参数
混合传参数时,参数为一个变量,然后在混合内部调用这个变量,在变量后加上 ‘()’(就像调用混合一样), 调用者调用时传入的参数为规则集即可
作用域
1)规则集里可以使用调用者里定义的变量和混合
2)外部定义的同名变量 的优先级高于 调用者内部的同名变量定义
//外部定义的同名变量
@color: red;
//规则集
@setrule: {
color: @color;
}
.caller{
//此时的 color 的颜色是 red
@setrule();
//调用者内部定义的同名变量
@color: green;
}
3)引入不会改变规则集的作用域
4)解锁将会改变规则集的作用域
<template>
<div class="lessrule">
<div class="passruleset">
向混合里传入 规则设置
</div>
<div class="seecaller">
规则集里可以访问调用者里定义的变量
</div>
<div class="compOutCaller">
比较外部定义的同名变量 和调用者内部定义的同名变量 的优先级
</div>
<div class="reference">
引入不能改变 规则集的作用域
</div>
<div class="unlock">
解锁将会改变引入的规则
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style lang="less" scoped>
@import './lessrule.less';
</style>
// 外部定义的同名变量
@border: 3px solid green;
@width: 300px;
.lessrule{
.passruleset{
// 以混合的形式调用变量
@manyrule();
.setcolor({color: red; width: 300px;height: 400px;})
}
// 调用者
.seecaller{
@callerVar();
@color: teal;
}
/和官网给出的结果相反/
// 比较外部定义的同名变量 和调用者内部定义的同名变量 的优先级
.compOutCaller{
@callerSameVar();
@border: 1px solid red;
@width: 100px;
}
//官网的结果是 采用外部定义的同名变量 忽略调用者里的
/和官网给出的结果相反
//引入不会改变规则集的作用域
// .reference{
// 报错 Variable @colorvalue1 is undefined
// 因为@setrule2 是引入 @setrule1 ,所以 作用域一样,调用者是 .one > .two() 里未定义变量 @colorvalue1
// .one > .two();
// @setrule2();
// }
// 解锁
.unlock{
.one > .two();
@setrule2();
}
}
// 变量里存规则集
// 规则集后面必须加 分号
@manyrule: {
background-color: bisque;
border: 2px solid hotpink;
};
// 在混合里传参,然后调用这个参数
.setcolor(@color){
// 当在屏幕宽度 大于768px 时才有效
@media (min-width: 768px){
@color();
}
// 只要调用 .setcolor 就有效
// @color();
}
@callerVar: {
// 此时规则集里的 color 是 teal
// 采用了调用者里定义的变量
color: @color;
};
@callerSameVar: {
border: @border;
width: @width;
height: @width;
};
//引入不会改变规则集的作用域
// @setrule1: {
// background-color: @colorvalue1 - @colorvalue2;
// };
// .one{
// @colorvalue1: #000;
// .two{
// @colorvalue2: #111;
// @setrule2: @setrule1;
// }
// }
// 解锁将会改变规则集的作用域
@setrule1: {
background-color: @colorvalue1 + @colorvalue2;
};
.one{
.two{
@colorvalue1: #000;
@colorvalue2: #111;
@setrule2: @setrule1;
}
}
混合守卫(Mixin Guards)
在混合执行的时候给混合加一个条件,类似于 if else 和 @media的查询特性规范
.mix(@a) when (@a < 100){
样式规则
}
当 @a 的值小于100 时才执行
在保护中可用的比较操作符的完整列表是:
>,>=,=,=<,<
此外,关键字true是惟一真实的值,这使得这两个混合语句等价:
selector(@a) when (@a) {}
selector(@a) when (@a = true) {}
还可以使用逻辑运算符
and not , 三种分别是 与 非 或
<template>
<div class="lessguardmixins">
<div class="guardmixins">
守卫混合
</div>
<div class="guardmixins2">
守卫混合2
</div>
<div class="guardmixins3">
守卫混合3
</div>
<div class="guardmixins4">
守卫混合4
</div>
<div class="guardmixins5">
守卫混合5
</div>
<div class="guardmixins6">
守卫混合6
</div>
<div class="cssguard">
cssguard
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style lang="less">
@import './lessguardmixins';
</style>
.lessguardmixins{
.guardmixins{
// 执行第一个 .setcolor 和第三个 .setcolor
.setcolor(#dfd);
}
.guardmixins2{
// 执行第二个 .setcolor 和第三个 .setcolor
.setcolor(#954);
}
.guardmixins3{
.truecom(true);
// 不执行
// .truecom(4);
}
.guardmixins4{
// 执行第一个 .compone
.compone(300px);
// 执行第二个 .compone
// .compone(450px);
}
.guardmixins5{
// 执行的是第二个 .comptwo
.copmtwo(40;50);
// 执行的是第一个 .comptwo
.copmtwo(200;10);
}
.guardmixins6{
// 会执行 .logicaland
// .logicaland(150);
// 不会执行 .logicaland
.logicaland(200);
// 会执行 .logicalor
// .logicalor(1,2);
// .logicalor(-3,-4);
// 不会执行 .logicalor
.logicalor(-1,1);
// 不会执行 .logicaknot
// .logicalnot(300);
// 会执行 .logicaknot
.logicalnot(100);
}
@csscolor: red;
// css 守卫
.cssguard when (@csscolor = red) {
color: @csscolor;
}
}
.setcolor(@color) when (lightness(@color) >= 50%){
background-color: @color;
}
.setcolor(@color) when (lightness(@color) < 50%){
color: @color;
}
.setcolor(@color){
margin-top: 20px;
border: 3px solid red;
}
// 只有 @a 的值为 true 时才会渲染,其他值都不行
// .truecom(@a) when (@a) {
// background-color: aqua;
// }
// 和上面的是一样的效果
.truecom(@a) when (@a = true) {
background-color: aqua;
}
.compone(@b) when (@b < 400px) {
width: @b;
height: @b;
border: 1px solid greenyellow;
}
.compone(@b) when (@b >= 400px) {
width: @b * 2;
height: @b * 2;
border: 1px solid green;
}
.copmtwo(@c;@d) when (@c >= @d) {
color: darkblue;
}
.copmtwo(@c;@d) when (@c < @d) {
color: salmon;
}
// 条件必须都满足才会执行
.logicaland(@e) when ((@e > 100) and (@e < 200)) {
background-color: bisque;
}
// 只要条件满足一个即可执行
.logicalor(@f;@g) when (@f > 0),(@g <0) {
color: hotpink;
}
// 满足条件的相反条件才会执行
.logicalnot(@h) when not(@h >200) {
background-color: aquamarine;
}