feat:增加移动端布局
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"dev": "vite --host 0.0.0.0",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
|
||||
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 481 KiB |
37
src/layout/components/Mobile/MobileDrawer.vue
Normal file
37
src/layout/components/Mobile/MobileDrawer.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<el-drawer v-model="appStore.drawerVisible" direction="ltr" size="250px" :with-header="false">
|
||||
<div class="drawer-content">
|
||||
<div class="drawer-user">
|
||||
<el-avatar :src="getAssetsImageFile('avatar.jpg')"/>
|
||||
<div class="user-info">
|
||||
<div class="title">{{ appStore.blogTitle }}</div>
|
||||
<div class="sub-title">{{ appStore.blogSubTitle }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-menu router @select="appStore.drawerVisible = false">
|
||||
<el-menu-item index="/overview">
|
||||
<i class="fa fa-fw fa-home" />
|
||||
<span>首页</span>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="/category">
|
||||
<i class="fa fa-fw fa-th" />
|
||||
<span>分类</span>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="/archive">
|
||||
<i class="fa fa-fw fa-archive" />
|
||||
<span class="menu-title">归档</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/store/app'
|
||||
import { getAssetsImageFile } from '@/utils'
|
||||
|
||||
const appStore = useAppStore()
|
||||
</script>
|
||||
17
src/layout/components/Mobile/MobileHeader.vue
Normal file
17
src/layout/components/Mobile/MobileHeader.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div class="mobile-header">
|
||||
<el-image :src="getAssetsImageFile('logo.png')" class="mobile-logo"/>
|
||||
<div class="mobile-title">{{ appStore.title }}</div>
|
||||
<el-button type="primary" text @click="appStore.drawerVisible = true">
|
||||
<el-icon size="24"><Menu /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Menu } from '@element-plus/icons-vue'
|
||||
import { useAppStore } from '@/store/app'
|
||||
import { getAssetsImageFile } from '@/utils'
|
||||
|
||||
const appStore = useAppStore()
|
||||
</script>
|
||||
@@ -1,15 +1,11 @@
|
||||
<template>
|
||||
<div class="title-container">
|
||||
<span class="title">{{ blogTitleInfo.title }}</span>
|
||||
<span class="sub-title">{{ blogTitleInfo.subTitle }}</span>
|
||||
<span class="title">{{ appStore.blogTitle }}</span>
|
||||
<span class="sub-title">{{ appStore.blogSubTitle }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const blogTitleInfo = reactive({
|
||||
title: 'NJCxx0822',
|
||||
subTitle: '不要因为别人5%的负面评价而否定自己100%的努力。'
|
||||
})
|
||||
import { useAppStore } from '@/store/app'
|
||||
const appStore = useAppStore()
|
||||
</script>
|
||||
|
||||
@@ -43,6 +43,7 @@ import { Ribbon } from '@/utils/blog/ribbon'
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import { useBlogStore } from '@/store/blog.ts'
|
||||
import { useAppStore } from '@/store/app.ts'
|
||||
import { isMobile } from 'vue3-common/utils/layoutUtil'
|
||||
|
||||
const ribbon = new Ribbon()
|
||||
const blogStore = useBlogStore()
|
||||
@@ -62,10 +63,12 @@ const handleClick = (event) => {
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('scroll', () => {
|
||||
if (!isMobile()) {
|
||||
const progressBar = document.getElementById('blog_progress') as HTMLProgressElement
|
||||
progressBar.max = document.documentElement.scrollHeight - window.innerHeight
|
||||
progressBar.value = window.scrollY
|
||||
blogStore.progressValue = `${(progressBar.value / progressBar.max * 100).toFixed(0)}%`
|
||||
}
|
||||
})
|
||||
|
||||
document.addEventListener('click', handleClick)
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<section class="blog-container" id="blog-container">
|
||||
<section v-if="appStore.isMobile" class="mobile-layout">
|
||||
<mobile-header />
|
||||
<router-view/>
|
||||
|
||||
<mobile-drawer />
|
||||
|
||||
<footer-bar />
|
||||
</section>
|
||||
|
||||
<section v-else class="blog-container" id="blog-container">
|
||||
<tools />
|
||||
|
||||
<sidebar />
|
||||
@@ -13,9 +22,29 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MobileHeader from '@/layout/components/Mobile/MobileHeader.vue'
|
||||
import MobileDrawer from '@/layout/components/Mobile/MobileDrawer.vue'
|
||||
import Tools from '@/layout/components/Tools/index.vue'
|
||||
import Sidebar from '@/layout/components/Sidebar/index.vue'
|
||||
import FooterBar from '@/layout/components/FooterBar/index.vue'
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import { useAppStore } from '@/store/app'
|
||||
import { isMobile } from 'vue3-common/utils/layoutUtil'
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const checkScreen = () => {
|
||||
appStore.isMobile = isMobile()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
checkScreen()
|
||||
window.addEventListener('resize', checkScreen)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', checkScreen)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -4,6 +4,11 @@ import { useDark, useToggle } from '@vueuse/core'
|
||||
export const useAppStore = defineStore('ipp', {
|
||||
state: () => ({
|
||||
isDark: false,
|
||||
isMobile: false,
|
||||
drawerVisible: false,
|
||||
title: '拾光记',
|
||||
blogTitle: 'NJCxx0822',
|
||||
blogSubTitle: '不要因为别人5%的负面评价而否定自己100%的努力。',
|
||||
version: 'v1.0.0.2025042901'
|
||||
}),
|
||||
actions: {
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
0 3px 1px -2px rgba(0,0,0,0.06),
|
||||
0 1px 5px 0 rgba(0,0,0,0.12),
|
||||
0 -1px 0.5px 0 rgba(0,0,0,0.09);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.module-title {
|
||||
background-color: blog.$theme-color;
|
||||
@@ -44,9 +47,6 @@
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
font-size: blog.$large-font-size;
|
||||
font-family: "华文楷体", serif;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-item {
|
||||
@@ -55,6 +55,77 @@
|
||||
border-radius: blog.$border-radius;
|
||||
// box-shadow: 3px 3px 3px #CFCFCF;
|
||||
}
|
||||
|
||||
.mobile-layout {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
.mobile-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background: white;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.mobile-logo {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.mobile-title {
|
||||
font-size: large;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer-content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.drawer-user {
|
||||
padding: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: 50px 1fr;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
border-bottom: 1px solid gray;
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.title {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: smaller;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
flex: 1;
|
||||
border: none;
|
||||
|
||||
.el-menu-item {
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user