Taro样式重构记录

前言

公司的商城小程序一直是开发几个周然后就停几个周。并且经由了多人开发,每个页面的样式也不统一。并且由于UI同学在figma上的UI图也不统一(比如有的间距是12px,有的间距是16px,但都是同样的卡片)。因此团队决定重构样式。

如何重构

主要是定义一系列的css变量。因为本项目没有使用任何css工具

css 复制代码
:root,
page {
  color: #333333;
  --nutui-color-primary: #ffcf14;
  /** 主要内容用色,常用语常规标题内容、细文浏览、常规按钮文字以及图表引导。*/
  --nutui-gray-7: #333333;
  /** 次要文字色,用于次级标题、属性标示、非主要信息引导等。*/
  --nutui-black-10: #666666;
  /** 不可操作内容色,用于预置内容、无效内容、特殊不可点击按钮、组件边框线等。*/
  --nutui-gray-6: #cccccc;
  /** 页面基底色,用于卡片式页面的兜底,永远置于页面最底层。*/
  --nutui-gray-5: #f7f8fa;
  /** 卡片内嵌背景色,用于卡片内部的信息包裹,感知较弱。*/
  --nutui-gray-4: #f7f8fc;
  /** 卡片背景色*/
  --nutui-black-3: #ffffff;
  /** 页面全局蒙层,用于弹出层、弹窗、新功能引导出现的整页遮罩*/
  --nutui-gray-3: rgba(0, 0, 0, 0.7);
  /** 局部蒙层,用于非整页遮罩*/
  --nutui-gray-2: rgba(0, 0, 0, 0.4);
  /** 间隔线/容错线,用于结构或信息分割*/
  --nutui-black-2: rgba(0, 0, 0, 0.08);
  /** 图片容错蒙层 */
  --nutui-gray-1: rgba(0, 0, 0, 0.02);

  /** 主题色 */
  --tx-bg: #ffcf14;
  /** 次主色 */
  --tx-bg-secondary: #ae7466;
  /** 浅主色 */
  --tx-bg-light: #fff8e5;
  /* 主文本浅颜色 */
  --tx-text-primary-light: #E79600;
  /** 主文本颜色 */
  --tx-text: #333333;
  /** 常规文本颜色 */
  --tx-text-normal: #666666;
  /** 次要文本颜色 */
  --tx-text-secondary: #999999;
  /** 不可操作内容颜色 */
  --tx-text-disabled: #cccccc;
  /** 页面背景色 */
  --tx-bg-page: #f7f8fa;
  /** 卡片背景色 */
  --tx-bg-card: #ffffff;
  /** 线条颜色 */
  --tx-border: #eeeeee;
  /** 价格红色 */
  --tx-text-price: #ff4d4f;

  /** 主/次按钮高度 */
  --tx-button-height: 88rpx;
  /** 主/次按钮字号 */
  --tx-button-font-size: 32rpx;
  /** 主/次按钮x内边距 */
  --tx-button-padding-x: 64rpx;
  /** 主/次按钮高度-小 */
  --tx-button-height-small: 66rpx;
  /** 主/次按钮字号-小 */
  --tx-button-font-size-small: 28rpx;
  /** 主/次按钮x内边距-小 */
  --tx-button-padding-x-small: 40rpx;
  /** 主/次按钮高度-极小 */
  --tx-button-height-tiny: 48rpx;
  /** 主/次按钮字号-极小 */
  --tx-button-font-size-tiny: 24rpx;
  /** 主/次按钮x内边距-极小 */
  --tx-button-padding-x-tiny: 24rpx;

  /** 按钮圆角 */
  --tx-button-border-radius: 100rpx;
  /** 幽灵按钮高度 */
  --tx-ghost-button-height: 64rpx;
  /** 幽灵按钮字号 */
  --tx-ghost-button-font-size: 28rpx;
  /** 极小间距 */
  --tx-tiny-spacing: 8rpx;
  /** 小间距 */
  --tx-small-spacing: 16rpx;
  /** 中间距 */
  --tx-medium-spacing: 24rpx;
  /** 标准间距 */
  --tx-standard-spacing: 32rpx;
  /** 大间距 */
  --tx-large-spacing: 48rpx;

  /** 卡片圆角 */
  --tx-card-border-radius: 16rpx;
  /** 标签圆角 */
  --tx-label-border-radius: 4rpx;
  /** 大标签圆角 */
  --tx-large-label-border-radius: 16rpx;
  /** 弹窗圆角 */
  --tx-popup-border-radius: 24rpx;
  /** 极大标题字号 */
  --tx-xlarge-title-font-size: 48rpx;
  /** 大标题字号 */
  --tx-large-title-font-size: 40rpx;
  /** 标准行高 */
  --tx-standard-line-height: 1.4;
  /** 小字行高 */
  --tx-small-line-height: 1.2;
  /** 模块标题字号 */
  --tx-module-title-font-size: 32rpx;
  /** 商品主标题字号 */
  --tx-product-title-font-size: 28rpx;
  /** 商品副文本字号 */
  --tx-product-subtitle-font-size: 24rpx;
  /** 极小标签字号 */
  --tx-tiny-label-font-size: 20rpx;
  /** 价格整数部分字号 */
  --tx-price-integer-font-size: 36rpx;
  /** 价格小数部分字号 */
  --tx-price-decimal-font-size: 24rpx;
  /** 积分数字小字号 */
  --tx-code-font-size: 60rpx;
  /** 积分数字小字号行高 */
  --tx-code-line-height: 60rpx;
  /** 积分数字大字号 */
  --tx-code-font-size-large: 72rpx;
  /** 积分数字大字号行高 */
  --tx-code-line-height-large: 72rpx;

  color: var(--tx-text-normal);
  font-size: var(--tx-product-title-font-size);
  line-height: var(--tx-standard-line-height);
}

