移动端更新

This commit is contained in:
2026-02-21 14:47:54 +08:00
parent 7f8e68bb0a
commit c0d27be99b
432 changed files with 100843 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<template>
<sc-pages title="基础用法" show-back>
<!-- 内容区域 -->
<view class="content">
<view class="card">
<view class="card-title">功能说明</view>
<view class="card-content">
<text class="item"> 显示顶部导航栏</text>
<text class="item"> 带返回按钮</text>
<text class="item"> 内容区域可滚动</text>
<text class="item"> Flex 布局自适应</text>
</view>
</view>
<view class="card">
<view class="card-title">使用方式</view>
<view class="code-block">
<text class="code">
<sc-pages
title="基础用法"
show-back
>
<!-- 内容区域 -->
</sc-pages>
</text>
</view>
</view>
<view class="card">
<view class="card-title">滚动内容</view>
<view class="scroll-content">
<view v-for="i in 20" :key="i" class="scroll-item">
列表项 {{ i }}
</view>
</view>
</view>
</view>
</sc-pages>
</template>
<script setup>
import { ref } from 'vue'
</script>
<style scoped lang="scss">
.content {
padding: 32rpx;
}
.card {
margin-bottom: 32rpx;
padding: 32rpx;
background: #fff;
border-radius: 16rpx;
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.card-content {
display: flex;
flex-direction: column;
gap: 12rpx;
.item {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
}
}
}
.code-block {
padding: 24rpx;
background: #f5f5f5;
border-radius: 8rpx;
border-left: 4rpx solid #007AFF;
.code {
font-size: 24rpx;
color: #333;
line-height: 36rpx;
white-space: pre-wrap;
}
}
.scroll-content {
.scroll-item {
padding: 24rpx 0;
border-bottom: 1rpx solid #f0f0f0;
font-size: 28rpx;
color: #666;
&:last-child {
border-bottom: none;
}
}
}
</style>

View File

@@ -0,0 +1,157 @@
<template>
<sc-pages
title="完整页面"
:show-tabbar="true"
:tabbar-list="tabbarList"
:current-tab="currentTab"
@tabbar-change="handleTabChange"
>
<!-- 自定义导航栏右侧按钮 -->
<template #navbar-right>
<view class="navbar-action" @click="handleShare">
<uni-icons type="redo" :size="20" color="#000000"></uni-icons>
</view>
</template>
<!-- 内容区域 -->
<view class="content">
<view class="card">
<view class="card-title">功能说明</view>
<view class="card-content">
<text class="item"> 显示顶部导航栏</text>
<text class="item"> 显示底部 TabBar</text>
<text class="item"> 支持 TabBar 切换</text>
<text class="item"> Flex 布局自适应</text>
<text class="item"> 滚动条只在内容区域显示</text>
</view>
</view>
<view class="card">
<view class="card-title">当前 Tab: {{ tabbarList[currentTab]?.text }}</view>
<view class="card-content">
<text class="item">TabBar 列表项: {{ tabbarList.length }} </text>
<text class="item">点击底部 Tab 可以切换页面</text>
</view>
</view>
<view class="card">
<view class="card-title">滚动内容</view>
<view class="scroll-content">
<view v-for="i in 30" :key="i" class="scroll-item">
{{ tabbarList[currentTab]?.text }} - 列表项 {{ i }}
</view>
</view>
</view>
</view>
</sc-pages>
</template>
<script setup>
import { ref } from 'vue'
// 当前选中的 Tab
const currentTab = ref(0)
// TabBar 列表
const tabbarList = ref([
{
text: '首页',
iconPath: 'home',
selectedIconPath: 'home-fill'
},
{
text: '发现',
iconPath: 'compass',
selectedIconPath: 'compass-fill'
},
{
text: '消息',
iconPath: 'message',
selectedIconPath: 'message-fill',
badge: '5'
},
{
text: '我的',
iconPath: 'user',
selectedIconPath: 'user-fill',
dot: true
}
])
// Tab 切换事件
const handleTabChange = (index, item) => {
console.log('切换到 tab:', index, item)
currentTab.value = index
uni.showToast({
title: `切换到 ${item.text}`,
icon: 'none'
})
}
// 分享按钮
const handleShare = () => {
uni.showToast({
title: '分享功能',
icon: 'none'
})
}
</script>
<style scoped lang="scss">
.content {
padding: 32rpx;
}
.card {
margin-bottom: 32rpx;
padding: 32rpx;
background: #fff;
border-radius: 16rpx;
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.card-content {
display: flex;
flex-direction: column;
gap: 12rpx;
.item {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
}
}
}
.scroll-content {
.scroll-item {
padding: 24rpx 0;
border-bottom: 1rpx solid #f0f0f0;
font-size: 28rpx;
color: #666;
&:last-child {
border-bottom: none;
}
}
}
.navbar-action {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 50%;
transition: background 0.3s;
&:active {
background: rgba(0, 0, 0, 0.05);
}
}
</style>

