vue项目妙用scss mixin实现样式全编程式风格
对于vue项目的样式部分,有多种风格,这将取决于框架搭建人员的设计思路。本人在vue项目中以使用sass(scss)为主,经探索,现研究出一种封装方案,可以快速的进行样式开发。这种方案的优点是:极大节省样式代码的行数,简洁。原先需要4-5行的代码仅需一行即可,即便是极端情况下也不会增加代码行数。样式代码被分成了几类,清晰易读。可扩展性强,要增加样式只需给mixin增加参数。可维护性强,很...
方案介绍:优点
对于vue项目的样式部分,有多种风格,这将取决于框架搭建人员的设计思路。本人在vue项目中以使用sass(scss)为主,经探索,现研究出一种封装方案,可以快速的进行样式开发。这种方案的优点是:
- 极大节省样式代码的行数,简洁。原先需要4-5行的代码仅需一行即可,即便是极端情况下也不会增加代码行数。
- 样式代码被分成了几类,清晰易读。
- 可扩展性强,要增加样式只需给mixin增加参数。
- 可维护性强,很容易定位并对样式进行增删改的操作。
·
来看一些案例
现在我们来看一个例子,假设我们需要设置一个元素的文本样式为如下效果:
font-size: 14px;
font-weight: bold;
color: #fff;
line-height: 20px;
text-align: center;
采用该方案,将只需一行代码:
@include font($s: 14px, $lh: 20px, $c: #fff, $w: bold, $ta: center);
你可能已经发现了,这相当于是编程式的样式书写风格
,我们将要写的样式的值作为参数传入了mixin。
一个问题是:如果我不需要那么多样式呢,比如我只需要font-size值和color值,这也不难得到:
@include font($c: #02172e, $s: 14px);
可以看出,我们可以传递的参数个数和顺序
也是不固定的,即可变参数
,这大大增加了灵活性。这种可变参数如何实现呢,只需要在mixin的定义中设置默认值
为null即可。现在我们放出完整地mixin定义:
@mixin font($s: null, $c: null, $lh: null, $w: null, $ta: null) {
font-size: $s;
font-weight: $w;
color: $c;
line-height: $lh;
text-align: $ta;
}
假设你还需要增加字体的设置,那么你只需要在font的mixin定义中增加一个参数,像这样:
@mixin font($s: null, $c: null, $lh: null, $w: null, $ta: null, $f: null) {
font-family: $f;
font-size: $s;
font-weight: $w;
color: $c;
line-height: $lh;
text-align: $ta;
}
现在你可以像其他参数一样传递font-family的值了:
@include font($c: #02172e, $s: 14px, $f: Serif);
项目中的实际效果
现在,你可能还心存怀疑,这种封装方案在实际开发中究竟好不好用,究竟能够多大程度上提高开发效率。现在我将附上某个完整地vue组件的代码,以便于你进行评估:
<template>
<div class="previous-detail">
<div class="previous-detail-img"></div>
<div class="previous-detail-info">
<div class="previous-detail-info-title">作品名称</div>
<div class="previous-detail-info-content">
<div class="previous-detail-info-content-item">作者:张三</div>
<div class="previous-detail-info-content-item">参赛赛区:天津赛区</div>
<div class="previous-detail-info-content-item">类别:A工作</div>
<div class="previous-detail-info-content-item">院校:南京大学</div>
<div class="previous-detail-info-content-item">指导老师:李四</div>
<div class="previous-detail-info-content-item">获得奖项:金奖</div>
</div>
</div>
<div class="previous-detail-media"></div>
</div>
</template>
<script>
export default {
name: "",
components: {},
props: {},
data() {
return {};
},
methods: {}
};
</script>
<style lang="scss" scoped>
.previous-detail {
@include padding($p: 30px 120px 106px);
&-img {
@include box($h: 532px);
@include bg($c: #fff);
@include border($b: 1px solid $border-color-main, $bra: 4px);
}
&-info {
@include margin($mt: 20px);
@include padding($p: 20px);
@include box($h: 92px);
@include bg($c: #fff);
@include border($b: 1px solid $border-color-main, $bra: 4px);
&-title {
@include margin($mb: 10px);
@include font($s: 16px, $lh: 22px, $c: $color-main-6, $w: bold);
}
&-content {
@include box($w: 100%);
@include flex;
@include font($s: 14px, $lh: 20px, $c: $color-main);
&-item {
@include margin($ml: 60px);
&:first-child {
@include margin($ml: 0);
}
}
}
}
&-media {
@include margin($mt: 20px);
@include box($h: 286px);
@include bg($c: #fff);
@include border($b: 1px solid $border-color-main, $bra: 4px);
}
}
</style>
我的mixin定义文件
现在,我们来看看mixin定义文件长什么样子,可以按哪些类型进行分类:
@mixin flex($v: null, $h: null, $w: null, $a: null) {
display: flex;
justify-content: $h;
align-items: $v;
flex-wrap: $w;
align-content: $a;
}
@mixin font($s: null, $c: null, $lh: null, $w: null, $ta: null) {
font-size: $s;
font-weight: $w;
color: $c;
line-height: $lh;
text-align: $ta;
}
@mixin box($h: null, $w: null, $d: null, $o: null, $p: null) {
position: $p;
display: $d;
width: $w;
height: $h;
overflow: $o;
}
@mixin margin($mt: null, $mb: null, $ml: null, $mr: null, $m: null) {
margin-top: $mt;
margin-bottom: $mb;
margin-left: $ml;
margin-right: $mr;
margin: $m;
}
@mixin padding($pt: null, $pb: null, $pl: null, $pr: null, $p: null) {
padding-top: $pt;
padding-bottom: $pb;
padding-left: $pl;
padding-right: $pr;
padding: $p;
}
@mixin border(
$bt: null,
$bb: null,
$bl: null,
$br: null,
$bs: null,
$bc: null,
$bra: null,
$bsd: null,
$b: null
) {
border: $b;
border-top: $bt;
border-bottom: $bb;
border-left: $bl;
border-right: $br;
border-collapse: $bc;
border-spacing: $bs;
border-radius: $bra;
box-shadow: $bsd;
}
@mixin bg(
$c: null,
$s: null,
$img: null,
$p: null,
$r: null,
$cl: null,
$o: null,
$bg: null
) {
background: $bg;
background-color: $c;
background-size: $s;
background-image: $img;
background-position: $p;
background-repeat: $r;
background-clip: $cl;
background-origin: $o;
}
@mixin pos($p: null, $l: null, $r: null, $t: null, $b: null, $z: null) {
position: $p;
top: $t;
bottom: $b;
left: $l;
right: $r;
z-index: $z;
}
// 包含transition和animate系列,
@mixin animate($t: null) {
transition: $t;
}
@mixin transform(
$sx: null,
$sy: null,
$s: null,
$tx: null,
$ty: null,
$t: null
) {
transform: scaleX($sx);
transform: scaleY($sy);
transform: scale($s);
transform: translateX($sx);
transform: translateX($sy);
transform: translate($s);
}
@mixin other($c: null) {
cursor: $c;
}
其他配套设置
为了最大程度的利用好这套方案,你还可以将其他scss配置技巧利用上,他们包括:
- 尽量统一风格,避免混杂。
- 使用scss全局变量和全局mixin。可以在任何组件中而不用再引入,这在上面的案例中有所体现。在vue项目中则需要在vue.config.js中配置css选项,像下面这样,具体可参考官方文档:
module.exports = {
// 这里配置scss的全局变量,这些变量在任何一个组件中无需引入可直接使用
css: {
loaderOptions: {
sass: {
prependData: `
@import "~@/styles/variables.scss";
@import "~@/styles/mixin.scss";
`
}
}
}
}
- 将mixin的优先级提到很高。像上面那样,mixin的优先级仅次于全局变量(variables.scss中定义),这样除了这两者之外的其他文件都可以使用mixin了。
以上仅仅是一家之言,如果你有更好的方案或者有自己的风格,欢迎交流!
更多推荐
所有评论(0)