AppLayout.vue 2.48 KB
<!-- src/layouts/AppLayout.vue -->
<template>
  <div class="app-layout">
    <!-- Header -->
    <header class="app-header">
      <div v-if="showBack" class="header-back" @click="goBack">
        <van-icon name="arrow-left" size="20" />
      </div>
      <h1 class="header-title">{{ title }}</h1>
      <div class="header-right">
        <slot name="header-right"></slot>
      </div>
    </header>

    <!-- Main Content -->
    <main class="app-content" :class="{ 'has-bottom-nav': showBottomNav }">
      <slot></slot>
    </main>

    <!-- Bottom Navigation -->
    <van-tabbar v-if="showBottomNav" route safe-area-inset-bottom>
      <van-tabbar-item to="/home" icon="home-o">首页</van-tabbar-item>
      <van-tabbar-item to="/courses" icon="orders-o">课程</van-tabbar-item>
      <van-tabbar-item to="/activities" icon="friends-o">活动</van-tabbar-item>
      <van-tabbar-item to="/community" icon="chat-o">社区</van-tabbar-item>
      <van-tabbar-item to="/profile" icon="user-o">我的</van-tabbar-item>
    </van-tabbar>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'

export default {
  name: 'AppLayout',
  props: {
    title: {
      type: String,
      default: '美乐爱觉教育'
    },
    showBack: {
      type: Boolean,
      default: false
    },
    showBottomNav: {
      type: Boolean,
      default: true
    }
  },
  setup(props) {
    const router = useRouter()
    const route = useRoute()

    const goBack = () => {
      if (window.history.length > 1) {
        router.back()
      } else {
        router.push('/')
      }
    }

    return {
      goBack
    }
  }
}
</script>

<style scoped>
.app-layout {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background-color: var(--background-color);
}

.app-header {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 46px;
  padding: 0 16px;
  background-color: var(--white);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.header-back {
  position: absolute;
  left: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-title {
  font-size: 18px;
  font-weight: 600;
  margin: 0;
}

.header-right {
  position: absolute;
  right: 16px;
  display: flex;
  align-items: center;
}

.app-content {
  flex: 1;
  overflow-y: auto;
  padding-bottom: 20px;
  -webkit-overflow-scrolling: touch;
}

.app-content.has-bottom-nav {
  padding-bottom: 50px;
}
</style>