阶段案例——后台管理系统

一、基本概念

二、运行效果及部分代码

1、运行效果

2、代码目录

3、部分代码

APP.VUE

复制代码
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <router-view></router-view>
</template>

Home.vue

复制代码
<template>
  <div class="home-wrap">
    <!--头部-->
    <MyHeader></MyHeader>
    <div class="main-content">
      <!--侧边栏-->
      <MyAside></MyAside>
      <!--内容区域-->
      <div class="page-main">
        <router-view></router-view>
      </div>
    </div>
  </div>
</template>

<script setup>
import MyHeader from './subcomponents/MyHeader.vue'
import MyAside from './subcomponents/MyAside.vue'
</script>

<style scoped lang="less">
.home-wrap {
  height: 100vh;
  display: flex;
  flex-direction: column;
}
.main-content {
  flex:1;
  display:flex;
  .page-main {
    flex:1;
    padding:15px;
    background:#f6f6f6;
  }
}
</style>

MyHeader.vue

复制代码
<template>
  <div class="layout-header-container">
    <div class="layout-header-left">
      <img src="../../assets/logo.png" class="logo-img" alt="">
      <h4>商城后台管理系统</h4>
    </div>
    <div class="layout-header-right">
      <button @click="onLogout">退出</button>
    </div>
  </div>
</template>

<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const onLogout = () => {
  localStorage.removeItem('token')
  router.push('/login')
}
</script>

<style scoped lang="less">
.layout-header-container {
  height:60px;
  background:#409eff;
  display:flex;
  justify-content:space-between;
  align-items:center;
  padding:0 20px;
  color:#fff;
  .layout-header-left {
    display:flex;
    align-items:center;
    gap:10px;
    .logo-img {
      width:36px;
    }
  }
  button {
    padding:5px 12px;
    border:none;
    border-radius:3px;
    cursor:pointer;
  }
}
</style>

MyAside.vue

复制代码
<template>
  <div class="layout-aside-container">
    <ul class="menu">
      <li class="menu-item">
        <router-link to="/home/users">用户管理</router-link>
      </li>
      <li class="menu-item">
        <router-link to="/home/rights">权限管理</router-link>
      </li>
      <li class="menu-item">
        <router-link to="/home/goods">商品管理</router-link>
      </li>
      <li class="menu-item">
        <router-link to="/home/orders">订单管理</router-link>
      </li>
      <li class="menu-item">
        <router-link to="/home/settings">系统设置</router-link>
      </li>
    </ul>
  </div>
</template>

<script setup>
</script>

<style scoped lang="less">
.layout-aside-container {
  width:180px;
  background:#304156;
  .menu {
    padding:0;
    margin:0;
    list-style:none;
    .menu-item {
      a {
        display:block;
        padding:14px 20px;
        color:#bfcbd9;
        text-decoration:none;
        &.router-link-active {
          background:#263445;
          color:#409eff;
        }
      }
    }
  }
}
</style>

router.js 代码

复制代码
import { createRouter, createWebHashHistory, RouterView } from 'vue-router'
import { h } from 'vue'

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      path: '/',
      redirect: '/login'
    },
    {
      path: '/login',
      component: () => import('./components/Login.vue')
    },
    {
      path: '/home',
      component: () => import('./components/Home.vue'),
      redirect: '/home/users',
      children: [
        {
          path: 'users',
          component: {
            render() {
              // 我这里没有自己的页面,我只是一个 "容器",用来显示我下面的子页面。
              return h(RouterView)
            }
          },
          children: [
            { path: '', component: () => import('./components/subcomponents/MyUsers.vue') },
            { path: ':id', component: () => import('./components/user/MyUserDetail.vue'), props: true }
          ]
        },
        {
          path: 'rights',
          component: () => import('./components/subcomponents/MyRights.vue')
        },
        {
          path: 'goods',
          component: () => import('./components/subcomponents/MyGoods.vue')
        },
        {
          path: 'orders',
          component: () => import('./components/subcomponents/MyOrders.vue')
        },
        {
          path: 'settings',
          component: () => import('./components/subcomponents/MySettings.vue')
        }
      ]
    }
  ]
})

// 路由守卫
router.beforeEach((to, from, next) => {
  if (to.path === '/login') {
    next()
  } else {
    const token = localStorage.getItem('token')
    token ? next() : next('/login')
  }
})

export default router

main.js 代码

复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ScopeSlot from './components/ScopeSlot.vue'
// 引入element-plus核心样式
import 'element-plus/dist/index.css'
import ElementPlus from 'element-plus'
const app = createApp(App)
app.use(ElementPlus).use(router)
app.mount('#app')
相关推荐
吴声子夜歌3 小时前
Java面试——算法
java·算法·面试
evans在进步3 小时前
LeetCode 64:最小路径和——Java 原地动态规划详解
java·leetcode·动态规划
ly76894 小时前
HTML5 从入门到工程实践:语义化、表单、多媒体、性能与项目规范详解
前端·html·html5
凤山老林5 小时前
Spring Boot 3.x AOT 编译实战:从原理、踩坑到生产落地
java·spring boot·后端
博傅5 小时前
Spring 核心原理
java·后端·spring
yurenpai(27届找实习中)5 小时前
从零读懂 AI 智能客服(一):模块职责与 SSE 聊天链路(后端架构)
java·人工智能·架构·langchain4j
M78佐菲5 小时前
c语言学习笔记:排序与查找方法整理
linux·c语言·笔记·学习·算法
陈皮波比茶6 小时前
Swagger
java
ltl6 小时前
QUIC 协议拆解(上):为什么 TCP 改不动了
linux