Vue实现后台管理系统

目录

前言

登录页面

后台界面


前言

今天用Vue实现一个简易的后台,不借助接口和后端代码,仅通过前端实现,本案例涉及Vue路由相关知识,不熟悉Vue路由可以先看一下右边的文章再接着看下面的项目案例:Vue路由 这篇文章详细介绍了路由的知识;Vue导航 这篇文章详细介绍了路由导航的知识。

登录页面

登录页面的话不需要很复杂的逻辑,只需要写好页面的样式即可,因为账号密码没有借助后端代码来实现,只通过前端的代码实现,这一点不是很安全,因为在页面的控制台就能看到你的登录的账号密码,因为这仅是一个案例,所以就没有那么严谨了。

因为要借助Vue的路由,所以我们要先安装一下vue-router,安装完成之后,创建router文件夹,书写以下四步骤进行vue的路由调用。

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const router = new VueRouter()

export default router

创建完成后在main.js文件中引入

import router from '@/router'

login.vue代码如下:

<template>
  <div class="login-container">
    <div class="login-box">
      <!-- 头像区域 -->
      <div class="text-center avatar-box">
        <img src="../assets/logo.png" class="img-thumbnail avatar" alt="">
      </div>
      <!-- 表单区域 -->
      <div class="form-login p-4">
        <!-- 登录名称 -->
        <div class="form-group form-inline">
          <label for="username">登录名称</label>
          <input type="text"
            class="form-control m1-2"
            id="username"
            placeholder="请输入登录名称"
            autocomplete="off"
            v-model.trim="username"
          >
        </div>
        <!-- 登录密码 -->
        <div class="form-group form-inline">
          <label for="password">登录密码</label>
          <input type="password"
            class="form-control m1-2"
            id="password"
            placeholder="请输入密码"
            v-model.trim="password"
          >
        </div>
        <!-- 登录和重置按钮 -->
        <div class="form-group form-inline d-flex justify-content-end">
          <button type="button" class="btn btn-danger mr-2" @click="reset">重置</button>
          <button type="button" class="btn btn-primary" @click="login">登录</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name:'MyLogin',
  data(){
    return {
      username:'',
      password:''
    }
  },
  methods:{
    reset(){
      this.username='',
      this.password=''
    },
    login(){
      if(this.username==='admin'&&this.password==='666666'){
        // 登录成功
        // 1.存储 token
        localStorage.setItem('token','Bearer xxxxx')
        // 2.跳转到后台主页
        this.$router.push('/home')
      }else{
        // 登录失败
        localStorage.removeItem('token')
      }
    }
  }
}
</script>

<style lang="less" scoped>
.login-container{
  background-color: #35495e;
  height: 760px;
  .login-box{
    width: 400px;
    height: 250px;
    text-align: center;
    background-color: #fff;
    border-radius: 3px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
    box-shadow: 0 0 6px rgba(255,255,255,0.5);
    .form-login{
      position: absolute;
      bottom: -15px;
      left: 0;
      width: 100%;
      box-sizing: border-box;
      #username{
        width: 250px;
        margin-left: 20px;
      }
      #password{
        width: 250px;
        margin-left: 20px;
      }
    }
    .d-flex{
      margin-left: 220px;
    }
  }
}
.form-control{
  flex: 1;
}
.avatar-box {
  position: absolute;
  width: 100%;
  top: -65px;
  left: 0;
  .avatar {
    width: 120px;
    height: 120px;
    border-radius: 50% !important;
    box-shadow: 0 0 6px #efefef;
  }
}
</style>

当我们输入正确的账号密码后,路由跳转到我们规定的 home hash地址下, 路由规则在router文件夹下书写。

全局前置守卫为了防止在不输入账号密码的情况下,直接访问home页面就进入的情况。

import Vue from 'vue'
import VueRouter from 'vue-router'

// 导入需要的组件
import Login from '@/admin/MyLogin.vue'
import Home from '@/admin/MyHome.vue'


Vue.use(VueRouter)

const router = new VueRouter({
  routes:[
    // 登录的路由规则
    {path:'/',redirect:'/login'},
    {path:'/login',component:Login},
    {path:'/home',component:Home,}
  ]
})

// 全局前置守卫
router.beforeEach(function(to,from,next){
  const pathArr = ['/home']
  if(pathArr.indexOf(to.path)!=-1){
    const token = localStorage.getItem('token')
    if(token){
      next()
    }else{
      next('/login')
    }
  }else{
    next()
  }
})
export default router

后台界面

接下来要准备给后台添加一些内容,如下:

Home组件内容如下:

<template>
  <div class="home-container">
    <!-- 头部区域 -->
    <MyHeader></MyHeader>
    <!-- 页面主体区域 -->
    <div class="home-main-box">
      <!-- 左侧边栏 -->
      <MyAside></MyAside>
      <!-- 右侧内容主题区域 -->
      <div class="home-main-body">
        <router-view></router-view>
      </div>
    </div>
  </div>
</template>

<script>
import MyHeader from '@/admin/subcomponents/MyHeader.vue'
import MyAside from '@/admin/subcomponents/MyAside.vue'
export default {
  components:{
    MyHeader,MyAside
  }
}
</script>