View File

@@ -0,0 +1,139 @@
<template>
<sc-pages
title="下拉刷新"
:refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="handleRefresh"
>
<!-- 内容区域 -->
<view class="content">
<view class="card">
<view class="card-title">功能说明</view>
<view class="card-content">
<text class="item"> 开启下拉刷新功能</text>
<text class="item"> 下拉时显示刷新指示器</text>
<text class="item"> 刷新完成后自动收起</text>
</view>
</view>
<view class="card">
<view class="card-title">使用方式</view>
<view class="code-block">
<text class="code">
<sc-pages
title="下拉刷新"
:refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="handleRefresh"
>
<!-- 内容区域 -->
</sc-pages>
</text>
</view>
</view>
<view class="card">
<view class="card-title">刷新状态</view>
<view class="card-content">
<text class="item">当前状态: {{ refreshStatus }}</text>
<text class="item">刷新次数: {{ refreshCount }}</text>
</view>
</view>
<view class="card">
<view class="card-title">滚动内容下拉刷新</view>
<view class="scroll-content">
<view v-for="i in 20" :key="i" class="scroll-item">
列表项 {{ i }}
</view>
</view>
</view>
</view>
</sc-pages>
</template>
<script setup>
import { ref } from 'vue'
// 刷新状态
const isRefreshing = ref(false)
const refreshStatus = ref('未刷新')
const refreshCount = ref(0)
// 下拉刷新处理
const handleRefresh = async () => {
refreshStatus.value = '刷新中...'
isRefreshing.value = true
// 模拟异步请求
setTimeout(() => {
refreshStatus.value = '刷新完成'
refreshCount.value++
isRefreshing.value = false
uni.showToast({
title: '刷新成功',
icon: 'success'
})
}, 1500)
}
</script>
<style scoped lang="scss">
.content {
padding: 32rpx;
}
.card {
margin-bottom: 32rpx;
padding: 32rpx;
background: #fff;
border-radius: 16rpx;
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.card-content {
display: flex;
flex-direction: column;
gap: 12rpx;
.item {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
}
}
}
.code-block {
padding: 24rpx;
background: #f5f5f5;
border-radius: 8rpx;
border-left: 4rpx solid #007AFF;
.code {
font-size: 24rpx;
color: #333;
line-height: 36rpx;
white-space: pre-wrap;
}
}
.scroll-content {
.scroll-item {
padding: 24rpx 0;
border-bottom: 1rpx solid #f0f0f0;
font-size: 28rpx;
color: #666;
&:last-child {
border-bottom: none;
}
}
}
</style>

View File

