一个基于UniApp和Vue 2的Flutter Scaffold-like组件,提供高度可配置的AppBar、顶部导航栏、底部导航栏、抽屉、悬浮操作按钮(FAB)和SnackBar等功能

更新记录

1.0.0(2025-12-05) 下载此版本

初始功能


平台兼容性

uni-app(4.66)
Vue2Vue3ChromeSafariapp-vueapp-nvueAndroidiOS鸿蒙
微信小程序支付宝小程序抖音小程序百度小程序快手小程序京东小程序鸿蒙元服务QQ小程序飞书小程序快应用-华为快应用-联盟

liaction-scaffold

一个基于UniApp和Vue 2的Flutter Scaffold-like组件,提供高度可配置的AppBar、顶部导航栏、底部导航栏、抽屉、悬浮操作按钮(FAB)和SnackBar等功能。

功能特性

  • ✅ AppBar: 可配置的顶部应用栏,支持自定义标题、背景色、文字颜色等
  • ✅ 顶部导航栏: 基于liaction-tabs的可滚动顶部导航
  • ✅ 底部导航栏: 基于liaction-tabs的底部导航
  • ✅ 抽屉: 可配置位置、宽度、点击遮罩是否关闭等
  • ✅ 悬浮操作按钮(FAB): 支持自定义图标、颜色、大小等
  • ✅ SnackBar: 底部提示条,支持自定义消息、操作按钮、持续时间等
  • ✅ 高度可配置: 所有组件都支持丰富的配置选项
  • ✅ 支持插槽: 所有组件都支持自定义插槽

安装

在UniApp项目中通过插件市场安装,或直接将组件复制到项目中。

配置选项

AppBar配置

属性类型默认值说明
showBooleantrue是否显示AppBar
titleString''标题文本
backgroundColorString'#007AFF'背景颜色
textColorString'#FFFFFF'文字颜色
heightString'44px'高度
paddingTopString'0px'顶部内边距
leadingString''返回按钮图标
actionsArray[]操作按钮数组
onBackPressFunctionnull返回按钮点击回调,返回true表示拦截返回

TopNavigation配置

属性类型默认值说明
showBooleantrue是否显示顶部导航
itemsArray[]导航项数组,每个项包含id、text、badge等属性
currentIndexNumber0当前激活的索引
backgroundColorString'#FFFFFF'背景颜色
textColorString'#666666'文字颜色
activeColorString'#007AFF'激活项颜色
heightString'48px'高度
scrollEnabledBooleanfalse是否支持滚动
tabsConfigObject{}liazction-tabs组件配置
tabsConfig配置
属性类型默认值说明
showBadgeBooleanfalse是否显示徽章
badgePositionString'top-right'徽章位置
badgeSizeString'16px'徽章大小
badgeColorString'#FF3B30'徽章颜色
tabFlexBooleantrue是否平均分配宽度
indicatorWidthString'content'指示器宽度
tabFontSizeString'14px'文字大小
tabPaddingString'12px'内边距

BottomNavigationBar配置

属性类型默认值说明
showBooleantrue是否显示底部导航
itemsArray[]导航项数组,每个项包含id、text、badge等属性
currentIndexNumber0当前激活的索引
backgroundColorString'#FFFFFF'背景颜色
textColorString'#666666'文字颜色
activeColorString'#007AFF'激活项颜色
heightString'50px'高度
scrollEnabledBooleanfalse是否支持滚动
tabsConfigObject{}liazction-tabs组件配置

Drawer配置

属性类型默认值说明
positionString'left'抽屉位置,可选值:'left'、'right'
widthString'280px'抽屉宽度
closeOnOverlayClickBooleantrue点击遮罩是否关闭抽屉

FloatingActionButton配置

属性类型默认值说明
showBooleantrue是否显示FAB
iconString'+'图标
backgroundColorString'#007AFF'背景颜色
colorString'#FFFFFF'文字颜色
sizeString'56px'大小
rightString'20px'距离右侧距离
bottomString'20px'距离底部距离

SnackBar配置

属性类型默认值说明
messageString''消息文本
actionObjectnull操作按钮配置,包含text和onClick属性
backgroundColorString'#333333'背景颜色
textColorString'#FFFFFF'文字颜色
durationNumber3000持续时间(毫秒)

其他配置