/** @description 主题颜色 */
.bg-theme {
  background-color: var(--tx-bg);
}

.bg-sub {
  background-color: var(--tx-bg-light);
}

.bg-page {
  background-color: var(--tx-bg-page);
}

.bg-card {
  background-color: var(--tx-bg-card);
}

/** @description 线条颜色 */
.border-color {
  border-color: var(--tx-border);
}

/** @description 文本颜色 */
.text-main {
  color: var(--tx-text);
}

.text-normal {
  color: var(--tx-text-normal);
}

.text-secondary {
  color: var(--tx-text-secondary);
}

.text-disabled {
  color: var(--tx-text-disabled);
}

.text-money {
  color: var(--tx-text-price);
}

/** @description 间距 */
.mt {
  margin-top: var(--tx-tiny-spacing);
}

.mb {
  margin-bottom: var(--tx-tiny-spacing);
}

.ml {
  margin-left: var(--tx-tiny-spacing);
}

.mr {
  margin-right: var(--tx-tiny-spacing);
}

.mx {
  margin-left: var(--tx-tiny-spacing);
  margin-right: var(--tx-tiny-spacing);
}

.my {
  margin-top: var(--tx-tiny-spacing);
  margin-bottom: var(--tx-tiny-spacing);
}

.m {
  margin: var(--tx-tiny-spacing);
}

.mt-2 {
  margin-top: var(--tx-small-spacing);
}

.mb-2 {
  margin-bottom: var(--tx-small-spacing);
}

.ml-2 {
  margin-left: var(--tx-small-spacing);
}

.mr-2 {
  margin-right: var(--tx-small-spacing);
}

.mx-2 {
  margin-left: var(--tx-small-spacing);
  margin-right: var(--tx-small-spacing);
}

.my-2 {
  margin-top: var(--tx-small-spacing);
  margin-bottom: var(--tx-small-spacing);
}

.m-2 {
  margin: var(--tx-small-spacing);
}

.m-3 {
  margin: var(--tx-medium-spacing);
}

/* 中间距 */
.mt-3 {
  margin-top: var(--tx-medium-spacing);
}

.mb-3 {
  margin-bottom: var(--tx-medium-spacing);
}

.ml-3 {
  margin-left: var(--tx-medium-spacing);
}

.mr-3 {
  margin-right: var(--tx-medium-spacing);
}

.mx-3 {
  margin-left: var(--tx-medium-spacing);
  margin-right: var(--tx-medium-spacing);
}

.my-3 {
  margin-top: var(--tx-medium-spacing);
  margin-bottom: var(--tx-medium-spacing);
}

/* 标准间距 */
.mt-4 {
  margin-top: var(--tx-standard-spacing);
}

.mb-4 {
  margin-bottom: var(--tx-standard-spacing);
}

.ml-4 {
  margin-left: var(--tx-standard-spacing);
}

.mr-4 {
  margin-right: var(--tx-standard-spacing);
}

.mx-4 {
  margin-left: var(--tx-standard-spacing);
  margin-right: var(--tx-standard-spacing);
}

.my-4 {
  margin-top: var(--tx-standard-spacing);
  margin-bottom: var(--tx-standard-spacing);
}

.m-4 {
  margin: var(--tx-standard-spacing);
}

/* 大间距 */
.mt-big {
  margin-top: var(--tx-large-spacing);
}

.mb-big {
  margin-bottom: var(--tx-large-spacing);
}

.ml-big {
  margin-left: var(--tx-large-spacing);
}

.mr-big {
  margin-right: var(--tx-large-spacing);
}

.mx-big {
  margin-left: var(--tx-large-spacing);
  margin-right: var(--tx-large-spacing);
}

