Vue实现后台管理系统

news2024/11/13 20:28:38

目录

前言

登录页面

后台界面


前言

今天用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>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/99092.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[CISCN2019 华北赛区 Day1 Web2]

目录 前言 涉及考点 部分记录 前言 第一次看到这题时没有思路&#xff0c;通过搜索相关WP并简单了解考点所涉及的知识后&#xff0c;通过解题来扩展自己的知识面 涉及考点 python爬虫&#xff0c;支付逻辑漏洞&#xff0c;cookie篡改&#xff0c;重放攻击&#xff0c;JWT…

C++11后的STL算法

文章目录一、函数对象二、预定义的函数对象三、算法函数1.自己实现foreach算法2.自己实现的findif算法3.自己实现bsort算法一、函数对象 STL提供了很多处理容器的函数模板&#xff0c;它们的设计是相同的&#xff0c;有以下特点&#xff1a; 1&#xff09;用迭代器表示需要处理…

数据结构---用栈实现队列

用栈实现队列模拟入队模拟出队JAVA实现总结用栈来模拟一个队列&#xff0c;要求实现队列的两个基本操作&#xff1a;入队、出队。栈是先入后出&#xff0c;队列是先入先出 用两个栈来实现一个队列功能 让其中一个栈作为队列的入口&#xff0c;负责插入新元素&#xff1b;另一个…

ARM9和STM32什么关系?

已剪辑自: https://mp.weixin.qq.com/s/QHARY-D2SwFoQbFsJoCNlg 有小伙伴问&#xff1a;ARM9和STM32什么关系&#xff1f;如果时间倒退10年&#xff0c;ARM9、 s3c2410还算是比较流行的年代&#xff0c;但STM32这类“新时代”的ARM处理器也问世了。 ARM9是早期的ARM处理器&…

Java+MySQL基于ssm的打车管理系统的设计与实现

随着时代的发展,交通也变的越来越便利,但是很多时候人们出行的时候因为各种原因还是会进行打车,因为一些地区比较偏远或者处于特殊的时间段而用户又急需用车等情况导致没办法及时的打到车,这种情况下就急需一套基于互联网的打车系统出现了。 本打车管理系统采用JAVA语言来进行开…

Vivado2019+Modelsim仿真环境搭建

目录 一、安装准备 二、安装与配置 2.1 Vivado安装 2.2 modelsim安装 2.3 Vivado设置modelsim仿真环境 1&#xff09;仿真库生成设置 2&#xff09;modelsim添加仿真库&#xff08;逐个添加&#xff09; 3&#xff09;modelsim添加仿真库&#xff08;批量添加&#xff…

Spring 中 @Value 注解使用和源码分析

1、Value 注解使用 先配置本地 application.properties 如下&#xff1a; apple.nameabc代码如下&#xff1a; PropertySource("application.properties") public class Apple {Value("${apple.name}")public String name; }ComponentScan public class …

非零基础自学Golang 第9章 结构体 9.7 匿名结构体 9.8 小结 9.9 知识拓展

非零基础自学Golang 文章目录非零基础自学Golang第9章 结构体9.7 匿名结构体9.7.1 匿名结构体定义与初始化9.7.2 匿名结构体的应用9.8 小结9.9 知识拓展9.9.1 使用结构体解析XML文件第9章 结构体 9.7 匿名结构体 9.7.1 匿名结构体定义与初始化 匿名结构体&#xff0c;顾名思…

blender源代码编译运行

其实在blender官网上已经给出了编译步骤https://wiki.blender.org/wiki/Building_Blender/Windows&#xff0c;由于在源码编译的过程中还遇到了很多问题&#xff0c;特此记录一下。 文章目录前提准备代码下载1. blender源码下载2. lib下载编译前提准备 Visual Studio2019或者2…

Innodb存储引擎-执行流程分析和二阶段提交分析