@@ -0,0 +1,229 @@
<template>
<sc-pages
title="自定义导航栏"
:show-back="false"
:navbar-bg-color="navbarBgColor"
:navbar-color="navbarColor"
:right-icon="rightIcon"
@right-click="handleRightClick"
>
<!-- 自定义左侧内容 -->
<template #navbar-left>
<view class="custom-left">
<image
src="/static/logo.png"
mode="aspectFit"
style="width: 40px; height: 40px; border-radius: 8px;"
/>
</view>
</template>
<!-- 自定义标题 -->
<template #navbar-title>
<view class="custom-title">
<text class="title-text">自定义标题</text>
<text class="title-subtitle">副标题</text>
</view>
</template>
<!-- 内容区域 -->
<view class="content">
<view class="card">
<view class="card-title">功能说明</view>
<view class="card-content">
<text class="item"> 自定义左侧内容</text>
<text class="item"> 自定义标题支持多行</text>
<text class="item"> 自定义右侧按钮</text>
<text class="item"> 自定义导航栏颜色</text>
</view>
</view>
<view class="card">
<view class="card-title">导航栏配置</view>
<view class="config-item">
<text class="label">背景色:</text>
<text class="value">{{ navbarBgColor }}</text>
</view>
<view class="config-item">
<text class="label">文字色:</text>
<text class="value">{{ navbarColor }}</text>
</view>
<view class="config-item">
<text class="label">右侧图标:</text>
<text class="value">{{ rightIcon }}</text>
</view>
</view>
<view class="card">
<view class="card-title">主题切换</view>
<view class="theme-switch">
<button
v-for="theme in themes"
:key="theme.name"
:class="{ active: currentTheme === theme.name }"
@click="switchTheme(theme)"
>
{{ theme.label }}
</button>
</view>
</view>
<view class="card">
<view class="card-title">滚动内容</view>
<view class="scroll-content">
<view v-for="i in 20" :key="i" class="scroll-item">
列表项 {{ i }}
</view>
</view>
</view>
</view>
</sc-pages>
</template>
<script setup>
import { ref } from 'vue'
// 导航栏配置
const navbarBgColor = ref('#FFFFFF')
const navbarColor = ref('#000000')
const rightIcon = ref('more')
// 当前主题
const currentTheme = ref('default')
// 主题配置
const themes = [
{ name: 'default', label: '默认', bg: '#FFFFFF', color: '#000000' },
{ name: 'primary', label: '主题蓝', bg: '#007AFF', color: '#FFFFFF' },
{ name: 'dark', label: '深色', bg: '#000000', color: '#FFFFFF' }
]
// 切换主题
const switchTheme = (theme) => {
currentTheme.value = theme.name
navbarBgColor.value = theme.bg
navbarColor.value = theme.color
}
// 右侧按钮点击
const handleRightClick = () => {
uni.showActionSheet({
itemList: ['选项1', '选项2', '选项3'],
success: (res) => {
console.log('选择了:', res.tapIndex)
}
})
}
</script>
<style scoped lang="scss">
.content {
padding: 32rpx;
}
.card {
margin-bottom: 32rpx;
padding: 32rpx;
background: #fff;
border-radius: 16rpx;
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.card-content {
display: flex;
flex-direction: column;
gap: 12rpx;
.item {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
}
}
}
.config-item {
display: flex;
justify-content: space-between;
padding: 16rpx 0;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.label {
font-size: 28rpx;
color: #666;
}
.value {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
}
.theme-switch {
display: flex;
gap: 16rpx;
button {
flex: 1;
height: 72rpx;
line-height: 72rpx;
font-size: 28rpx;
background: #f5f5f5;
color: #333;
border: none;
border-radius: 8rpx;
&.active {
background: #007AFF;
color: #fff;
}
}
}
.scroll-content {
.scroll-item {
padding: 24rpx 0;
border-bottom: 1rpx solid #f0f0f0;
font-size: 28rpx;
color: #666;
&:last-child {
border-bottom: none;
}
}
}
.custom-left {
display: flex;
align-items: center;
}
.custom-title {
display: flex;
flex-direction: column;
align-items: center;
gap: 4rpx;
.title-text {
font-size: 18px;
font-weight: 500;
color: inherit;
}
.title-subtitle {
font-size: 12px;
color: inherit;
opacity: 0.7;
}
}
</style>

View File

@@ -0,0 +1,167 @@
<template>
<sc-pages
:show-navbar="false"
:show-tabbar="true"
:tabbar-list="tabbarList"
:current-tab="currentTab"
@tabbar-change="handleTabChange"
>
<!-- 内容区域 -->
<view class="content">
<view class="card">
<view class="card-title">功能说明</view>
<view class="card-content">
<text class="item"> 隐藏顶部导航栏</text>
<text class="item"> 显示底部 TabBar</text>
<text class="item"> 内容区域占满全部高度</text>
<text class="item"> 适合全屏内容页面</text>
</view>
</view>
<view class="card">
<view class="card-title">使用场景</view>
<view class="card-content">
<text class="item"> 启动页</text>
<text class="item"> 引导页</text>
<text class="item"> 全屏图片浏览</text>
<text class="item"> 游戏页面</text>
<text class="item"> 特殊展示页面</text>
</view>
</view>
<view class="card">
<view class="card-title">使用方式</view>
<view class="code-block">
<text class="code">
<sc-pages
:show-navbar="false"
:show-tabbar="true"
:tabbar-list="tabbarList"
:current-tab="currentTab"
@tabbar-change="handleTabChange"
>
<!-- 内容区域 -->
</sc-pages>
</text>
</view>
</view>
<view class="card">
<view class="card-title">当前 Tab: {{ tabbarList[currentTab]?.text }}</view>
<view class="card-content">
<text class="item">点击底部 Tab 可以切换</text>
</view>
</view>
<view class="card">
<view class="card-title">滚动内容</view>
<view class="scroll-content">
<view v-for="i in 20" :key="i" class="scroll-item">
列表项 {{ i }}
</view>
</view>
</view>
</view>
</sc-pages>
</template>
<script setup>
import { ref } from 'vue'
// 当前选中的 Tab
const currentTab = ref(0)
// TabBar 列表
const tabbarList = ref([
{
text: '首页',
iconPath: 'home',
selectedIconPath: 'home-fill'
},
{
text: '发现',
iconPath: 'compass',
selectedIconPath: 'compass-fill'
},
{
text: '消息',
iconPath: 'message',
selectedIconPath: 'message-fill',
badge: '3'
},
{
text: '我的',
iconPath: 'user',
selectedIconPath: 'user-fill'
}
])
// Tab 切换事件
const handleTabChange = (index, item) => {
console.log('切换到 tab:', index, item)
currentTab.value = index
uni.showToast({
title: `切换到 ${item.text}`,
icon: 'none'
})
}
</script>
<style scoped lang="scss">
.content {
padding: 32rpx;
}
.card {
margin-bottom: 32rpx;
padding: 32rpx;
background: #fff;
border-radius: 16rpx;
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.card-content {
display: flex;
flex-direction: column;
gap: 12rpx;
.item {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
}
}
}
.code-block {
padding: 24rpx;
background: #f5f5f5;
border-radius: 8rpx;
border-left: 4rpx solid #007AFF;
.code {
font-size: 24rpx;
color: #333;
line-height: 36rpx;
white-space: pre-wrap;
}
}
.scroll-content {
.scroll-item {
padding: 24rpx 0;
border-bottom: 1rpx solid #f0f0f0;
font-size: 28rpx;
color: #666;
&:last-child {
border-bottom: none;
}
}
}
</style>

View File

@@ -0,0 +1,115 @@
<template>
<view class="pages-example">
<!-- 示例 1: 基础用法带导航栏 -->
<view class="example-section">
<view class="example-title">示例 1: 基础用法带导航栏</view>
<view class="example-desc">显示顶部导航栏带返回按钮内容区域可滚动</view>
<button @click="showExample1">查看示例</button>
</view>
<!-- 示例 2: 完整页面 TabBar -->
<view class="example-section">
<view class="example-title">示例 2: 完整页面 TabBar</view>
<view class="example-desc">显示顶部导航栏和底部 TabBar完整页面结构</view>
<button @click="showExample2">查看示例</button>
</view>
<!-- 示例 3: 下拉刷新 -->
<view class="example-section">
<view class="example-title">示例 3: 下拉刷新</view>
<view class="example-desc">开启下拉刷新功能</view>
<button @click="showExample3">查看示例</button>
</view>
<!-- 示例 4: 自定义导航栏 -->
<view class="example-section">
<view class="example-title">示例 4: 自定义导航栏</view>
<view class="example-desc">自定义导航栏标题和右侧按钮</view>
<button @click="showExample4">查看示例</button>
</view>
<!-- 示例 5: 无导航栏 -->
<view class="example-section">
<view class="example-title">示例 5: 无导航栏</view>
<view class="example-desc">隐藏顶部导航栏</view>
<button @click="showExample5">查看示例</button>
</view>
</view>
</template>
<script setup>
// 跳转到示例 1
const showExample1 = () => {
uni.navigateTo({
url: '/pages/example/pages/example1'
})
}
// 跳转到示例 2
const showExample2 = () => {
uni.navigateTo({
url: '/pages/example/pages/example2'
})
}
// 跳转到示例 3
const showExample3 = () => {
uni.navigateTo({
url: '/pages/example/pages/example3'
})
}
// 跳转到示例 4
const showExample4 = () => {
uni.navigateTo({
url: '/pages/example/pages/example4'
})
}
// 跳转到示例 5
const showExample5 = () => {
uni.navigateTo({
url: '/pages/example/pages/example5'
})
}
</script>
<style scoped lang="scss">
.pages-example {
min-height: 100vh;
padding: 32rpx;
background: #f5f5f5;
}
.example-section {
margin-bottom: 32rpx;
padding: 32rpx;
background: #fff;
border-radius: 16rpx;
.example-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.example-desc {
font-size: 28rpx;
color: #666;
margin-bottom: 24rpx;
line-height: 40rpx;
}
button {
width: 100%;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
background: #007AFF;
color: #fff;
border: none;
border-radius: 12rpx;
}
}
</style>

View File

@@ -0,0 +1,168 @@
<template>
<view class="tabbar-example-page">
<!-- 页面内容区域 -->
<scroll-view class="page-content" scroll-y>
<view class="content-card">
<view class="card-title">TabBar 组件示例</view>
<view class="card-desc">当前选中{{ currentTab }}</view>
<view class="section">
<view class="section-title">功能说明</view>
<view class="section-content">
<text class="item"> 支持自定义图标iconfont</text>
<text class="item"> 支持徽标显示badge</text>
<text class="item"> 支持红点显示dot</text>
<text class="item"> 支持自定义主题色</text>
<text class="item"> 支持底部安全区适配</text>
<text class="item"> 支持 v-model 双向绑定</text>
</view>
</view>
<view class="section">
<view class="section-title">TabBar 数据</view>
<view class="section-content">
<text class="item" v-for="(item, index) in tabList" :key="index">
{{ index + 1 }}. {{ item.text }}
<text v-if="item.badge"> (徽标: {{ item.badge }})</text>
<text v-if="item.dot"> (红点)</text>
</text>
</view>
</view>
</view>
</scroll-view>
<!-- TabBar 组件 -->
<sc-tabbar
v-model="currentTab"
:list="tabList"
:fixed="true"
:safe-area-inset-bottom="true"
active-color="#007AFF"
inactive-color="#999999"
@change="handleTabChange"
>
<!-- 自定义图标插槽 -->
<template #icon="{ item, index, active }">
<text class="iconfont sc-tabbar__icon-text" :class="active ? item.selectedIconPath : item.iconPath"></text>
</template>
</sc-tabbar>
</view>
</template>
<script setup>
import { ref } from 'vue'
// 当前选中的 tab 索引
const currentTab = ref(0)
// tab 列表数据
const tabList = ref([
{
text: '首页',
iconPath: 'home',
selectedIconPath: 'home-fill',
pagePath: '/pages/index/index'
},
{
text: '发现',
iconPath: 'compass',
selectedIconPath: 'compass-fill',
pagePath: '/pages/discover/index'
},
{
text: '消息',
iconPath: 'message',
selectedIconPath: 'message-fill',
badge: '5', // 徽标显示
pagePath: '/pages/message/index'
},
{
text: '购物车',
iconPath: 'shopping-cart',
selectedIconPath: 'shopping-cart-fill',
dot: true, // 红点显示
pagePath: '/pages/cart/index'
},
{
text: '我的',
iconPath: 'user',
selectedIconPath: 'user-fill',
pagePath: '/pages/user/index'
}
])
// tab 切换事件
const handleTabChange = (index, item) => {
console.log('切换到 tab:', index, item)
// 跳转到对应页面
if (item.pagePath) {
uni.switchTab({
url: item.pagePath,
fail: () => {
// 如果不是 tabBar 页面,使用 navigateTo
uni.navigateTo({
url: item.pagePath
})
}
})
}
}
</script>
<style scoped lang="scss">
.tabbar-example-page {
display: flex;
flex-direction: column;
height: 100vh;
background: #f5f5f5;
}
.page-content {
flex: 1;
padding-bottom: 120rpx;
}
.content-card {
margin: 16rpx;
padding: 32rpx;
background: #fff;
border-radius: 16rpx;
.card-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.card-desc {
font-size: 28rpx;
color: #666;
margin-bottom: 32rpx;
}
}
.section {
margin-bottom: 32rpx;
&-title {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 16rpx;
}
&-content {
display: flex;
flex-direction: column;
gap: 12rpx;
.item {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
}
}
}
</style>