.my-big {
  margin-top: var(--tx-large-spacing);
  margin-bottom: var(--tx-large-spacing);
}

.m-big {
  margin: var(--tx-large-spacing);
}

.pt-tiny {
  padding-top: var(--tx-tiny-spacing);
}
.pb-tiny {
  padding-bottom: var(--tx-tiny-spacing);
}
.pl-tiny {
  padding-left: var(--tx-tiny-spacing);
}
.pr-tiny {
  padding-right: var(--tx-tiny-spacing);
}
.px-tiny {
  padding-left: var(--tx-tiny-spacing);
  padding-right: var(--tx-tiny-spacing);
}
.py-tiny {
  padding-top: var(--tx-tiny-spacing);
  padding-bottom: var(--tx-tiny-spacing);
}
.p-tiny {
  padding: var(--tx-tiny-spacing);
}

.pt-small {
  padding-top: var(--tx-small-spacing);
}
.pb-small {
  padding-bottom: var(--tx-small-spacing);
}
.pl-small {
  padding-left: var(--tx-small-spacing);
}
.pr-small {
  padding-right: var(--tx-small-spacing);
}
.px-small {
  padding-left: var(--tx-small-spacing);
  padding-right: var(--tx-small-spacing);
}
.py-small {
  padding-top: var(--tx-small-spacing);
  padding-bottom: var(--tx-small-spacing);
}
.p-small {
  padding: var(--tx-small-spacing);
}

.pt-medium {
  padding-top: var(--tx-medium-spacing);
}
.pb-medium {
  padding-bottom: var(--tx-medium-spacing);
}
.pl-medium {
  padding-left: var(--tx-medium-spacing);
}
.pr-medium {
  padding-right: var(--tx-medium-spacing);
}
.px-medium {
  padding-left: var(--tx-medium-spacing);
  padding-right: var(--tx-medium-spacing);
}
.py-medium {
  padding-top: var(--tx-medium-spacing);
  padding-bottom: var(--tx-medium-spacing);
}
.p-medium {
  padding: var(--tx-medium-spacing);
}

.pt-standard {
  padding-top: var(--tx-standard-spacing);
}
.pb-standard {
  padding-bottom: var(--tx-standard-spacing);
}
.pl-standard {
  padding-left: var(--tx-standard-spacing);
}
.pr-standard {
  padding-right: var(--tx-standard-spacing);
}
.px-standard {
  padding-left: var(--tx-standard-spacing);
  padding-right: var(--tx-standard-spacing);
}
.py-standard {
  padding-top: var(--tx-standard-spacing);
  padding-bottom: var(--tx-standard-spacing);
}
.p-standard {
  padding: var(--tx-standard-spacing);
}

.pt-large {
  padding-top: var(--tx-large-spacing);
}
.pb-large {
  padding-bottom: var(--tx-large-spacing);
}
.pl-large {
  padding-left: var(--tx-large-spacing);
}
.pr-large {
  padding-right: var(--tx-large-spacing);
}
.px-large {
  padding-left: var(--tx-large-spacing);
  padding-right: var(--tx-large-spacing);
}
.py-large {
  padding-top: var(--tx-large-spacing);
  padding-bottom: var(--tx-large-spacing);
}
.p-large {
  padding: var(--tx-large-spacing);
}

.p-card {
  padding: var(--tx-medium-spacing);
}

.p-page {
  margin: var(--tx-standard-spacing);
}

.ml-big {
  margin-left: var(--tx-large-spacing);
}

.mr-big {
  margin-right: var(--tx-large-spacing);
}

.mt-big {
  margin-top: var(--tx-large-spacing);
}

.mb-big {
  margin-bottom: var(--tx-large-spacing);
}

.mx-big {
  margin-left: var(--tx-large-spacing);
  margin-right: var(--tx-large-spacing);
}

.my-big {
  margin-top: var(--tx-large-spacing);
  margin-bottom: var(--tx-large-spacing);
}

/** @description 圆角 */
.radius-card {
  border-radius: var(--tx-card-border-radius);
}

.radius-label {
  border-radius: var(--tx-label-border-radius);
}

.radius-label-big {
  border-radius: var(--tx-large-label-border-radius);
}

.radius-modal {
  border-radius: var(--tx-popup-border-radius);
}

/** @description 字体大小 */
.text-h1 {
  font-size: var(--tx-large-title-font-size);
  line-height: var(--tx-standard-line-height);
  font-weight: 500;
}

.text-h2 {
  font-size: var(--tx-module-title-font-size);
  line-height: var(--tx-standard-line-height);
  font-weight: 500;
}

.text-title {
  font-size: var(--tx-product-title-font-size);
  line-height: var(--tx-standard-line-height);
  font-weight: 400;
}

.text-tips {
  font-size: var(--tx-product-subtitle-font-size);
  line-height: var(--tx-standard-line-height);
  font-weight: 400;
}

