vue项目妙用scss 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了。

以上仅仅是一家之言,如果你有更好的方案或者有自己的风格,欢迎交流!

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值