文章目录执行流程分析基本流程WAL(Write-Ahead Log)write和fsync区别innodb_flush_logs_at_trx_commit & sync_binlog二阶段提交执行流程分析 基本流程 &#xff08;1&#xff09;连接,分析,优化,执行 客户端与MySQL Server建立连接&#xff0c;发送语句给MySQL Server&a…

2022.12.18 学习周报

文章目录摘要文献阅读1.题目2.摘要3.介绍4.RNNConventional Recurrent Neural Networks5.Deep Recurrent Neural Networks5.1 Deep Transition RNN5.2 Deep Output5.3 Stacked RNN6.实验6.1 训练6.2 结果与分析7.讨论深度学习GRU公式推导1.GRU前向传播2.GRU反向传播GRU代码实现…

关于数学中“函数(function)”的含义

目录 1. 问题 2. “function”是如何翻译成“函数”的&#xff1f; 3. “function”是谁引入数学中的&#xff0c;其意义何在&#xff1f; 3.1 “function”的词源 3.2 “function”引入数学中 3.3 “function”的含义 4. 常见的函数(Common Functions) 4.1 线性函数(L…

word页码如何设置为章节加页码,例如第一章第一页1-1、第二章章第一页2-1

由于用到word页码分章节页码的形式&#xff0c;从网上查了一下&#xff0c;质量真的很差&#xff0c;没有一篇文章讲清楚的&#xff0c;有的所答非所问&#xff0c;一怒之下&#xff0c;利用几个小时的时间解决问题并写下这篇文章&#xff0c;以供大家学习参考&#xff01;&…

【JSP】

文章目录简介Scriptlet脚本小程序JSP的指令标签include静态包含include动态包含不传参传参JSP的四大域对象四种属性范围验证属性范围的特点EL表达式操作字符串操作集合emptyJSTL条件动作标签if标签choose、when 和 otherwise 标签迭代标签foreach格式化动作标签formatNumber标签…

NProgress 进度条的使用方法

安装NProgress 进度条 npm install nprogress --save-dev 在vue项目中mian.js中或router.js或axios.js&#xff1a; import NProgress from nprogress import nprogress/nprogress.css 使用NProgress进度条 NProgress.start(); &#xff1a;进度条开始&#xff1b; NProgr…

GCD和LCM

目录 一 整除 定义 性质 二 GCD 1&#xff09;定义 2&#xff09;性质 3&#xff09;GCD编程 ①暴力法 ②欧几里得算法 ③更相减损术 ④Stein算法 三 LCM ①暴力法 ②最大公约数法 四 裴蜀定理 例题&#xff1a;裴蜀定理 一 整除 定义 a 能整除b,记为 a|b。其…

你还会想起这道题吗

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 原神是由米哈游自主研发的一款全新开放世界冒险游戏。游戏发生在一个被称作「提瓦特」的幻想世界&#xff0c;在这里&#xff0c;被神选中的人将被授予「神之眼」&#xff0c;导引元…

m基于神经网络的气候预测matlab仿真,气候数据采用的BoM气候数据,神经网络为matlab编程实现不使用工具箱函数

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 人工神经网络&#xff08;Artificial Neural Networks&#xff0c;简写为ANNs&#xff09;也简称为神经网络&#xff08;NNs&#xff09;或称作连接模型&#xff08;Connection Model&#xff09…

UICollectionView 实际使用

一. 使用UICollectionView制作书架 我想的书架是那种每一排都可以滑动的。暂时的想法是使用两个collectionView&#xff0c;第一个collectionView布置书架的每一排&#xff0c;第二个布置每一排内部的书。 布置外部的colletionView&#xff0c;这部分很简单&#xff0c;item的…

[ 数据结构 -- 手撕排序算法第五篇 ] 堆排序

文章目录前言一、常见的排序算法二、堆的概念及结构三、堆的实现3.1 堆的插入3.2 堆的删除四、堆排序4.1 向上调整建堆4.2 向下调整建堆4.3 建堆的时间复杂度4.4 堆排序五、堆排序的特性前言 手撕排序算法第五篇&#xff1a;堆排序&#xff01; 从本篇文章开始&#xff0c;我会…