scss 转为原子css unocss

文章目录

  • 前言
    • [🎯 **方案一:混合模式 (推荐)**](#🎯 方案一:混合模式 (推荐))
    • [🎯 **方案二:语义化组件类**](#🎯 方案二:语义化组件类)
    • [🎯 **方案三:CSS 模块化**](#🎯 方案三:CSS 模块化)
    • [🎯 **方案四:BEM 命名规范**](#🎯 方案四:BEM 命名规范)
    • [💡 **推荐做法**](#💡 推荐做法)

前言

记录让c4 从scss 转为 原子css unocss

🎯 方案一:混合模式 (推荐)

保留语义化的 SCSS 类名,内部使用 @apply 指令应用 UnoCSS:

让我展示如何重构为语义化的 SCSS + UnoCSS 混合模式:

js 复制代码
<template>
  <view class="page">

    <view class="tab-bar">
      <view
        v-for="(tab, index) in tabList"
        :key="tab.key"
        class="tab-item"
        :class="{ 'active': currentTab === index }"
        @click="changeTab(index)"
      >
        <text class="tab-text">{{ tab.label }}</text>
        <text class="tab-count">({{ tab.count }})</text>
      </view>
    </view>

    <!-- 成员列表 -->
    <view class="content">
      <scroll-view scroll-y class="scroll-container">
        <view class="member-list">
          <view
            v-for="member in currentMemberList"
            :key="member.id"
            class="member-item"
          >
            <view class="member-info">
              <image :src="member.avatar" class="avatar" mode="aspectFill" />
              <view class="info">
       xxx
                </view>
              </view>
            </view>
            <view class="delete-btn" @click="deleteMember(member.id)">
              删除
            </view>
          </view>

          <!-- 空状态 -->
          <view v-if="currentMemberList.length === 0" class="empty-state">
            <image src="/static/images/mine/no_list.webp" class="empty-icon" mode="aspectFit" />
            <text class="empty-text">暂无成员</text>
          </view>
        </view>
      </scroll-view>
    </view>

  </view>
</template>

<style lang="scss" scoped>
/* 使用 @apply 指令结合 UnoCSS */
.page {
  @apply min-h-screen flex flex-col bg-#f7f7f7;
}

.tab-bar {
  @apply bg-white flex px-32rpx border-b-2rpx border-#f5f5f5;
}

.member-item {
  @apply flex items-center justify-between h-174rpx bg-white rounded-20rpx px-32rpx mb-24rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
}

.add-text {
  @apply text-32rpx font-600 text-white;
}

.modal-overlay {
  @apply fixed top-0 left-0 right-0 bottom-0 z-1000 flex items-center justify-center p-40rpx bg-black bg-opacity-50;
}



/* 其他弹窗样式... */
</style>

🎯 方案二:语义化组件类

创建语义化的组件类,内部使用 UnoCSS:

html 复制代码
<template>
  <view class="member-management-page">
    <view class="navigation-tabs">
      <view class="tab-item" :class="{ 'is-active': currentTab === index }">
        <!-- 内容 -->
      </view>
    </view>
    
    <view class="member-content">
      <view class="member-card">
        <view class="member-basic-info">
          <!-- 成员信息 -->
        </view>
        <view class="member-actions">
          <!-- 操作按钮 -->
        </view>
      </view>
    </view>
    
    <view class="floating-add-section">
      <view class="primary-add-button">
        <!-- 添加按钮 -->
      </view>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.member-management-page {
  @apply min-h-screen flex flex-col bg-#f7f7f7;
}

.navigation-tabs {
  @apply bg-white flex px-32rpx border-b-2rpx border-#f5f5f5;
}

.tab-item {
  @apply flex-1 py-32rpx relative flex items-center justify-center gap-8rpx cursor-pointer;
  
  &.is-active {
    &::after {
      content: '';
      position: absolute;
      bottom: 0;
      left: 50%;
      transform: translateX(-50%);
      width: 40rpx;
      height: 4rpx;
      background: #ff6600;
      border-radius: 2rpx;
    }
  }
}

.member-content {
  @apply flex-1 flex flex-col;
}

.member-card {
  @apply flex items-center justify-between h-174rpx bg-white rounded-20rpx px-32rpx mb-24rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
}

.member-basic-info {
  @apply flex items-center flex-1 gap-24rpx mr-24rpx;
}

.member-actions {
  @apply min-w-88rpx py-16rpx bg-white rounded-24rpx text-24rpx font-500 text-center flex-shrink-0 cursor-pointer transition-all-300ms;
}

.floating-add-section {
  @apply fixed bottom-0 left-0 right-0 bg-white rounded-t-48rpx px-32rpx pt-24rpx pb-120rpx;
  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
}

.primary-add-button {
  @apply w-full h-88rpx flex items-center justify-center bg-#ff6600 rounded-44rpx cursor-pointer transition-all-300ms;
  box-shadow: 0 8rpx 24rpx rgba(255, 102, 0, 0.3);
  
  &:active {
    @apply opacity-90 scale-98;
  }
}
</style>

🎯 方案三:CSS 模块化

使用 CSS 变量 + 语义化类名:

html 复制代码
<template>
  <view class="page">
    <view class="tab-bar">
      <view class="tab-item" :class="{ 'active': currentTab === index }">
        <!-- 内容 -->
      </view>
    </view>
  </view>
</template>

<style lang="scss" scoped>
:root {
  --primary-color: #ff6600;
  --text-primary: #333333;
  --text-secondary: #666666;
  --text-placeholder: #999999;
  --bg-page: #f7f7f7;
  --bg-card: #ffffff;
  --border-light: #f5f5f5;
  --shadow-card: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
  --shadow-floating: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
  --radius-small: 20rpx;
  --radius-medium: 24rpx;
  --radius-large: 48rpx;
}

.page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-page);
}

.tab-bar {
  background: var(--bg-card);
  display: flex;
  padding: 0 32rpx;
  border-bottom: 2rpx solid var(--border-light);
}

.tab-item {
  flex: 1;
  padding: 32rpx 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8rpx;
  cursor: pointer;
  
  &.active::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 40rpx;
    height: 4rpx;
    background: var(--primary-color);
    border-radius: 2rpx;
  }
}

.member-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 174rpx;
  background: var(--bg-card);
  border-radius: var(--radius-small);
  padding: 0 32rpx;
  margin-bottom: 24rpx;
  box-shadow: var(--shadow-card);
}

.add-button-wrapper {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--bg-card);
  border-radius: var(--radius-large) var(--radius-large) 0 0;
  padding: 24rpx 32rpx 120rpx;
  box-shadow: var(--shadow-floating);
}
</style>

