zoukankan      html  css  js  c++  java
  • 记一次小程序样式优化重构

    上周花了 3 天的时间和老大一起重构了一下小程序的样式开发,虽然说在开发的过程中遇到了一些问题,但是最终减少了不少样式代码,同时功能上也更加强大。进一步来说,如果在后面我们的小程序用户想要自己定制化主题,也可以很快的实现。

    全局样式开发

    之前的小程序开发中,我们全方面使用了 Component 构造小程序组件以及页面(页面也可以使用 Component 构造器来编写)。当然一方面是因为小程序 Component 的开发体验非常好,拥有类似于 vue mixin, watch 的 behaviors 和 observers,比 Page 构造器强大了很多。另一方面,对于业务较重的小程序来说, Component 也有性能优势。可以参照 滴滴开源小程序框架Mpx 中的 Page与Component setData性能对照。

    在开发过程中,有很多样式是可以复用的。如果在之前开发中经常使用 Bootstrap 之类的 ui 库,那么你就会习惯使用这种库的 utilities 类。但是默认情况下,自定义组件的样式只受到自定义组件 wxss 的影响。不会受到全局样式 app.wxss 的影响。所以我们只能通过增加 @import 语法来辅助各个组件进行开发。

    @import "xxx.css";

    如果你使用 css 预处理器来辅助小程序开发的话,可能就需要通过 gulp-insert 为编译出来的 wxss 文件前置添加该语句。请注意: 之所以 @import 需要前置,是因为 @import 语法会把引入的样式按照导入的位置来生效,也就是说,按照 CSS 同等权重看先后的规则来说,如果把 @import 放在中间位置,前面位置定义的样式可能会被 @import 给覆盖掉。

    小程序全局样式

    当然,小程序基础库版本在 2.2.3 以上就支持了addGlobalClass 配置项,即在 Component 的 options 中设置 addGlobalClass: true 。

    Component({
      options: {
        addGlobalClass: true
      }
    })

    该配置项目表示页面级别的 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面。也就是说我们可以用该配置替代之前的每个组件的 @import。只要在 app.wxss 上导入 CSS 样式即可,同时我们可以在页面上对组件内部的样式进行修改。不过需要说明的是: 该配置并不影响父子组件间的样式。各个子组件只受到 app.wxss 和页面的样式的侵入。小程序开发基本上以页面为单位,所以这个配置是非常适合开发的。不过在之前的开发中并没有在意过这个配置。

    组件样式隔离

    当然了,在后面的版本 2.6.5 中,微信小程序也提供了更为详细的隔离选项 styleIsolation 。

    Component({
      options: {
        styleIsolation: 'isolated'
      }
    })
    • isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值)。
    • apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面。
    • shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。(这个选项在插件中不可用)。

    styleIsolation 浅析

    如果大家不想了解太多,只想使用的话, 简短来说:

    大家在组件中直接使用 apply-shared,如果当前的 Component 构造器应用于页面,那么不要配置隔离选项即可。其余的隔离选项都是基本没什么用的。

    styleIsolation 详解

    isolated 等同于什么都不干,设置不设置一般没有区别,所以可以当该配置项目不存在。

    apply-shared 等同于addGlobalClass: true,也是最有用的配置项 。

    shared 最复杂,在子组件设置了样式,不但会影响自身和页面(同时包括了其他设置了apply-shared 或 shared 的自定义组件),同时呢,又会被页面样式和其他设置了 shared 的组件样式影响。在我使用该功能的过程中,我认为,这个配置项千万不要在组件中去使用,除非你“疯了”。

    但是不介绍这个配置项目又不行,因为当你使用 Component 去构建页面时候,该页面的配置项目默认就是 shared。这是因为页面又需要全局样式,又需要影响其他设置了apply-shared 或 shared 的自定义组件。

    不过可以放心的是: 小程序样式隔离是以页面为单位,不会影响全局样式,即使当前页面你有组件使用了以 shared 影响了当前页面。跳转到下一个页面中,不会出现问题。所以我们基本上按照上面的设置即可。

    针对于页面级别的 Component 还有几个额外的样式隔离选项可用:

    • page-isolated 表示在这个页面禁用 app.wxss ,同时,页面的 wxss 不会影响到其他自定义组件;
    • page-apply-shared 表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式不会影响到其他自定义组件,但设为 shared 的自定义组件会影响到页面;
    • page-shared 表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式会影响到其他设为 apply-shared 或 shared 的自定义组件,也会受到设为 shared 的自定义组件的影响。

    基本上这些配置都会让页面上禁用 app.wxss,所以在开发中并不使用。大家如果有需求,可以自行研究。

    从小程序基础库版本 2.10.1 开始,也可以在页面或自定义组件的 json 文件中配置 styleIsolation (这样就不需在 js 文件的 options 中再配置)。例如:

    {
      "styleIsolation": "isolated"
    }

    其他样式配置功能

    诸如 外部样式类) 和 引用页面或父组件的样式) 这些功能,大家也可酌情学习使用。不过有了组件样式隔离之后,这些功能可能就有些鸡肋,我可以直接通过页面的样式控制组件内部的样式。而且外部样式类功能需要父组件直接提供样式,不会被 app.wxss 所影响。

    在样式隔离功能使用的情况下,我们可以大幅度减少各个组件的代码。并且让整个小程序内部更加干净整洁,可重用性更高。同时我们的主题色等全局配置都可以通过修改 app.wxss 来修改。

    CSS var 定制主题

    var 功能简单描述

    如果当年 CSS 预处理器变量对于我来说是开启了新世界的大门,那么 CSS 变量这个功能对于无疑就是晴天霹雳。

    // 在 body 选择器中声明了两个变量
    body {
      --primary-color: #7F583F;
      --secondary-color: #F7EFD2;
    }
    
    /** 同一个 CSS 变量,可以在多个选择器内声明。优先级高的会替换优先级低的 */
    .a {
      --primary-color: #FFF;
      --secondary-color: #F4F4F4;
    }
    
    /** 使用 CSS 变量 */
    .btn-primary {
      color: var(--primary-color)
    }

    在前端的领域中,标准的实现总是比社区的约定要慢的多,前端框架最喜欢的 $ 被 Sass 变量用掉了。而最常用的 @ 也被 Less 用掉了。官方为了让 CSS 变量也能够在 Sass 及 Less 中使用,无奈只能妥协的使用 --。

    当然,我们也可以通过 JS 来操作 CSS 变量。如此,CSS 变量可以动态的修改。

    
    // 设置变量
    document.body.style.setProperty('--primary', '#7F583F');
    
    // 读取变量
    document.body.style.getPropertyValue('--primary').trim();
    // '#7F583F'
    
    // 删除变量
    document.body.style.removeProperty('--primary');

    var 默认配置

    事实上,var() 函数还可以使用第二个参数,表示变量的默认值。如果该变量此前没有定义,就会使用这个默认值。如果让我来思考,我肯定无法想象出结合 Less 和 CSS 变量便可以实现小程序样式的默认配置。这里我们参考了有赞的 Vant Weapp 的做法。有赞代码 theme.less 如下所示:

    // 先导入所有 less 变量
    @import (reference) './var.less';
    
    // 利用正则去替换变量
    .theme(@property, @imp) {
      @{property}: e(replace(@imp, '@([^() ]+)', '@{$1}', 'ig'));
      @{property}: e(replace(@imp, '@([^() ]+)', 'var(--$1, @{$1})', 'ig'));
    }

    函数效果如下所示:

    @import '../common/style/theme.less';
    
    .van-button {
      // ... 其他省略
      .theme(height, '@button-default-height');
      .theme(line-height, '@button-line-height');
      .theme(font-size, '@button-default-font-size');
    }
    
    // => 编译之后
    
    .van-button{
       // ... 其他省略
      height:44px;
      height:var(--button-default-height,44px);
      line-height:20px;
      line-height:var(--button-line-height,20px);
      font-size:16px;
      font-size:var(--button-default-font-size,16px);
    }

    我们可以看到每调用一次 Less 函数将会被编译成两个属性。第一个属性的设定对于不支持 CSS 变量的设备可以直接使用,如果当前设备支持 CSS 变量,则会使用 CSS 变量,但是由于当前 css 变量未定义,就会使用变量的默认值。

    经过这种函数的修改,我们就可以完成定制主题。详细请参考 Vant Weapp 定制主题。

    // component.wxml
    <van-button class="my-button">
      默认按钮
    </van-button>
    
    // component.wxss
    
    .my-button {
      --button-border-radius: 10px;
      --button-default-color: #f2f3f5;
    }

    大家可能有时候会想,这样的话,不是有更多的代码了吗?其实未必,事实上我们可以直接直接在页面内部定义变量样式。其他组件直接通过样式隔离去使用页面内的变量。当然了,事实上书写的代码多少,重点在于想要控制默认样式的粒度大小。粒度越小,则需要在各个组件内部书写的变量越多,粒度大,我们也就不必考虑太多。

    当然了,我们可以基于用户机型提供默认和适合当前机型修改的的样式配置,这样的话。即使用户想要自己定义,也不会出现样式特别怪异的状况。

    vi设计http://www.maiqicn.com 办公资源网站大全https://www.wode007.com

  • 相关阅读:
    C语言I博客作业07
    C语言I 博客作业03
    我的第一次作业
    C语言I博客作业05
    js闭包在你身边却不知
    浅谈SQL Transaction在请求中断后的行锁表锁
    事件订阅分发模型
    js 继承 对象方法与原型方法
    PHP学习笔记有关php中的变量
    PHP学习笔记不同编码占据不同的字节
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/13714344.html
Copyright © 2011-2022 走看看