属性类型默认值说明
backgroundColorString'#FFFFFF'页面背景颜色
enableStatusBarVarBooleantrue是否启用状态栏高度CSS变量
enableWindowBottomVarBooleantrue是否启用窗口底部CSS变量

事件说明

事件名参数说明
appbar-leading-clickAppBar返回按钮点击事件
appbar-action-clickindexAppBar操作按钮点击事件,返回索引
top-nav-clickindex顶部导航项点击事件,返回索引
bottom-nav-clickindex底部导航项点击事件,返回索引
fab-clickFAB点击事件
snackbar-action-clickSnackBar操作按钮点击事件

插槽说明

插槽名说明
default主内容区域
drawer抽屉内容
appbar-leadingAppBar左侧内容
appbar-titleAppBar标题内容
appbar-actionsAppBar右侧操作按钮
top-nav顶部导航自定义内容
bottom-nav底部导航自定义内容
fabFAB自定义内容

方法说明

方法名参数说明
openDrawer打开抽屉
closeDrawer关闭抽屉
toggleDrawer切换抽屉状态
displaySnackBaroptions显示SnackBar,options包含message、action、duration等属性
hideSnackBar隐藏SnackBar

使用示例

普通示例

<template>
  <liaction-scaffold 
    :app-bar="appBar"
    :top-navigation="topNavigation"
    :bottom-navigation-bar="bottomNavigationBar"
    :drawer="drawer"
    :floating-action-button="floatingActionButton"
    :background-color="backgroundColor"
    @appbar-leading-click="handleAppBarLeadingClick"
    @appbar-action-click="handleAppBarActionClick"
    @top-nav-click="handleTopNavClick"
    @bottom-nav-click="handleBottomNavClick"
    @fab-click="handleFabClick"
  >
    <!-- 内容区域 -->
    <view class="content">
      <text>这是页面内容</text>
    </view>

    <!-- 抽屉内容 -->
    <template #drawer>
      <view class="drawer-content">
        <text>抽屉内容</text>
      </view>
    </template>
  </liaction-scaffold>
</template>

<script>
export default {
  data() {
    return {
      // AppBar配置
      appBar: {
        show: true,
        title: 'Scaffold演示',
        backgroundColor: '#007AFF',
        textColor: '#FFFFFF'
      },

      // 顶部导航配置
      topNavigation: {
        show: true,
        items: [
          { id: 'all', text: '全部' },
          { id: 'news', text: '新闻' },
          { id: 'sports', text: '体育' }
        ],
        tabsConfig: {
          showBadge: false,
          tabFlex: true
        }
      },

      // 底部导航配置
      bottomNavigationBar: {
        show: true,
        items: [
          { id: 'home', text: '首页'},
          { id: 'category', text: '分类' },
          { id: 'profile', text: '我的' }
        ],
        tabsConfig: {
          showBadge: true
        }
      },

      // 抽屉配置
      drawer: {
        width: '280px',
        position: 'left',
        closeOnOverlayClick: true
      },

      // FAB配置
      floatingActionButton: {
        show: true,
        icon: '+',
        backgroundColor: '#007AFF'
      },

      // 背景颜色
      backgroundColor: '#F5F5F5'
    }
  },
  methods: {
    // 处理AppBar返回按钮点击
    handleAppBarLeadingClick() {
      console.log('AppBar返回按钮点击');
    },

    // 处理AppBar操作按钮点击
    handleAppBarActionClick(index) {
      console.log('AppBar操作按钮点击,索引:', index);
    },

    // 处理顶部导航点击
    handleTopNavClick(index) {
      console.log('顶部导航点击,索引:', index);
    },

    // 处理底部导航点击
    handleBottomNavClick(index) {
      console.log('底部导航点击,索引:', index);
    },

    // 处理FAB点击
    handleFabClick() {
      console.log('FAB点击');
      // 显示SnackBar
      this.$refs.scaffoldRef.displaySnackBar({
        message: 'FAB被点击了',
        duration: 2000
      });
    }
  }
}
</script>

自定义底部导航

<liaction-scaffold 
  :app-bar="appBar"
  :bottom-navigation-bar="bottomNavigationBar"
  @bottom-nav-click="handleBottomNavClick"
