在我们写前端项目时,经常会需要对移动端和pc端进行响应式展示,我们会用到以下的媒体查询进行打断点写样式,如果不进行封装会在css文件里出现大量的判断分支,不容易阅读和维护。
@media (min-width: 450px) and (max-width: 680px){
width:680px;
}
此时可以使用scss或者less等预编译器,将打断点的代码进行封装,封装代码如下
// 屏幕宽度媒体查询打断点的逻辑
$breakpoints: (
//手机端
phone: 1360px,
//平板端
pad: (1361px, 1600px),
//pc端
pc: (1601px, 1660px)
);
// 检查传入的断点名称是否存在于断点映射中
@function check-breakpoint($breakname) {
// 检查传入的断点名称是否存在于断点映射中
// 参数:
// $breakname: 需要检查的断点名称
// 返回值:
// 如果断点名称存在,则返回 true,否则抛出错误
@if map-has-key($breakpoints, $breakname) {
@return true;
} @else {
@error "The breakpoint name #{$breakname} does not exist in the breakpoint map.";
}
}
@mixin responseTo($breakname) {//使用@mixin混入暴露一个类似js函数一样的函数
// 根据传入的断点名称应用相应的媒体查询
// 参数:
// $breakname: 断点名称
// 功能:
// 如果断点名称存在,则根据该断点的值生成媒体查询,可以在媒体查询内部通过 @content 添加样式
@if check-breakpoint($breakname) {
$bp: map-get($breakpoints, $breakname);
@if type-of($bp) == "list" {
// 如果断点是一个列表,则处理最小宽度和最大宽度
// 大于等于$breakpoints数组的第一项并且小于等于$breakpoints数组的第二项
@media (min-width: nth($bp, 1)) and (max-width: nth($bp, 2)) {
@content;
}
} @else {
// 如果断点不是一个列表,只处理最小宽度
// 小于等于$breakpoints这个变量
@media (max-width: $bp) {
@content;
}
}
}
}
在业务组件里就可以引用这个混入,并进行样式设置,此时我们就可以单独另外写一个style标签,并注意要把这些打断点的代码放到最下面,否则会被覆盖
<style lang="scss" scoped>
// 打断点的逻辑单独写
@import '@/styles/screenWidth.scss'; //屏幕宽度媒体查询打断点的逻辑
@include responseTo(phone) {
.history-content {
width: 1320px;
}
}
@include responseTo(pad) {
.history-content {
width: 1540px;
}
}
@include responseTo(pc) {
.history-content {
width: 1620px;
}
}
</style>
如何理解混入@mixin混入函数
1.直接使用
// 定义一个名为flex的混入
@mixin flex{
display:flex;
justify-content:center;
align-items:center;
}
.header{
width:100%;
@include flex;//引用这个混入
}
//转义之后相当于合并这两个css
// .header{
// width:100%;
// display:flex;
// justify-content:center;
// align-items:center;
// }
2.传参的形式使用
//如果两个类引用这个混入,但是存在差异如何传参一样的使用混入
@mixin flex ($layout) {
display:flex;
justify-content:$layout;
align-items:$layout;
}
//使用
.nav {
width:100%;
@include flex(start);//引用这个混入
}
.header{
width:100%;
@include flex(center);//引用这个混入
}
//编译之后
// .nav{
// display:flex;
// justify-content:center;
// align-items:center;
// }
// .header{
// width:100%;
// display:flex;
// justify-content:start;
// align-items:start;
// }
3.使用传参的时候不仅仅可以传递参数,也可以把内容传过去
// 类似于vue中的插槽
@mixin flex ($layout) {
display:flex;
justify-content:$layout;
align-items:$layout;
@content;//相当于插槽<slot/>
}
//使用
.nav {
width:100%;
@include flex(start){
width:100%;
height:50%;
}
}
.header{
width:100%;
@include flex(center){
height:50px;//这里写的东西都会在@content这个插槽位置展示出来
}
}
//编译之后
// .nav{
// display:flex;
// justify-content:center;
// align-items:center;
// width:100%;
// height:50px;
// }
// .header{
// width:100%;
// display:flex;
// justify-content:start;
// align-items:start;
// height:50px;
// }