• 技术文章 >web前端 >css教程

    浅析CSS中的5种设计模式,聊聊vue项目中CSS目录代码的作用

    青灯夜游青灯夜游2022-02-08 10:30:49转载103
    本篇文章带大家聊聊CSS中的5种设计模式,并介绍一下vue3项目中个CSS style目录中的代码作用,希望对大家有所帮助!

    工作了几年,发现在项目中经常存在如下问题:

    因为这些不良的编程习惯,导致了项目越来越难以维护,程序性能越来越低,大大降低了日常的工作效率以及提高了公司的开发成本。

    下面就以CSS在Vue3项目中的架构为切入点,通过减少CSS代码的冗余度和增强CSS代码的维护性、扩展性来提高我们的编程能力和项目架构能力。

    技术储备:

    CSS的设计模式

    在学习CSS架构之前,我们先简单看一下常见的5种CSS设计模式,这些设计模式都为我们的CSS架构提供了一定的开发思路。

    1.OOCSS模式

    OOCSS(Object-Oriented CSS)字面意思是面向对象的CSS,在开发中它有如下的规范约定

    # bad
    # 1.匹配效率低,影响css性能
    # 2.和html耦合度高,维护性和扩展性低
    .container-list ul li a {}
    
    <div class="container-list">
      <ul>
        <li>
          <a>...</a>
        </li>
      </ul>
    </div>
    
    
    # good
    .container-list .list-item {}
    
    <div class="container-list">
      <ul>
        <li>
          <a class="list-item">...</a>
        </li>
      </ul>
    </div>
    .label {
      # 公共代码
    }
    .label-danger {
      # 特定代码
    }
    .label-info {
      # 特定代码
    }
    <div>
      <p class="label label-danger"></p>
      <p class="label label-info"></p>
    </div>

    2.BEM模式

    BEM 是进阶版的OOCSS,是一个分层系统,它把我们的网站分为三层,这三层正好对应着 BEM 三个英文单词的简写 block, element, modifier,分为为 块层、元素层、修饰符层。

    把 BEM 体现到代码上,我们需要遵循三个原则:

    <div class="menu">
      <div class="menu__tab menu__tab--style1">tab1</div>
      <div class="menu__tab menu__tab--style1">tab2</div>
    </div>

    但是,由于两个下划线__和两个破折号--在实际开发中不是那么的顺手,影响开发效率,不过要严格控制CSS命名规范的话,这无疑是一个好的选择。并且在写CSS的时候我们可以通过Sass的混合指令封装一个BEM.scss文件来减少类名的输入以及增强CSS结构

    3.SMACSS模式

    BEM 简单的三层分法,在应对小中型网站没有问题,但是去应对复杂网站的样式可能就比较困难了,我们需要寻求一个更好的办法。

    SMACSS(Scalable and Modular Architecture for CSS)是要编写模块化、结构化和可扩展的 CSS。它对项目中的CSS分为五大类

    4.ITCSS模式

    ITCSS(Inverted Triangle Cascading Style Sheets)可以翻译为"倒三角CSS",它基于分层的概念把我们项目中的样式分为七层

    5.ACSS模式

    ACSS(Atomic CSS)翻译为"原子化CSS",是一种 CSS 的架构方式,它倾向于小巧且用途单一的 class,并且会以视觉效果进行命名。是一个不强调逻辑,而更侧重表现的一门所见即所得的语言,它出现的背景是——前端组件化时代的到来,各个组件的CSS可以做到互相独立,互不影响。因此就有这样的代码出现

    <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">按钮</button>

    目前市场上比较成熟的ACSS库有:Tailwind CSSWindi CSS

    ACSS的优点

    ACSS的缺点

    综上,我们可以看出ACSS 劣处是非常小的,而好处有非常大,没有理由在项目中不适用。下面我们通过使用BEM、ITCSS和ACSS模式打造一套CSS架构方案。

    项目搭建

    创建vue3项目和安装依赖

    CSS目录结构展示与说明

    src
      style
        acss         # 存放boder、margin、padding等基于acss模式的代码
        base         # 存放元素(input、p、h1等)的重置样式
        settings     # 存放项目统一规范的文本颜色、边框颜色等变量
        theme        # 存放项目特定主题下的元素样式
        tools        # 存放封装好的mixin(混合指令)和function(函数)样式
        global.scss  # 需要项目全局引用的CSS
        index.scss   # 需要Vue文件引用的CSS

    1.关于mixin(混合指令)和function(函数)的区别

    /* mixin */
    @mixin center-translate($direction: both) {
      position: absolute;
      @if $direction == both {
        top: 50%;
        left: 50%;
        transform: translate3d(-50%, -50%, 0);
      } @else if $direction == horizontal {
        left: 50%;
        transform: translate3d(-50%, 0, 0);
      } @else if $direction == vertical {
        top: 50%;
        transform: translate3d(0, -50%, 0);
      }
    }
    
    /* function */
    @function am($module, $trait: false) {
      @if $trait==false {
        @return '[am-' + $module + ']';
      } @else {
        @return '[am-' + $module + '~="' + $trait + '"]';
      }
    }

    2.关于style/global.scss和style/index.scss

    # style/global.scss
    @import "./settings/var.scss";
    
    # style/settings/var.scss
    $background-color-primary: #F1F1F1;
    $background-color-secondary: $color-white;
    
    # style/acss/color.scss
    @each $style in (primary $background-color-primary, secondary $background-color-secondary) {
      [bg-#{nth($style, 1)}] {
        background-color: #{nth($style, 2)};
      }
    }
    // 根目录下:vue.config.js
    module.exports = {
      css: {
        loaderOptions: {
          scss: {
            // @/ 是 src/ 的别名
            // 注意:在 sass-loader v8 中,这个选项名是 "prependData"
            prependData: `@import "@/style/global.scss";`
          },
        }
      }
    }
    // src/main.js
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import './style/index.scss'
    
    createApp(App).use(router).mount('#app')

    下面简单分析和演示下各个style目录中的代码作用。

    1.acss

    该目录主要是定义一些简单的border、color、font-size、margin和padding等代码

    /* style/acss/border.scss */
    @for $i from 1 through 100 {
      [radius#{$i}] { 
        border-radius: #{$i}Px;
        overflow: hidden;
      }
    }
    [circle] {
      border-radius: 50%;
    }
    
    /* style/acss/font-size.scss */
    @for $i from 12 through 30 {
      [fz#{$i}] { 
        font-size: #{$i}px;
      }
    }

    使用acss代码

    <div class="container">
      <div class="item" radius20>border-radius: 20px;</div>
    </div>
    <div class="container">
      <div class="item" circle>border-radius: 50%;</div>
    </div>
    <div class="container">
      <div class="item" fz30>font-size: 30px;</div>
    </div>

    2.base

    该目录主要是重置项目中一些元素的默认样式,比如input、hn、p、a等元素

    /* style/base/form.scss */
    input {
      padding: 0;
      outline: none;
      border: none;
    }
    
    /* style/base/link.scss */
    a {
      color: #ccc;
      text-decoration: none;
    }

    3.settings

    该目录是定义全局的、项目统一规范的文本颜色、边框颜色等变量

    /* style/settings/var.scss */
    /* 主题色调 */
    $color-primary: #FF5777;
    $color-white: #FFFFFF;
    
    /* 文本色调 */
    $color-text-primary: green;
    $color-text-secondary: #FF4533;
    $color-text-tertiary: $color-white;
    $color-text-quaternary: $color-primary;
    
    /* 盒子边框色调 */
    $border-color-base: #E5E5E5;
    
    /* 盒子背景色色调 */
    $background-color-primary: #F1F1F1;
    $background-color-secondary: $color-white;
    $background-color-tertiary: $color-primary;
    
    
    /* 盒子默认边框 */
    $border-width-base: 1Px !default;
    $border-style-base: solid !default;
    $border-base: $border-width-base $border-style-base $border-color-base !default;

    4.theme

    该目录定义项目各个主题下相关模块的样式

    /* style/theme/default.scss */
    [data-theme='default'] .header {
      background: #FF5777;
    }
    [data-theme='default'] .footer {
      color: #FF5777;
      border: 2px solid #FF5777;;
    }
    
    /* style/theme/cool.scss */
    [data-theme='cool'] .header {
      background: #409EFF;
    }
    [data-theme='cool'] .footer {
      color: #409EFF;
      border: 2px solid #409EFF;;
    }

    我们通过添加html元素上的data-theme属性和值,即可达到项目主题的变换

    <!-- Theme.vue -->
    <template>
      <div class="theme">
        <div class="header"></div>
        <div class="theme__set">
          <div class="set set--default" @click="changeTheme('default')"></div>
          <div class="set set--cool" @click="changeTheme('cool')"></div>
        </div>
        <div class="footer"></div>
      </div>
    </template>
    
    <script>
    export default {
      name: "Theme",
      setup() {
        const changeTheme = (theme = 'default') => {
          window.document.documentElement.setAttribute("data-theme", theme);
        }
        return {
          changeTheme
        }
      }
    }
    </script>
    
    
    <!-- Other.vue -->
    <template>
      <div class="about">
        <div class="header"></div>
        <div class="about-title">This is an about page title</div>
        <div class="about-content">This is an about page content</div>
        <div class="footer"></div>
      </div>
    </template>

    5.tools

    该目录是定义一些全局的公共mixin和function,目前这块内容比较完善就是SassMagic,感兴趣的可以点进来看一下。下面简单看一下BEM模式的应用

    $elementSeparator: '__';
    $modifierSeparator: '--';
    
    // 判断`$selector`中是否包含BEM中Modify
    @function containsModifier($selector) {
      $selector: selectorToString($selector);
      @if str-index($selector, $modifierSeparator) {
        @return true;
      } @else {
        @return false;
      }
    }
    
    // 将`$selector`转换成String
    @function selectorToString($selector) {
      $selector: inspect($selector); //cast to string
      $selector: str-slice($selector, 2, -2); //remove brackets
      @return $selector;
    }
    
    // @param  {String}  $selector
    @function getBlock($selector) {
      $selector: selectorToString($selector);
      $modifierStart: str-index($selector, $modifierSeparator) - 1;
      @return str-slice($selector, 0, $modifierStart);
    }
    
    @mixin b($block) {
      .#{$block} {
        @content;
      }
    }
    
    @mixin e($element) {
      $selector: &;
      @if containsModifier($selector) {
        $block: getBlock($selector);
        @at-root {
          #{$selector} {
            #{$block + $elementSeparator + $element} {
              @content;
            }
          }
        }
      } @else {
        @at-root {
          #{$selector + $elementSeparator + $element} {
            @content;
          }
        }
      }
    }
    
    @mixin m($modifier) {
      @at-root {
        #{&}#{$modifierSeparator + $modifier} {
          @content;
        }
      }
    }
    
    // @param {string} $block - BEM中的Block
    // <div class="block">
    //   <div class="block__header">
    //     <div class="block__header--css"></div>
    //   </div>
    // </div>
    
    //  @include b(block) {
    //    background: red;
    //    @include e(header){
    //       font-size: 14px;
    //       @include m(css) {
    //         font-size: 18px;
    //      }
    //   };
    // }
    
    // 编译后
    // .block {
    //   background: red;
    // }
    // .block__header {
    //   font-size: 14px;
    // }
    // .block__header--css {
    //   font-size: 18px;
    // }

    尾声

    暂时先讲这么多,更多内容可以关注下这个仓库vue3-css-architecture,会持续更新完善,补充更多的mixin、function,以及在项目中的应用。

    (学习视频分享:css视频教程

    以上就是浅析CSS中的5种设计模式,聊聊vue项目中CSS目录代码的作用的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    上一篇:深入浅析css中的层叠上下文 下一篇:鲜为人知!用css做极光效果

    相关文章推荐

    • rgba是css3新增的属性吗• css3怎样设置一行显示多少个字符• css3怎样用rotate设置旋转角度• css3设置动画匀速的属性单词是哪个• 值得收藏css预处理器scss的使用总结• 聊聊利用CSS实现九宫格布局的几种方法!

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网