>
  <!-- 主内容 -->
  <view class="content">
    <text>这是页面内容</text>
  </view>

  <!-- 自定义底部导航 -->
  <template #bottom-nav>
    <view class="custom-bottom-nav">
      <view 
        v-for="(item, index) in bottomNavigationBar.items" 
        :key="item.id"
        class="nav-item"
        :class="{ 'active': bottomNavigationBar.currentIndex === index }"
        @click="handleBottomNavItemClick(index)"
      >
        <uni-icons 
          :type="item.icon" 
          size="24px" 
          :color="bottomNavigationBar.currentIndex === index ? '#007AFF' : '#666666'"
        ></uni-icons>
        <text 
          class="nav-text"
          :style="{
            color: bottomNavigationBar.currentIndex === index ? '#007AFF' : '#666666'
          }"
        >
          {{ item.text }}
        </text>
      </view>
    </view>
  </template>
</liaction-scaffold>

<style scoped>
.custom-bottom-nav {
  display: flex;
  align-items: center;
  justify-content: space-around;
  height: 50px;
  background-color: #FFFFFF;
  box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
  width: 100%;
}

.nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  height: 100%;
  cursor: pointer;
  padding: 4px 0;
}

.nav-item.active {
  font-weight: 600;
}

.nav-text {
  font-size: 12px;
  margin-top: 4px;
}
</style>

<script>
export default {
  data() {
    return {
      appBar: {
        title: '自定义底部导航',
        backgroundColor: '#007AFF',
        textColor: '#FFFFFF'
      },
      bottomNavigationBar: {
        items: [
          { id: 'home', icon: 'home', text: '首页' },
          { id: 'category', icon: 'grid', text: '分类' },
          { id: 'discover', icon: 'compass', text: '发现' },
          { id: 'profile', icon: 'person', text: '我的' }
        ],
        currentIndex: 0
      }
    }
  },
  methods: {
    handleBottomNavClick(index) {
      console.log('底部导航点击,索引:', index);
    },
    handleBottomNavItemClick(index) {
      // 更新当前索引
      this.bottomNavigationBar.currentIndex = index;
      // 触发事件
      this.$emit('bottom-nav-click', index);
      // 可以在这里添加额外的逻辑
      console.log('自定义底部导航项点击,索引:', index);
    }
  }
}
</script>

自定义顶部导航

<liaction-scaffold 
  :app-bar="appBar"
  :top-navigation="topNavigation"
  @top-nav-click="handleTopNavClick"
>
  <!-- 主内容 -->
  <view class="content">
    <text>这是页面内容</text>
  </view>

  <!-- 自定义顶部导航 -->
  <template #top-nav>
    <view class="custom-top-nav">
      <view 
        v-for="(item, index) in topNavigation.items" 
        :key="item.id"
        class="nav-item"
        :class="{ 'active': topNavigation.currentIndex === index }"
        @click="handleTopNavItemClick(index)"
      >
        <text 
          class="nav-text"
          :style="{
            color: topNavigation.currentIndex === index ? '#007AFF' : '#666666',
            fontWeight: topNavigation.currentIndex === index ? '600' : 'normal'
          }"
        >
          {{ item.text }}
        </text>
      </view>
    </view>
  </template>
</liaction-scaffold>

<style scoped>
.custom-top-nav {
  display: flex;
  align-items: center;
  height: 48px;
  background-color: #FFFFFF;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  overflow-x: auto;
  white-space: nowrap;
}

.nav-item {
  display: flex;
  align-items: center;
  padding: 0 20px;
  height: 100%;
  cursor: pointer;
  position: relative;
}

.nav-item.active {
  border-bottom: 2px solid #007AFF;
}

.nav-text {
  font-size: 14px;
}

</style>

<script>
export default {
  data() {
    return {
      appBar: {
        title: '自定义顶部导航',
        backgroundColor: '#007AFF',
        textColor: '#FFFFFF'
      },
      topNavigation: {
        items: [
          { id: 'all', text: '全部' },
          { id: 'news', text: '新闻' },
          { id: 'sports', text: '体育' },
          { id: 'entertainment', text: '娱乐' },
          { id: 'technology', text: '科技' }
        ],
        currentIndex: 0
      }
    }
  },
  methods: {
    handleTopNavClick(index) {
      console.log('顶部导航点击,索引:', index);
    },
    handleTopNavItemClick(index) {
      // 更新当前索引
      this.topNavigation.currentIndex = index;
      // 触发事件
      this.$emit('top-nav-click', index);
    }
  }
}
</script>

许可证

MIT License

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值