<style lang="less" scoped>
.home-container {
  height: 100%;
  display: flex;
  flex-direction: column;

  .home-main-box {
    height: 100%;
    display: flex;
    .home-main-body {
      padding: 15px;
      flex: 1;
    }
  }
}
</style>

给后台页面匹配路由规程,如下:

import Vue from 'vue'
import VueRouter from 'vue-router'

// 导入需要的组件
import Login from '@/admin/MyLogin.vue'
import Home from '@/admin/MyHome.vue'

// 导入子组件路由
import Users from '@/admin/menus/MyUsers.vue'
import Rights from '@/admin/menus/MyRight.vue'
import Goods from '@/admin/menus/MyGoods.vue'
import Orders from '@/admin/menus/MyOrders.vue'
import Settings from '@/admin/menus/MySettings.vue'
import UserDetail from '@/admin/user/MyUserDetail.vue'

Vue.use(VueRouter)

const router = new VueRouter({
  routes:[
    // 登录的路由规则
    {path:'/',redirect:'/login'},
    {path:'/login',component:Login},
    {path:'/home',redirect:'/home/users',component:Home,children:[
      {path:'users',component:Users},
      {path:'rights',component:Rights},
      {path:'goods',component:Goods},
      {path:'orders',component:Orders},
      {path:'settings',component:Settings},
      // 用户详情页的路由规则
      {path:'userinfo/:id',component:UserDetail,props:true}
    ]}
  ]
})

// 全局前置守卫
router.beforeEach(function(to,from,next){
  const pathArr = ['/home','/home/users','home/rights']
  if(pathArr.indexOf(to.path)!=-1){
    const token = localStorage.getItem('token')
    if(token){
      next()
    }else{
      next('/login')
    }
  }else{
    next()
  }
})
export default router

书写头部组件,如下:

<template>
  <div class="layout-header-container d-flex justify-content-between align-items-center p-3">
    <!-- 左侧 logo 和 标题区域 -->
    <div class="layout-header-left d-flex align-items-center user-select-none">
      <!-- logo -->
      <img class="layout-header-left-img" src="../../assets/logo.png" alt="" />
      <!-- 标题 -->
      <h4 class="layout-header-left-title ml-3">后台管理系统</h4>
    </div>

    <!-- 右侧按钮区域 -->
    <div class="layout-header-right">
      <button type="button" class="btn btn-light" @click="logout">退出登录</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'MyHeader',
  methods: {
    logout() {
      // 1. 清空 token
      localStorage.removeItem('token')
      // 2. 跳转到登录页面
      this.$router.push('/login')
    }
  }
}
</script>

<style lang="less" scoped>
.layout-header-container {
  height: 60px;
  border-bottom: 1px solid #eaeaea;
}

.layout-header-left-img {
  height: 50px;
}
</style>

书写左侧边栏,如下:

<template>
  <div class="layout-aside-container">
    <!-- 左侧边栏列表 -->
    <ul class="user-select-none 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>
export default {
  name:'MyAside'
}
</script>

<style lang="less" scoped>
.layout-aside-container{
  width: 250px;
  height: 700px;
  border-right: 1px solid #eaeaea;
}
.menu{
  list-style: none;
  padding: 0;
  .menu-item{
    line-height: 50px;
    font-weight: bold;
    font-size: 14px;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    &:hover{
      background-color: #efefef;
      cursor: pointer;
    }
    a{
      display: block;
      color: black;
      padding-left: 30px;
      &:hover{
        text-decoration: none;
      }
    }
  }
}
// 设置路由高亮效果
.router-link-active{
  background-color: #efefef;
  box-sizing: border-box;
  position: relative;
  // 伪元素实现路由高亮效果
  &::before{
    content: '';
    display: block;
    width: 4px;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    background-color: #42b983;
  }
}
</style>

上文的路由规则已经书写了home组件下子路由的规则,点击侧边栏的菜单直接进入子路由的路径

users子组件的内容如下:

<template>
  <div>
    <!-- 标题 -->
    <h4 class="text-center">用户管理</h4>
    <!-- 用户列表 -->
    <table class="table table-bordered table-striped table-hover">
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>年龄</th>
          <th>头衔</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in userlist" :key="item.id">
          <td>{
   
   {item.id}}</td>
          <td>{
   
   {item.name}}</td>
          <td>{
   
   {item.age}}</td>
          <td>{
   
   {item.position}}</td>
          <td><a href="#" @click.prevent="gotoDetail(item.id)">详情</a></td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  data(){
    return {
      // 用户列表
      userlist:[
        {id:1,name:'张三',age:18,position:'律师'},
        {id:2,name:'李四',age:28,position:'老师'},
        {id:3,name:'王五',age:33,position:'工程师'},
        {id:4,name:'陈六',age:23,position:'商人'},
      ]
    }
  },
  methods:{
    gotoDetail(id){
      this.$router.push('/home/userinfo/'+id)
    }
  }
}
</script>

<style>

</style>

每天一个小案例,让自己的代码水平趋于成熟。

猜你喜欢

转载自blog.csdn.net/qq_53123067/article/details/128365301