Browse Source

基本的账户首页框架

mrh 1 year ago
parent
commit
de44239fac

+ 1 - 0
package-lock.json

@@ -8,6 +8,7 @@
       "name": "siweilian",
       "version": "0.0.0",
       "dependencies": {
+        "@element-plus/icons-vue": "^2.3.1",
         "amis": "^3.6.4",
         "element-plus": "^2.5.3",
         "nodemon": "^3.0.1",

+ 1 - 0
package.json

@@ -9,6 +9,7 @@
     "start": "nodemon"
   },
   "dependencies": {
+    "@element-plus/icons-vue": "^2.3.1",
     "amis": "^3.6.4",
     "element-plus": "^2.5.3",
     "nodemon": "^3.0.1",

+ 22 - 10
src/App.vue

@@ -1,15 +1,21 @@
 <script setup>
     import { ref } from 'vue'
     import Head from '@/views/home/head.vue'; 
+    import Aside from './views/aside/index.vue'; 
 </script>
 <template>
-      <el-container >
-        <el-header id="Head">
+      <el-container style="height: 100vh; ">
+        <el-header id="Head" height="50px" >
             <Head></Head>
         </el-header>
-        
-        <el-main >
-            <router-view />
+        <el-main style="" class="app-main-container">
+            <el-container style="height: 100%; ">
+                <!-- <Aside v-if="$route.path !== '/'"  class="aside-container" /> -->
+                <el-aside v-if="$route.path !== '/'" class="aside-container" ><Aside></Aside></el-aside>
+                <el-main >
+                    <router-view />
+                </el-main>
+            </el-container>
         </el-main>
       </el-container>
 </template>
@@ -18,16 +24,22 @@
 #Head  {
     border: 1px solid;
     border-color: rgb(227, 227, 227);
+    padding: 0px 0px;
 }
 
-#app .el-container {
-    height: 100vh; 
-    display: flex; 
-    flex-direction: column;
-}
+.app-main-container {
+    height: 100%; 
+    margin: 0px;
+    padding: 0px;
+} 
 
 .el-main{
     background-color: rgb(233,241,253);
 }
 
+.aside-container{
+    width: 200px;
+    height: 100%; 
+}
+
 </style>

+ 6 - 0
src/main.js

@@ -6,9 +6,15 @@ import ElementPlus from 'element-plus'
 import 'element-plus/dist/index.css'
 import eventBus from 'vue3-eventbus'
 import store from './store'
+import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+
 // import vue3videoPlay from "vue3-video-play"; // 引入组件
 // import "vue3-video-play/dist/style.css"; // 引入css
 const app = createApp(App)
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+    app.component(key, component)
+  }
+  
 // app.use(vue3videoPlay);
 app.use(ElementPlus)
 app.use(router)

+ 0 - 1
src/router/index.js