🎯 方案四:BEM 命名规范

使用 BEM 命名约定保持语义性:

html 复制代码
<template>
  <view class="member-page">
    <view class="member-page__tabs">
      <view class="member-page__tab member-page__tab--active">
        <!-- 标签内容 -->
      </view>
    </view>
    
    <view class="member-page__content">
      <view class="member-card">
        <view class="member-card__info">
          <view class="member-card__avatar"></view>
          <view class="member-card__details">
            <view class="member-card__name-section">
              <!-- 姓名和编辑 -->
            </view>
            <view class="member-card__address-section">
              <!-- 地址和复制 -->
            </view>
          </view>
        </view>
        <view class="member-card__actions">
          <!-- 删除按钮 -->
        </view>
      </view>
    </view>
    
    <view class="member-page__floating-actions">
      <button class="member-page__add-btn">
        <!-- 添加按钮 -->
      </button>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.member-page {
  @apply min-h-screen flex flex-col bg-#f7f7f7;
  
  &__tabs {
    @apply bg-white flex px-32rpx border-b-2rpx border-#f5f5f5;
  }
  
  &__tab {
    @apply flex-1 py-32rpx relative flex items-center justify-center gap-8rpx cursor-pointer;
    
    &--active::after {
      content: '';
      position: absolute;
      bottom: 0;
      left: 50%;
      transform: translateX(-50%);
      width: 40rpx;
      height: 4rpx;
      background: #ff6600;
      border-radius: 2rpx;
    }
  }
  
  &__content {
    @apply flex-1 flex flex-col;
  }
  
  &__floating-actions {
    @apply fixed bottom-0 left-0 right-0 bg-white rounded-t-48rpx px-32rpx pt-24rpx pb-120rpx;
    box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
  }
  
  &__add-btn {
    @apply w-full h-88rpx flex items-center justify-center bg-#ff6600 rounded-44rpx cursor-pointer transition-all-300ms;
    box-shadow: 0 8rpx 24rpx rgba(255, 102, 0, 0.3);
    
    &:active {
      @apply opacity-90 scale-98;
    }
  }
}

.member-card {
  @apply flex items-center justify-between h-174rpx bg-white rounded-20rpx px-32rpx mb-24rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
  
  &__info {
    @apply flex items-center flex-1 gap-24rpx mr-24rpx;
  }
  
  &__avatar {
    @apply w-88rpx h-88rpx rounded-20rpx flex-shrink-0;
  }
  
  &__details {
    @apply flex-1;
  }
  
  &__name-section {
    @apply flex items-center gap-12rpx mb-12rpx;
  }
  
  &__address-section {
    @apply flex items-center gap-8rpx;
  }
  
  &__actions {
    @apply min-w-88rpx py-16rpx bg-white rounded-24rpx text-24rpx font-500 text-center flex-shrink-0 cursor-pointer transition-all-300ms;
    color: var(--text-placeholder);
    
    &:active {
      @apply bg-#f8f8f8 text-#333333;
    }
  }
}
</style>

💡 推荐做法

方案一(混合模式),因为它:

  1. 保持语义性: 类名清晰表达组件功能
  2. 利用 UnoCSS : 通过 @apply 获得原子化 CSS 的好处
  3. 易于维护: 样式集中管理,便于修改
  4. 性能优化: 结合两种方案的优势
  5. 团队友好: 新成员容易理解代码结构
相关推荐
Sapphire~10 小时前
重学前端012 --- 响应式网页设计 CSS变量
前端·css
家里有只小肥猫10 小时前
css中的v-bind 动态变化
前端·css
超人不会飛10 小时前
LLM应用专属的Vue3 Markdown组件 🚀重磅开源!
前端·javascript·vue.js
NULL Not NULL10 小时前
ES6+新特性:现代JavaScript的强大功能
开发语言·前端·javascript
小高00710 小时前
🚄 前端人必收:5 分钟掌握 ES2025 超实用语法
前端·javascript·面试
程序员海军10 小时前
2025年上半年前端技术圈生态总结分享
前端·vue.js·react.js
记忆怪 bug11 小时前
2025前端面试题及答案(详细)
前端
群联云防护小杜11 小时前
服务器异常负载排查手册 · 隐蔽进程篇
运维·服务器·前端·数据库·笔记·sql·tcp/ip
小小菜鸡ing11 小时前
简单爬一个小说页面 HTML 的title和内容
前端·html