起因
最近在做移动端官网开发,决定采用vw做响应式,但设计图是375px宽度,所以需要每块元素的px单位转为vw单位*
JS还好说,通过函数很容易就封装了
function px2vw(value) {
return (value / 375) * 100 + "vw";
}
但是在Less的语法呀,又该如何去封装喃?
解决方案
以设计稿375px*667px
为例,兼容处理尺寸为宽度50px*50px的div元素
变量
@designWidth: 375;
div {
width: unit((50/ 375 * 100), vw); // 13.33333333vw
height: unit((50 / 375 * 100), vw); // 13.33333333vw;
}
这样使用虽然能够达到所需的效果,但是并不符合复用的原则
混入
// unit.scss
@designWidth: 375;
.px2vw(@name, @px) {
@{name}: unit((@px / @designWidth * 100), vw);
}
// test.less
@import "unit.less";
div {
.px2vw(width, 50); // 13.33333333vw
.px2vw(height, 50); // 13.33333333vw
}
混入解决了复用的问题,但又引入一个新问题,transform: translateX(50px);
、margin: 50px 30px;
此类语法并不能解决
当然创建这些属性的专属混入就可以了
.transformTranslateX(@px) {
transform: translateX(unit((@px / @designWidth * 100), vw));
}
但这并不符合偷懒原则
混入+返回值
在less文档中有详细的语法介绍,这里就不班门弄虎了
// unit.scss
@designWidth: 375;
.px2vw(@px) {
@result: unit((@px / @designWidth) * 100, vw);
}
// test.less
@import "unit.less";
div {
width: .px2vw(50) []; // 13.33333333vw
height: .px2vw(50) []; // 13.33333333vw
}
这样偷懒原则也符合了,但但但是,末尾要加[]
很丑陋,不符合审美原则!!!
@functions
使用这种方式首先需要修改lessjavascriptEnabled
配置,开启less文件内联 JavaScript
以vue-cli5为例,修改vue.config.js配置文件
module.exports = {
css: {
loaderOptions: {
less: {
lessOptions: {
javascriptEnabled: true,
},
},
},
},
};
下面才能开始使用
(function () {
let designWidth = 375;
this.px2vw = function (px) {
return (px / designWidth) * 100 + "vw";
};
})();
// unit.scss
.initFun(){
@functions: ~`(function () {
let designWidth = 375;
this.px2vw = function (px) {
return (px / designWidth) * 100 + "vw";
};
})();`;
}
.initFun();
// test.less
@import "unit.less";
div {
width: ~`px2vw(50)`; // 13.33333333vw
height: ~`px2vw(50)`; // 13.33333333vw
}
感觉更丑陋了,有木有!!!
刚好less也弃用了该语法,经测试在"less": "^4.1.3"
中还是能使用
注意看图中替换方案,因为这将是本文的主角
@plugin(推荐)
老规矩,想了解更多语法,请看less文档
首先定义unit-plugin.js
// unit-plugin.js
module.exports = {
install: function (less, pluginManager, functions) {
functions.add("px2vw", function (param) {
return (param.value / 375) * 100 + "vw";
});
},
};
// test.less
@plugin "./unit-plugin.js";
div {
width: px2vw(50); // 13.33333333vw
height: px2vw(50); // 13.33333333vw
}
完美解决问题了!!!
下面不属于本文的主要内容,可以略过。。。
项目中
@plugin使用方案有两种,还是以vue-cli5为例
全局less文件(推荐)
定义全局less文件
// global.less
@plugin "~@/assets/css/less-plugin.js";
// vue.config.js
module.exports = {
// 设置全局less文件
pluginOptions: {
"style-resources-loader": {
preProcessor: "less",
patterns: [path.resolve(__dirname, "src/assets/css/global.less")],
},
},
}
具体如何全局引入less文件根据当前环境有不同的解决方案
定义插件
// vue.config.js
module.exports = {
css: {
loaderOptions: {
less: {
lessOptions: {
plugins: [
new (class {
constructor() {}
install(less, parser, functions) {
functions.add("px2vw", function (param) {
return (param.value / 375) * 100 + "vw";
});
}
})(),
],
},
},
},
},
};