@@ -13,7 +13,6 @@ const routes = [
   {  
     path: '/account',  
     name: 'Account',  
-    props: true,
     component: Account  
   },
   {  

+ 46 - 0
src/views/account/HeaderAccount.vue

@@ -0,0 +1,46 @@
+<template lang="">
+    <el-row justify="end" style="margin:0px;width:100%" v-if="user">
+        <el-col :span="2">
+            <Message></Message>
+        </el-col>
+        <el-col :span="4">
+            <UserName :user="user"></UserName>
+        </el-col>
+    </el-row>
+</template>
+
+<script lang="js" setup>
+import { computed, ref, onMounted } from 'vue';  
+import { useStore } from 'vuex';  
+import UserName from './UserName.vue'
+import Message from './Message.vue';
+import createApiClient from '@/api/client.js';  
+import axios from 'axios';  
+  
+const API_URLS = import.meta.env.VITE_API_URLS.split(',');  
+const store = useStore();  
+const user = ref(null)
+
+
+const apiClient = createApiClient(API_URLS);  
+  
+const loadUserInfo = async () => {
+  try {  
+    const response = await apiClient.get('/user_info');  
+    user.value = response.data;
+  } catch (error) {  
+    console.error('Failed to load user info after all retries', error);  
+    // 这里可以添加进一步的错误处理  
+  }  
+};  
+  
+onMounted(loadUserInfo);  
+
+</script>
+
+<style lang="css" scoped>
+.header-account {  
+    /* margin-left: auto; */
+    margin-right: 18px;
+}  
+</style>

+ 32 - 0
src/views/account/Message.vue

@@ -0,0 +1,32 @@
+<template lang="">
+    <div style="height:100%;">
+        <el-badge :value=messageValue class="item" :hidden=isHidden>
+            <el-button :icon="Bell" id="message-btn"></el-button>
+        </el-badge>
+        <!-- <el-icon ><Bell /></el-icon> -->
+    </div>
+</template>
+
+<script lang="js" setup>
+import { Bell } from '@element-plus/icons-vue'
+import { ref,computed } from 'vue'
+const messageValue = ref(1)
+const isHidden = computed(() => messageValue.value === 0);  
+
+</script>
+
+<style lang="css" scoped>
+.el-button{
+    padding: 0px;
+    border: 0px;
+    margin: auto;
+}
+#message-btn{
+    font-size: 20px;
+    margin-left: 18px;
+}
+.item {
+  margin-top: 0px;
+  margin-right: 0px;
+}
+</style>

+ 37 - 0
src/views/account/UserName.vue

@@ -0,0 +1,37 @@
+<template lang="">
+    <el-dropdown :show-timeout=0>
+        <!-- <el-button
+            v-for="button in buttons"
+            :key="button.text"
+            :type="button.type"
+            text
+            >{{ user.nickname }}
+            <el-icon class="el-icon--right"><arrow-down /></el-icon>
+        </el-button> -->
+        <el-button  >
+            {{ user.nickname }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
+      </el-button>
+    <template #dropdown>
+      <el-dropdown-menu>
+        <el-dropdown-item>账号中心</el-dropdown-item>
+        <el-dropdown-item>充值续费</el-dropdown-item>
+        <el-dropdown-item divided><el-text class="mx-1" type="danger">退出登录</el-text></el-dropdown-item>
+      </el-dropdown-menu>
+    </template>
+  </el-dropdown>
+</template>
+
+<script setup>
+// 正确地声明 props  
+defineProps({  
+  user: {  
+    type: Object,  
+    required: true  
+  }  
+});  
+
+</script>
+
+<style lang="css" scoped>
+   
+</style>

+ 2 - 29
src/views/account/index.vue

@@ -1,36 +1,9 @@
 <template>  
     <div >
-            <h1>用户主页</h1>  
-            <div v-if="user">  
-                <h1>Welcome, {{ user.nickname }}!</h1>  
-                <img :src="user.avatar" alt="User Avatar" />  
-            </div>  
+        <h1>首页</h1>  
     </div>
 
 </template>  
-<script setup>  
-import { computed, ref, onMounted } from 'vue';  
-import { useStore } from 'vuex';  
-import Head from '@/views/home/head.vue';  
-import createApiClient from '@/api/client.js';  
-import axios from 'axios';  
-  
-const API_URLS = import.meta.env.VITE_API_URLS.split(',');  
-const store = useStore();  
-const user = ref(null)
+<script lang="js" setup>  
 
-
-const apiClient = createApiClient(API_URLS);  
-  
-const loadUserInfo = async () => {
-  try {  
-    const response = await apiClient.get('/user_info');  
-    user.value = response.data;
-  } catch (error) {  
-    console.error('Failed to load user info after all retries', error);  
-    // 这里可以添加进一步的错误处理  
-  }  
-};  
-  
-onMounted(loadUserInfo);  
 </script>

+ 0 - 13
src/views/account/sidebar.vue

@@ -1,13 +0,0 @@
-<template lang="">
-    <div>
-        
-    </div>
-</template>
-
-<script setup>
-   
-</script>
-
-<style lang="" scoped>
-   
-</style>

+ 34 - 0
src/views/aside/CollapseBtn.vue

@@ -0,0 +1,34 @@
+<template lang="">
+    <div>
+        <div class="aside-btn">
+            <el-icon id="collapse-btn"><Fold /></el-icon>
+        </div>
+    </div>
+
+</template>
+
+<script setup>
+   
+</script>
+
+<style lang="css" scoped>
+.aside-div {  
+  position: relative; /* 确保子元素可以相对于此容器定位 */  
+  width: 30px;
+  padding-left: 15px;
+} 
+.aside-btn {  
+    position: fixed; /* 悬浮定位 */  
+    bottom: 0; /* 底部对齐 */  
+    left: 0; /* 左侧对齐,根据需要调整 */  
+    font-size: 25px;
+    color: #504e4e;
+}
+.aside-btn:hover{
+    background-color: #d0d0d0; /* 背景色,根据需要调整 */  
+}
+#collapse-btn:hover{
+    color: #6e5fdc;
+}
+
+</style>

+ 89 - 0
src/views/aside/Menu.vue

@@ -0,0 +1,89 @@
+<template lang="">
+    <el-menu
+        default-active="2"
+        class="aside"
+        :collapse="isCollapse"
+        @open="handleOpen"
+        @close="handleClose"
+        >
+        <el-menu-item index="1">
+            <el-icon><HomeFilled /></el-icon>
+            <span>首页</span>
+        </el-menu-item>
+        <el-menu-item index="2">
+            <el-icon><Notebook /></el-icon>
+            <span>知识中心</span>
+        </el-menu-item>
+        <el-menu-item index="3" >
+            <el-icon><SetUp /></el-icon>
+            <span>功能扩展</span>
+        </el-menu-item>
+        <el-menu-item index="4">
+            <el-icon><Setting /></el-icon>
+            <span>设置</span>
+        </el-menu-item>
+
+        <el-menu-item v-for="(item, index) in menuItems" :key="index" :index="`${index + 1}`">  
+            <el-icon :name="item.icon"></el-icon>  
+            <span>{{ item.label }}</span>  
+        </el-menu-item>  
+    </el-menu>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+const isCollapse = ref(false)
+// 生成指定数量的 menuItems  
+const generateMenuItems = (num) => {  
+  const items = [];  
+  for (let i = 1; i <= num; i++) {  
+    // 假设图标名称和标签有一定的规律,这里使用了简单的示例  
+    items.push({  
+      icon: `el-icon-menu-${i % 5}`, // 假设有5种图标循环使用  
+      label: `菜单项${i}`  
+    });  
+  }  
+  return items;  
+};  
+  
+// 创建一个响应式数组来存储菜单项,并初始化为20个菜单项  
+const menuItems = ref(generateMenuItems(20));
+const handleOpen = ()=>{
+
+}
+const handleClose = ()=>{
+
+}
+
+
+</script>
+
+<style lang="css" scoped>
+   
+.aside {  
+    height: 100%; 
+    overflow-y: auto;
+}
+
+.el-menu{
+    height: 100%;
+}
+
+.el-menu::-webkit-scrollbar {  
+    width: 6px; /* 滚动条的宽度 */ 
+    height: 10px; 
+}  
+
+.el-menu::-webkit-scrollbar-track {  
+    background: transparent; /* 滚动条轨道的背景色 */  
+}  
+  
+.el-menu::-webkit-scrollbar-thumb {  
+    background: #c8c8c8; /* 滚动条的背景色 */  
+    border-radius: 10px; /* 滚动条的圆角 */  
+}  
+  
+.el-menu::-webkit-scrollbar-thumb:hover {  
+    background: #7b7a7a; /* 滚动条悬停时的背景色 */  
+}
+</style>

+ 18 - 0
src/views/aside/index.vue

@@ -0,0 +1,18 @@
+<template lang="">
+    <div class="aside-div">
+        <Menu></Menu>
+        <CollapseBtn></CollapseBtn>
+    </div>
+    
+</template>
+
+<script lang="js" setup >
+import { ref } from 'vue'
+import Menu from "./Menu.vue"
+import CollapseBtn from './CollapseBtn.vue'
+</script>
+
+<style lang="css" scoped>
+
+
+</style>

+ 10 - 3
src/views/home/head.vue

@@ -1,20 +1,27 @@
 <template lang="">
     <div >
         <el-row style="height: 100%;">
-            <el-col :span="9">
+            <el-col :span="6">
                     <el-avatar id="logo" :size="30" :src="avatarUrl" />
                     <el-text id="pro_name" class="title-text" >思维链</el-text>
             </el-col>
+            <el-col :span="18">
+                <HeaderAccount></HeaderAccount>
+            </el-col>
         </el-row>
     </div>
 </template>
 
-<script setup>
+<script lang="js" setup>
+import HeaderAccount from '../account/HeaderAccount.vue';
 const avatarUrl='https://s3.magong.site/swl/web/avatar.jpg'  
 
 </script>
 
 <style lang="css" scoped>
+.el-avatar{
+    margin-left: 15px;
+}
 .el-col {
   display: flex;
   align-items: center;
@@ -22,7 +29,7 @@ const avatarUrl='https://s3.magong.site/swl/web/avatar.jpg'
 #pro_name {
     color: rgb(36, 36, 36);  
     font-size: 18px;
-    margin-left: 15px;
+    margin-left: 10px;
 }
 
 </style>