.text-mini {
  font-size: var(--tx-tiny-label-font-size);
  line-height: var(--tx-small-line-height);
  font-weight: 400;
}

.text-price {
  font-size: var(--tx-price-integer-font-size);
  line-height: var(--tx-small-line-height);
  font-weight: 600;
}

.text-price-sub {
  font-size: var(--tx-price-decimal-font-size);
  line-height: var(--tx-small-line-height);
  font-weight: 600;
}

.text-code-number {
  font-size: var(--tx-code-font-size);
  line-height: var(--tx-code-line-height-large);
  font-weight: 500;
}

.text-code-number-large {
  font-size: var(--tx-code-font-size-large);
  line-height: var(--tx-code-line-height);
  font-weight: bold;
}

.gap {
  gap: var(--tx-standard-spacing);
}

.gap-block {
  gap: var(--tx-large-spacing);
}

.gap-card {
  gap: var(--tx-small-spacing);
}

.gap-medium {
  gap: var(--tx-medium-spacing);
}

.gap-tiny {
  gap: var(--tx-tiny-spacing);
}

比如规定好,大按钮、小按钮、主要文本色、次要文本色、页面间距、卡片间距等等。

如何在把原来的替换掉统一起来。

像按钮这种,就封一个组件,根据props去生成样式

tsx 复制代码
import { classNames } from '@/utils/Tool';
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import './index.scss';

export interface ITXButtonProps {
  children?: React.ReactNode;
  /** @param 是否占据整行 */
  block?: boolean;
  className?: string;
  /** @param 是否禁用 */
  disabled?: boolean;
  /** @param 禁用时的提示文本 */
  disabledText?: string;
  /** @param 点击事件 */
  onClick?: () => void;
  /** @param 是否为大按钮 */
  large?: boolean;
  /** @param 是否为小按钮 */
  small?: boolean;
  /** @param 是否为极小按钮 */
  tiny?: boolean;
  /** @param 是否为主要按钮 */
  theme?: boolean;
  /** @param 是否为主要按钮-浅色 */
  themeLight?: boolean;
}

export const TXButton = function TXButton_(props: ITXButtonProps) {
  return (
    <View
      className={classNames({
        'tx-button': true,
        'tx-button-block': props.block,
        small: props.small,
        tiny: props.tiny,
        large: props.large,
        disabled: props.disabled,
        theme: props.theme,
        themeLight: props.themeLight,
        [props.className || '']: true,
      })}
      onClick={() => {
        if (props.disabled) {
          if (props.disabledText) {
            Taro.showToast({
              title: props.disabledText,
              icon: 'none',
              duration: 700,
            });
          }
          return;
        }
        props.onClick?.();
      }}
    >
      {props.children}
    </View>
  );
};
css 复制代码
.tx-button {
  --bg: var(--tx-bg-page);
  --color: var(--tx-text);
  --border-radius: var(--tx-button-border-radius);
  --height: var(--tx-button-height-small);
  --font-size: var(--tx-button-font-size-small);
  --padding-x: var(--tx-button-padding-x-small);
  --font-weight: 400;

  background-color: var(--bg);
  color: var(--color);
  border-radius: var(--border-radius);
  height: var(--height);
  font-size: var(--font-size);
  font-weight: var(--font-weight);
  padding: 0 var(--padding-x);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;

  &.tx-button-block {
    display: flex;
  }

  &.theme {
    --bg: var(--tx-bg);
    --color: var(--tx-text);
  }

  &.themeLight {
    --color: var(--tx-text-primary-light);
    --bg: var(--tx-bg-light);
  }

  &.large {
    --height: var(--tx-button-height);
    --font-size: var(--tx-button-font-size);
    --padding-x: var(--tx-button-padding-x);
    --font-weight: 700;
  }

  &.small {
    --height: var(--tx-button-height-small);
    --font-size: var(--tx-button-font-size-small);
    --padding-x: var(--tx-button-padding-x-small);
  }

  &.tiny {
    --height: var(--tx-button-height-tiny);
    --font-size: var(--tx-button-font-size-tiny);
    --padding-x: var(--tx-button-padding-x-tiny);
  }

  &.disabled {
    --bg: var(--tx-border);
    --color: var(--tx-text-secondary);
  }
}

.nut-popup-bottom.nut-popup-round {
  border-radius: var(--tx-popup-border-radius) var(--tx-popup-border-radius) 0 0 !important;
}

在使用时

tsx 复制代码
<TXButton
  large
  theme
  block
  onClick={() => {
    if (computed.loading) return;
    logic.onSave();
  }}
>
  保存地址
</TXButton>
相关推荐
To_OC2 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic2 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy2 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志3 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble4 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯5 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜5 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森6 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒7 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端