Ver Fonte

style: 大量组件使用element-plus替换,统一视觉效果

Jinyao há 5 anos atrás
pai
commit
f12c8515c0

+ 0 - 2
babel.config.js

@@ -4,8 +4,6 @@ module.exports = {
       'import',
       {
         libraryName: 'element-plus',
-        // 由于 customStyleName 在配置中被声明的原因,`style: true` 会被直接忽略掉,
-        // 如果你需要使用 scss 源文件,把文件结尾的扩展名从 `.css` 替换成 `.scss` 就可以了
         customStyleName: (name) => `element-plus/lib/theme-chalk/${name}.css`
         ,
       },

+ 9 - 12
src/App.vue

@@ -1,35 +1,32 @@
 <template>
-  <Menu
-    :project-list="projectList"
-    :selected-project="selectedProject"
-    @project-change="handleProjectChange"></Menu>
-  <router-view/>
+  <el-header>
+    <Menu></Menu>
+  </el-header>
+  <el-container>
+    <router-view/>
+  </el-container>
 </template>
 
 <script lang="ts">
 import { defineComponent } from 'vue';
 import Menu from '@/components/Menu.vue';
 
-import { useProjectList } from '@/composable/useProject';
 import { getVariableFromQueryString } from '@/utils/qs';
 import { WorkspaceDispatcher, UserDispatcher, TokenDispatcher } from './store/dispatchers';
+import { useStore } from './store';
 
 export default defineComponent({
   components: { Menu },
   setup() {
+    const store = useStore();
+    console.log(store.state);
     const token = getVariableFromQueryString('id_token');
     if (token) {
       TokenDispatcher.updateToken(token);
     }
 
-    const { projectList, selectedProject, handleProjectChange } = useProjectList();
     UserDispatcher.updateUserInfo();
     WorkspaceDispatcher.refreshProjectList();
-    return {
-      projectList,
-      selectedProject,
-      handleProjectChange,
-    };
   },
 });
 </script>

+ 97 - 124
src/components/Menu.vue

@@ -1,146 +1,119 @@
 <template>
-  <div id="menu" class="menu-container">
-    <div class="menu-logo">
+  <ElMenu class="menu" mode="horizontal" @select="handleSelect">
+    <ElMenuItem class="menu-logo" index="logo" disabled>
       LOGO
-    </div>
-    <div class="project-switcher" v-show="projectList.length>0" ref="switcher">
-      <div class="selected-project-name">{{selectedProject.name}}</div>
-      <div class="icon" @click="handleSwitcherClick"></div>
-      <transition name="expand">
-        <div class="dropdown" v-show="isDropDownExpand">
-          <div
-            v-for="item in projectList"
-            :key="item.id"
-            class="item"
-            @click="handleProjectChange(item)">{{item.name}}</div>
-        </div>
-      </transition>
-    </div>
-    <div class="notify"></div>
-    <div class="user"></div>
-  </div>
+    </ElMenuItem>
+    <ElSubmenu index="group">
+      <template #title>{{selectedGroup.name}}</template>
+      <template  v-if="groupList.length > 0">
+      <ElMenuItem v-for="group in groupList" :key="group.id" :index="`group-${group.id}`">{{group.name}}</ElMenuItem>
+      </template>
+      <template v-else>
+        <ElMenuItem disabled>暂未加入任何小组</ElMenuItem>
+      </template>
+    </ElSubmenu>
+    <ElSubmenu index="project">
+      <template #title>{{selectedProject.name}}</template>
+      <template v-if="projectList.length > 0">
+        <ElMenuItem v-for="project in projectList" :key="project.id" :index="`project-${project.id}`">{{project.name}}</ElMenuItem>
+      </template>
+      <template v-else-if="selectedGroup.id === -1">
+        <ElMenuItem disabled>请先选择小组</ElMenuItem>
+      </template>
+      <template v-else>
+        <ElMenuItem disabled>该小组暂无项目</ElMenuItem>
+      </template>
+    </ElSubmenu>
+      <template v-if="userLoggedIn">
+        <ElSubmenu index="user" class="user">
+          <template #title>{{userInfo.username}}</template>
+          <ElMenuItem index="user-create">创建小组</ElMenuItem>
+          <ElMenuItem index="user-join">加入小组</ElMenuItem>
+          <ElMenuItem index="user-logout">登出</ElMenuItem>
+        </ElSubmenu>
+      </template>
+      <template v-else>
+        <ElLink type="primary" href="/login" class="user">登录</ElLink>
+      </template>
+  </ElMenu>
 </template>
 
-<script>
-export default {
+<script lang="ts">
+import { useProjectList } from '@/composable/useProject';
+import { useGroupList } from '@/composable/useGroup';
+import { useUser } from '@/composable/useUser';
+import { defineComponent } from 'vue';
+
+export default defineComponent({
   name: 'Menu',
-  props: {
-    projectList: Array,
-    selectedProject: Object,
-  },
-  data() {
+  setup(_, { emit }) {
+    const { projectListOfCurrentGroup: projectList, selectedProject, handleProjectChange } = useProjectList();
+    const { groupList, selectedGroup, handleGroupChange } = useGroupList();
+    const { userInfo, userLoggedIn, userLogOut } = useUser();
+
+    const handleSelect = (index: string) => {
+      const [type, id] = index.split('-');
+      switch (type) {
+        case 'logo': {
+          break;
+        }
+        case 'project': {
+          handleProjectChange(parseInt(id, 10));
+          break;
+        }
+        case 'group': {
+          handleGroupChange(parseInt(id, 10));
+          break;
+        }
+        case 'user': {
+          if (id === 'create') {
+            emit('show-create-group-drawer');
+          } else if (id === 'join') {
+            emit('show-join-group-drawer');
+          } else if (id === 'logout') {
+            userLogOut();
+          }
+          break;
+        }
+        default:
+          console.warn('unknown type of sub-menu');
+          break;
+      }
+    };
+
     return {
-      isDropDownExpand: false,
+      projectList,
+      selectedProject,
+      groupList,
+      selectedGroup,
+      handleSelect,
+      userInfo,
+      userLoggedIn,
+      userLogOut,
     };
   },
-  mounted() {
-    document.addEventListener('click', (e) => {
-      if (!this.$refs.switcher.contains(e.target)) {
-        this.isDropDownExpand = false;
-      }
-    });
-  },
-  methods: {
-    handleSwitcherClick() {
-      this.isDropDownExpand = !this.isDropDownExpand;
-    },
-    handleProjectChange(item) {
-      this.$emit('project-change', item.id);
-      this.isDropDownExpand = !this.isDropDownExpand;
-    },
-  },
-};
+});
 </script>
 
 <style scoped>
-.menu-container{
-  height: 58px;
+.menu {
   width: 100%;
-  position: fixed;
-  top:0px;
-  background-color: #34495E;
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  justify-content: flex-start;
-  z-index: 100;
 }
-.menu-logo{
-  color: #FFFFFF;
+.menu-logo {
+  color: #000000;
   font-size: 24px;
   font-weight: bolder;
   line-height: 58px;
   margin-left: 30px;
   transition: all .2s linear;
 }
-.menu-logo:hover{
-  color: #BDC3C7;
-}
-.project-switcher{
-  margin-left: 20px;
-  background-color: #2C3E50;
-  height: 30px;
-  padding: 5px;
-  width: 240px;
-  display: flex;
-  flex-direction: row;
-  justify-content: flex-start;
-  align-items: center;
-  border-radius: 5px;
-  position: relative;
-}
-.project-switcher .icon{
-  width: 24px;
-  height: 24px;
-  cursor: pointer;
-  margin-left: auto;
-  background-position: center;
-  background-repeat: no-repeat;
-  background-size: 100% 100%;
-  transition: all .2s linear;
-  background-image: url("../assets/icon/menu.svg");
-}
-.project-switcher .icon:hover{
-  background-image: url("../assets/icon/menu-hover.svg");
-}
-.project-switcher .dropdown{
-  width: 240px;
-  position: absolute;
-  background-color: #2C3E50;
-  color: #FFFFFF;
-  top: 39px;
-  left: 0px;
-  padding: 5px;
-  border-radius: 0 0 5px 5px;
-  flex-direction: column;
-  justify-content: center;
-  align-items: start;
-  transform-origin: 0px 0px;
-}
-.expand-enter-active,.expand-leave-active{
-  transition: all .3s ease-in-out;
-}
-.expand-enter-from,.expand-leave-to{
-  opacity: 0;
-  transform: scaleY(0);
-}
-.project-switcher .selected-project-name{
-  width: 220px;
-  line-height: 30px;
-  color: #FFFFFF;
-  text-align: start;
-  text-overflow: ellipsis;
-  white-space:nowrap; overflow:hidden
-}
-.project-switcher .dropdown .item{
-  line-height: 24px;
-  width: 240px;
-  text-align: start;
-  text-overflow: ellipsis;
-  white-space:nowrap; overflow:hidden;
-  cursor: pointer;
+.menu-logo.is-disabled {
+  opacity: 1;
+  cursor: default;
 }
-.project-switcher .dropdown .item:hover{
-  background-color: #34495E;
+.user {
+  float: right;
+  height: 60px;
+  margin: 0 20px;
 }
 </style>

+ 11 - 22
src/components/ProjectCard.vue

@@ -1,10 +1,11 @@
 <template>
-  <div class="project-card" @click="goToProject(id)">
-    <div class="project-name">{{name}}</div>
-    <div class="project-description">
-      {{description}}
-    </div>
-  </div>
+  <ElCard class="project-card" shadow="hover">
+    <template #header>
+      <span>{{name}}</span>
+    </template>
+    <div>描述:{{description}}</div>
+    <div>链接:{{gitRemoteUrl}}</div>
+  </ElCard>
 </template>
 
 <script lang="ts">
@@ -15,27 +16,15 @@ export default defineComponent({
     id: Number,
     name: String,
     description: String,
-  },
-  methods: {
-    goToProject(id: number) {
-      this.$router.push(`/project/${id}/schedule`);
-    },
+    gitRemoteUrl: String,
+    groupId: Number,
   },
 });
 </script>
 
 <style lang="scss" scoped>
 .project-card {
-  display: inline-block;
-  box-shadow: 0 0 1px #BDC3C7;
-  border-radius: 5px;
-  padding: 10px;
-  height: 150px;
-  width: 320px;
-  margin: 10px auto;
-  transition: all .3s ease;
-}
-.project-card:hover {
-  box-shadow: 0 0 5px #BDC3C7;
+  width: calc(25% - 24px);
+  margin: 12px;
 }
 </style>

+ 68 - 66
src/components/SideBar.vue

@@ -1,12 +1,24 @@
 <template>
-  <div class="side-bar-container" @click="handleClick">
-      <div :class="{icon:true,selected:selectedIndex === 0}" target="schedule"></div>
-      <div :class="{icon:true,selected:selectedIndex === 1}" target="taskList"></div>
-      <div :class="{icon:true,selected:selectedIndex === 2}" target="bugList"></div>
-      <div :class="{icon:true,selected:selectedIndex === 3}" target="statistics"></div>
-      <div :class="{icon:true,selected:selectedIndex === 4}" target="pipeline"></div>
-      <div :class="{icon:true,selected:selectedIndex === 5}" target="apitest"></div>
-  </div>
+  <el-menu default-active="schedule" class="side-bar" collapse="true" router="true">
+    <el-menu-item index="schedule">
+      <i class="icon" target="schedule"></i>
+    </el-menu-item>
+    <el-menu-item index="taskList">
+      <i class="icon" target="taskList"></i>
+    </el-menu-item>
+    <el-menu-item index="bugList">
+      <i class="icon" target="bugList"></i>
+    </el-menu-item>
+    <el-menu-item index="statistics">
+      <i class="icon" target="statistics"></i>
+    </el-menu-item>
+    <el-menu-item index="pipeline">
+      <i class="icon" target="pipeline"></i>
+    </el-menu-item>
+    <el-menu-item index="apitest">
+      <i class="icon" target="apitest"></i>
+    </el-menu-item>
+  </el-menu>
 </template>
 
 <script>
@@ -49,88 +61,78 @@ export default {
 };
 </script>
 
-<style scoped>
-.side-bar-container{
-  width: 42px;
+<style lang="scss" scoped>
+.side-bar {
   height: 100%;
-  position: fixed;
-  top:58px;
-  left: 0;
-  background-color: #ecf0f1;
-  display: flex;
-  flex-direction: column;
-  justify-content: start;
-  align-items: center;
-  padding-top: 20px;
-  z-index: 100;
 }
-.icon{
+.icon {
   width: 28px;
   height: 28px;
+  float: right;
   background-position: center;
   background-repeat: no-repeat;
   background-size: 100% 100%;
-  margin-top:16px;
+  margin-top: 14px;
   transition: all .2s linear;
-}
-.icon:hover{
-  cursor: pointer;
-  transition-duration:0.2s;
-  transform:scale(1.1);
-  transition-timing-function:ease-in-out;
+  .el-menu-item:hover & {
+    cursor: pointer;
+    transition-duration:0.2s;
+    transform:scale(1.1);
+    transition-timing-function:ease-in-out;
+  }
 }
 .icon[target=schedule]{
   background-image: url("../assets/icon/navigation.svg");
-}
-.icon[target=schedule]:hover{
-  background-image: url("../assets/icon/navigation-hover.svg");
-}
-.icon[target=schedule].selected{
-  background-image: url("../assets/icon/navigation-using.svg");
+  .el-menu-item:hover & {
+    background-image: url("../assets/icon/navigation-hover.svg");
+  }
+  .el-menu-item.is-active:hover & {
+    background-image: url("../assets/icon/navigation-using.svg");
+  }
 }
 .icon[target=taskList]{
   background-image: url("../assets/icon/task.svg");
-}
-.icon[target=taskList]:hover{
-  background-image: url("../assets/icon/task-hover.svg");
-}
-.icon[target=taskList].selected{
-  background-image: url("../assets/icon/task-using.svg");
+  .el-menu-item:hover & {
+    background-image: url("../assets/icon/task-hover.svg");
+  }
+  .el-menu-item.is-active:hover & {
+    background-image: url("../assets/icon/task-using.svg");
+  }
 }
 .icon[target=bugList]{
   background-image: url("../assets/icon/bug.svg");
-}
-.icon[target=bugList]:hover{
-  background-image: url("../assets/icon/bug-hover.svg");
-}
-.icon[target=bugList].selected{
-  background-image: url("../assets/icon/bug-using.svg");
+  .el-menu-item:hover & {
+    background-image: url("../assets/icon/bug-hover.svg");
+  }
+  .el-menu-item.is-active:hover & {
+    background-image: url("../assets/icon/bug-using.svg");
+  }
 }
 .icon[target=statistics]{
   background-image: url("../assets/icon/training.svg");
-}
-.icon[target=statistics]:hover{
-  background-image: url("../assets/icon/training-hover.svg");
-}
-.icon[target=statistics].selected{
-  background-image: url("../assets/icon/training-using.svg");
+  .el-menu-item:hover & {
+    background-image: url("../assets/icon/training-hover.svg");
+  }
+  .el-menu-item.is-active:hover & {
+    background-image: url("../assets/icon/training-using.svg");
+  }
 }
 .icon[target=pipeline]{
   background-image: url("../assets/icon/training.svg");
-}
-.icon[target=pipeline]:hover{
-  background-image: url("../assets/icon/training-hover.svg");
-}
-.icon[target=pipeline].selected{
-  background-image: url("../assets/icon/training-using.svg");
+  .el-menu-item:hover & {
+    background-image: url("../assets/icon/training-hover.svg");
+  }
+  .el-menu-item.is-active:hover & {
+    background-image: url("../assets/icon/training-using.svg");
+  }
 }
 .icon[target=apitest]{
-  background-image: url("../assets/icon/training.svg");
-}
-.icon[target=apitest]:hover{
-  background-image: url("../assets/icon/training-hover.svg");
-}
-.icon[target=apitest].selected{
-  background-image: url("../assets/icon/training-using.svg");
+   background-image: url("../assets/icon/training.svg");
+  .el-menu-item:hover & {
+    background-image: url("../assets/icon/training-hover.svg");
+  }
+  .el-menu-item.is-active:hover & {
+    background-image: url("../assets/icon/training-using.svg");
+  }
 }
 </style>

+ 1 - 1
src/components/TreeNode.vue

@@ -49,7 +49,7 @@ export default {
 };
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 .tree-node-container {
   position: absolute;
   height: 140px;

+ 19 - 0
src/composable/useGroup.ts

@@ -0,0 +1,19 @@
+import { computed } from 'vue';
+import { useStore } from '@/store';
+import { WorkspaceDispatcher } from '@/store/dispatchers';
+
+export const useGroupList = () => {
+  const store = useStore();
+
+  const groupList = computed(() => store.state.workspace.groupList);
+  const selectedGroup = computed(() => store.getters.currentGroupInfo);
+
+  const handleGroupChange = (groupId: number) => {
+    WorkspaceDispatcher.changeGroup(groupId);
+  };
+  return {
+    groupList,
+    selectedGroup,
+    handleGroupChange,
+  };
+};

+ 2 - 0
src/composable/useProject.ts

@@ -8,6 +8,7 @@ export const useProjectList = () => {
   const router = useRouter();
 
   const projectList = computed(() => store.state.workspace.projectList);
+  const projectListOfCurrentGroup = computed(() => store.getters.projectListOfCurrentGroup);
   const selectedProject = computed(() => store.getters.currentProjectInfo);
 
   const handleProjectChange = (projectId: number) => {
@@ -16,6 +17,7 @@ export const useProjectList = () => {
   };
   return {
     projectList,
+    projectListOfCurrentGroup,
     selectedProject,
     handleProjectChange,
   };

+ 23 - 0
src/composable/useUser.ts

@@ -0,0 +1,23 @@
+import { computed } from 'vue';
+import { useStore } from '@/store';
+import { UserDispatcher, TokenDispatcher } from '@/store/dispatchers';
+import { useRouter } from 'vue-router';
+
+export const useUser = () => {
+  const store = useStore();
+  const router = useRouter();
+
+  const userInfo = computed(() => store.state.user);
+  const userLoggedIn = computed(() => store.state.user.role !== 'GUEST');
+
+  const userLogOut = () => {
+    UserDispatcher.userLogOut();
+    TokenDispatcher.destroyToken();
+    router.push('/');
+  };
+  return {
+    userInfo,
+    userLoggedIn,
+    userLogOut,
+  };
+};

+ 10 - 0
src/element-plus.ts

@@ -1,11 +1,16 @@
 import {
+  ElAside,
   ElCard,
   ElCarousel,
   ElCarouselItem,
   ElContainer,
   ElDivider,
   ElHeader,
+  ElLink,
   ElMain,
+  ElMenu,
+  ElSubmenu,
+  ElMenuItem,
   ElRow,
   ElTable,
   ElTableColumn,
@@ -18,10 +23,14 @@ import {
 } from 'element-plus';
 
 export const Components = [
+  ElAside,
   ElRow,
   ElContainer,
   ElHeader,
   ElMain,
+  ElMenu,
+  ElLink,
+  ElMenuItem,
   ElCarousel,
   ElCarouselItem,
   ElDivider,
@@ -32,6 +41,7 @@ export const Components = [
   ElButton,
   ElSelect,
   ElOption,
+  ElSubmenu,
   ElTabs,
   ElTabPane,
 ];

+ 0 - 1
src/main.ts

@@ -1,6 +1,5 @@
 import { createApp } from 'vue';
 import { Components, Plugins } from '@/element-plus';
-import 'element-plus/lib/theme-chalk/index.css';
 import { store, key } from '@/store';
 import App from '@/App.vue';
 import router from '@/router';

+ 18 - 18
src/router/index.ts

@@ -67,22 +67,22 @@ const router = createRouter({
   routes,
 });
 
-router.beforeEach((to, from, next) => {
-  if (to.matched.some((record) => record.meta.requiresAuth)) {
-    // this route requires auth, check if logged in
-    // if not, redirect to login page.
-    if (!isUserLoggedIn()) {
-      next({
-        name: LOGIN,
-        query: { redirect: to.fullPath },
-      });
-    } else {
-      next();
-    }
-  } else {
-    next();
-  }
-});
+// router.beforeEach((to, from, next) => {
+//   if (to.matched.some((record) => record.meta.requiresAuth)) {
+//     // this route requires auth, check if logged in
+//     // if not, redirect to login page.
+//     if (!isUserLoggedIn()) {
+//       next({
+//         name: LOGIN,
+//         query: { redirect: to.fullPath },
+//       });
+//     } else {
+//       next();
+//     }
+//   } else {
+//     next();
+//   }
+// });
 
 router.beforeEach((to, from, next) => {
   if (to.name !== LOGIN || !isUserLoggedIn()) {
@@ -92,9 +92,9 @@ router.beforeEach((to, from, next) => {
 
 router.afterEach((to, from) => {
   if (to.matched.some((record) => record.meta.hideNavigator)) {
-    document.getElementById('menu')!.style.display = 'none';
+    document.getElementsByTagName('header')[0]!.style.display = 'none';
   } else {
-    document.getElementById('menu')!.style.display = 'flex';
+    document.getElementsByTagName('header')[0]!.style.display = 'flex';
   }
 });
 

+ 0 - 6
src/store/dispatchers/token.ts

@@ -9,9 +9,3 @@ export const updateToken = (token: string) => {
 export const destroyToken = () => {
   store.dispatch('destoryToken');
 };
-
-export const changeGroup = (groupId: string) => {
-  store.dispatch('changeGroup', {
-    groupId,
-  });
-};

+ 4 - 0
src/store/dispatchers/user.ts

@@ -3,3 +3,7 @@ import { store } from '../index';
 export const updateUserInfo = () => {
   store.dispatch('updateUserInfo');
 };
+
+export const userLogOut = () => {
+  store.dispatch('userLogOut');
+};

+ 1 - 0
src/store/dispatchers/workspace.ts

@@ -10,4 +10,5 @@ export const changeProject = (projectId: number) => {
 
 export const changeGroup = (groupId: number) => {
   store.dispatch('changeGroup', { groupId });
+  store.dispatch('resetCurrentProject');
 };

+ 3 - 0
src/store/modules/user.ts

@@ -17,6 +17,9 @@ const actions: ActionTree<UserState, RootState> = {
     };
     commit('updateUserInfo', res.user_info);
   },
+  userLogOut({ commit }) {
+    commit('updateUserInfo', DEFAULT);
+  },
 };
 
 const mutations: MutationTree<UserState> = {

+ 32 - 1
src/store/modules/workspace.ts

@@ -9,7 +9,28 @@ import {
 const DEFAULT: WorkspaceState = {
   currentProjectId: -1,
   currentGroupId: -1,
-  groupList: [],
+  groupList: [
+    {
+      id: 101,
+      name: 'Group-1',
+    },
+    {
+      id: 102,
+      name: 'Group-2',
+    },
+    {
+      id: 13,
+      name: 'Group-3',
+    },
+    {
+      id: 104,
+      name: 'Group-4',
+    },
+    {
+      id: 105,
+      name: 'Group-5',
+    },
+  ],
   projectList: [],
 };
 
@@ -24,6 +45,9 @@ const actions: ActionTree<WorkspaceState, RootState> = {
   changeProject({ commit }, payload: ChangeProjectPayload) {
     commit('changeProject', payload);
   },
+  resetCurrentProject({ commit }) {
+    commit('changeProject', -1);
+  },
 };
 
 const mutations: MutationTree<WorkspaceState> = {
@@ -49,6 +73,13 @@ const getters: GetterTree<WorkspaceState, RootState> = {
         name: '未选择项目',
       };
   },
+  currentGroupInfo(state) {
+    return Array.prototype.find.call(state.groupList, (group) => group.id === state.currentGroupId)
+      || {
+        id: -1,
+        name: '未选择小组',
+      };
+  },
 };
 
 export const workspace: Module<WorkspaceState, RootState> = {

+ 1 - 1
src/store/typings.ts

@@ -23,7 +23,7 @@ export interface UserState {
 export interface WorkspaceState {
   currentGroupId: GroupId;
   currentProjectId: ProjectId;
-  groupList: Array<GroupId>;
+  groupList: Array<Group>;
   projectList: Array<Project>;
 }
 

+ 5 - 5
src/views/Home.vue

@@ -7,9 +7,8 @@
       <ProjectCard
         v-for="project in projectList"
         :key="project.id"
-        :id="project.id"
-        :name="project.name"
-        :description="project.description"
+        v-bind="project"
+        @click="handleProjectChange(project.id)"
       ></ProjectCard>
     </div>
   </div>
@@ -26,18 +25,19 @@ export default defineComponent({
     ProjectCard,
   },
   setup() {
-    const { projectList } = useProjectList();
+    const { projectList, handleProjectChange } = useProjectList();
     const store = useStore();
     return {
       projectList,
       username: computed(() => store.state.user.username),
+      handleProjectChange,
     };
   },
 });
 </script>
 <style scoped>
 .home{
-  margin-top: 58px ;
+  width: 100%;
 }
 .project-list {
   display:flex;

+ 5 - 7
src/views/ProjectContainer.vue

@@ -1,10 +1,10 @@
 <template>
-  <div>
+  <el-aside width="65">
     <SideBar @change="handleTabChange"></SideBar>
-    <div class="container">
-      <router-view></router-view><!--此处路由路由4个功能页-->
-    </div>
-  </div>
+  </el-aside>
+  <el-main class="container">
+    <router-view></router-view>
+  </el-main>
 </template>
 
 <script>
@@ -25,8 +25,6 @@ export default {
 .container{
   background-color: #FFFFFF;
   width: calc(100% - 42px);
-  margin-top: 58px;
-  margin-left: 42px;
   min-height: 60vh;
 }
 .content{