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

一、基本概念

二、运行效果及部分代码

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')
相关推荐
恋猫de小郭1 小时前
Android 17 内存管理将严格管控,App 要注意适配
android·前端·flutter
摇滚侠1 小时前
JavaWeb 全套教程 Tomcat 53-62
java·tomcat
暗冰ཏོ1 小时前
《uni-app 跨端开发完整指南:从基础入门到 H5、小程序、App 发布上线》
前端·小程序·uni-app·vue·html5
Cx330❀1 小时前
【Linux网络】打破“一问一答”局限:从零构建全双工多线程UDP群聊系统
linux·运维·服务器·网络·网络协议·udp
搬砖的前端1 小时前
AI工具集:Git提交时使用AI进行CodeReview如何在前端应用构建NPM包
前端·人工智能·git·npm·codeview
ID_180079054732 小时前
TikTok 视频详情 & 列表 API 接口技术文档(带全套 JSON 样例・核心章节)
linux·windows·microsoft
隔窗听雨眠2 小时前
ORM框架选型指南:MyBatis与Hibernate的全面对比
java·开发语言·数据库
zincsweet2 小时前
Linux进程信号:从产生、保存到递达的全流程解析
linux
Bigger2 小时前
mini-cc 终端 UI:用 React 写 CLI 是什么体验
前端·react.js·ai编程