feat: add mobile bottom menu bar

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/581/head
Ryan Wang 2022-05-07 17:35:10 +08:00
parent ff3d495a6b
commit f58428215d
7 changed files with 123 additions and 27 deletions

View File

@ -2,20 +2,21 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="renderer" content="webkit" />
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<meta content="webkit" name="renderer" />
<meta
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
/>
<meta name="robots" content="noindex,nofollow" />
<meta content="noindex,nofollow" name="robots" />
<title>Halo</title>
<link rel="icon" href="/favicon.ico" />
<link href="/favicon.ico" rel="icon" />
<style>
body {
height: 100%;
background-color: #f5f5f5;
}
#loader {
position: absolute;
top: 0;
@ -30,6 +31,7 @@
height: 30px;
animation: spin 0.6s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
@ -44,9 +46,9 @@
JavaScript enabled. Please enable it to continue.
</strong>
</noscript>
<div id="app" class="h-screen">
<div id="app">
<div id="loader"></div>
</div>
<script type="module" src="/src/main.ts"></script>
<script src="/src/main.ts" type="module"></script>
</body>
</html>

View File

@ -18,7 +18,9 @@
"story:build": "histoire build"
},
"dependencies": {
"@vueuse/core": "^8.4.2",
"pinia": "^2.0.13",
"tailwindcss-safe-area": "^0.2.2",
"tippy.js": "^6.3.7",
"vue": "^3.2.33",
"vue-router": "^4.0.15"

View File

@ -12,6 +12,7 @@ specifiers:
'@vue/eslint-config-typescript': ^10.0.0
'@vue/test-utils': ^2.0.0-rc.21
'@vue/tsconfig': ^0.1.3
'@vueuse/core': ^8.4.2
autoprefixer: ^10.4.7
c8: ^7.11.2
cypress: ^9.6.0
@ -27,6 +28,7 @@ specifiers:
sass: ^1.51.0
start-server-and-test: ^1.14.0
tailwindcss: ^3.0.24
tailwindcss-safe-area: ^0.2.2
tailwindcss-themeable: ^1.3.0
tippy.js: ^6.3.7
typescript: ~4.6.4
@ -39,7 +41,9 @@ specifiers:
vue-tsc: ^0.34.11
dependencies:
'@vueuse/core': 8.4.2_vue@3.2.33
pinia: 2.0.13_typescript@4.6.4+vue@3.2.33
tailwindcss-safe-area: 0.2.2
tippy.js: 6.3.7
vue: 3.2.33
vue-router: 4.0.15_vue@3.2.33
@ -499,7 +503,7 @@ packages:
resolution: {integrity: sha512-4+yTBlUaIiVBe6jVoDB90bfyUUaNANDqFRPpURPPibZQ715zoTo9QGxemZun1etKGG2ZYH92d0pOmnGKwa/rPQ==}
dependencies:
'@iconify/vue': 3.2.1_vue@3.2.33
'@vueuse/core': 8.2.5_vue@3.2.33
'@vueuse/core': 8.4.2_vue@3.2.33
floating-vue: 2.0.0-beta.15_vue@3.2.33
transitivePeerDependencies:
- '@vue/composition-api'
@ -1057,8 +1061,8 @@ packages:
'@types/node': 17.0.31
dev: true
/@vueuse/core/8.2.5_vue@3.2.33:
resolution: {integrity: sha512-5prZAA1Ji2ltwNUnzreu6WIXYqHYP/9U2BiY5mD/650VYLpVcwVlYznJDFcLCmEWI3o3Vd34oS1FUf+6Mh68GQ==}
/@vueuse/core/8.4.2_vue@3.2.33:
resolution: {integrity: sha512-dUVU96lii1ZdWoNJXauQNt+4QrHz1DKbuW+y6pDR2N10q7rGZJMDU7pQeMcC2XeosX7kMODfaBuqsF03NozzLg==}
peerDependencies:
'@vue/composition-api': ^1.1.0
vue: ^2.6.0 || ^3.2.0
@ -1068,18 +1072,16 @@ packages:
vue:
optional: true
dependencies:
'@vueuse/metadata': 8.2.5
'@vueuse/shared': 8.2.5_vue@3.2.33
'@vueuse/metadata': 8.4.2
'@vueuse/shared': 8.4.2_vue@3.2.33
vue: 3.2.33
vue-demi: 0.12.1_vue@3.2.33
dev: true
/@vueuse/metadata/8.2.5:
resolution: {integrity: sha512-Lk9plJjh9cIdiRdcj16dau+2LANxIdFCiTgdfzwYXbflxq0QnMBeOD2qHgKDE7fuVrtPcVWj8VSuZEx1HRfNQA==}
dev: true
/@vueuse/metadata/8.4.2:
resolution: {integrity: sha512-2BIj++7P0/I5dfMsEe8q7Kw0HqVAjVcyNOd9+G22/ILUC9TVLTeYOuJ1kwa1Gpr+0LWKHc6GqHiLWNL33+exoQ==}
/@vueuse/shared/8.2.5_vue@3.2.33:
resolution: {integrity: sha512-lNWo+7sk6JCuOj4AiYM+6HZ6fq4xAuVq1sVckMQKgfCJZpZRe4i8es+ZULO5bYTKP+VrOCtqrLR2GzEfrbr3YQ==}
/@vueuse/shared/8.4.2_vue@3.2.33:
resolution: {integrity: sha512-hILXMEjL8YQhj1LHN/HZ49UThyfk8irTjhele2nW+L3N55ElFUBGB/f4w0rg8EW+/suhqv7kJJPTZzvHCqxlIw==}
peerDependencies:
'@vue/composition-api': ^1.1.0
vue: ^2.6.0 || ^3.2.0
@ -1091,7 +1093,6 @@ packages:
dependencies:
vue: 3.2.33
vue-demi: 0.12.1_vue@3.2.33
dev: true
/abab/2.0.5:
resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==}
@ -2758,7 +2759,7 @@ packages:
'@histoire/controls': 0.2.5_vue@3.2.33
'@iconify/vue': 3.2.1_vue@3.2.33
'@vitejs/plugin-vue': 2.3.1_vite@2.9.7+vue@3.2.33
'@vueuse/core': 8.2.5_vue@3.2.33
'@vueuse/core': 8.4.2_vue@3.2.33
birpc: 0.1.1
case: 1.6.3
chokidar: 3.5.3
@ -4108,6 +4109,10 @@ packages:
get-port: 3.2.0
dev: true
/tailwindcss-safe-area/0.2.2:
resolution: {integrity: sha512-sygGuEFFBBzjqR6d2gB9hDW9xX/4yLt7ymhR2E/XVa6Ar4B86Net8/9EmPAsqFUvXY40+W0HnXwFavFJEM+eCQ==}
dev: false
/tailwindcss-themeable/1.3.0:
resolution: {integrity: sha512-AmZrk3yAZaJqfrbGast24KrFDtD21rwil05xuqNMFPWTswCHyFugetPk9vy1X+KD4ZTAFWZwW2ULov6VUeK/1A==}
dev: true

View File

@ -1,6 +1,9 @@
<template>
<div class="flex h-full">
<aside class="navbar fixed h-full overflow-y-auto" style="background: #fff">
<aside
class="hidden md:block navbar fixed h-full overflow-y-auto"
style="background: #fff"
>
<div class="logo flex justify-center py-5">
<img :src="logo" alt="Halo Logo" style="width: 78px" />
</div>
@ -27,23 +30,77 @@
</div>
</div>
</aside>
<main class="content w-full overflow-y-auto">
<main class="content w-full overflow-y-auto mb-safe pb-12 md:pb-0">
<slot />
</main>
<!--bottom nav bar-->
<div
class="md:hidden bottom-nav-bar grid grid-cols-6 fixed left-0 bottom-0 right-0 border-t-2 border-black drop-shadow-2xl pb-safe mt-safe"
style="background: #0e1731"
>
<div
v-for="(menu, index) in minimenus"
:key="index"
:class="{ 'bg-black': route.path === menu.path }"
class="nav-item"
@click="router.push(menu.path)"
>
<div
class="p-1 w-full cursor-pointer flex items-center justify-center text-white"
>
<div
class="w-10 h-10 flex flex-col justify-center items-center is-active is-active0"
>
<div class="text-base">
<Component :is="menu.icon" />
</div>
<div class="text-xs mt-0.5">
{{ menu.name }}
</div>
</div>
</div>
</div>
<div class="nav-item" @click="moreMenuVisible = true">
<div
class="p-1 w-full cursor-pointer flex items-center justify-center text-white"
>
<div
class="w-10 h-10 flex flex-col justify-center items-center is-active is-active0"
>
<div class="text-base">
<IconMore />
</div>
<div class="text-xs mt-0.5">更多</div>
</div>
</div>
</div>
<VModal v-model:visible="moreMenuVisible" title="菜单">
<VRoutesMenu :menus="menus" class="p-0" />
</VModal>
</div>
</div>
</template>
<script lang="ts" setup>
import { VRoutesMenu } from "@/components/base/menu";
import { VTag } from "@/components/base/tag";
import { menus } from "@/router/menus.config";
import { VModal } from "@/components/base/modal";
import { menus, minimenus } from "@/router/menus.config";
import logo from "@/assets/logo.svg";
import { IconMore, IconUserSettings } from "@/core/icons";
import { useRoute, useRouter } from "vue-router";
import { ref } from "vue";
const route = useRoute();
const router = useRouter();
const moreMenuVisible = ref(false);
</script>
<style lang="scss">
.navbar {
width: 270px;
@apply w-64;
z-index: 999;
box-shadow: 0 4px 4px #f6c6ce;
padding-bottom: 70px;
@ -53,9 +110,9 @@ import { IconMore, IconUserSettings } from "@/core/icons";
position: fixed;
left: 0;
bottom: 0;
width: 270px;
height: 70px;
display: flex;
@apply w-64;
@apply p-3;
.profile-avatar {
@ -76,7 +133,8 @@ import { IconMore, IconUserSettings } from "@/core/icons";
}
.content {
margin-left: 270px;
@apply ml-0;
@apply md:ml-64;
display: flex;
flex: auto;
flex-direction: column;

View File

@ -103,6 +103,34 @@ export const menus: MenuGroupType[] = [
},
];
export const minimenus: MenuItemType[] = [
{
name: "仪表盘",
path: "/",
icon: IconDashboard,
},
{
name: "文章",
path: "/posts",
icon: IconBookRead,
},
{
name: "评论",
path: "/comment",
icon: IconMessage,
},
{
name: "附件",
path: "/attachment",
icon: IconFolder,
},
{
name: "用户",
path: "/users",
icon: IconUserSettings,
},
];
export type { MenuItemType, MenuGroupType };
export default menus;

View File

@ -2,7 +2,7 @@
<FilledLayout>
<header class="bg-white">
<div class="h-48 bg-gradient-to-r from-gray-800 to-red-500"></div>
<div class="mx-auto px-4 sm:px-6 lg:px-8">
<div class="px-4 sm:px-6 lg:px-8">
<div class="-mt-12 sm:-mt-16 flex items-end space-x-5">
<div class="flex">
<img

View File

@ -6,6 +6,7 @@ module.exports = {
extend: {},
},
plugins: [
require("tailwindcss-safe-area"),
themeable({
defaultTheme: "default",
themes: [