前言:之前后台管理系统只是写了两个页面并没有分开布局
所用到的技术栈:
vue-element-ui |
vue-vuex |
vue-router |
vue-axios |
这篇文章是按照上篇文章进行了大幅度修改,并且使用多页面进行布局。效果看起来会比之前的好一些
下面我们来看一下这种写法的实现效果
登录页面默认为Login页面
如果这里随便输入路径也会自动跳回登录页面
对表单验证进行了改进
管理员权限页面
普通用户页面
把整个页面进行了分割,一个部分一个页面,这样的话复用性比较强
下面是页面结构
还有一个axios.js上面没有截取到
下面是实战代码:
Header.vue:这个页面就是放在普通用户页面和管理员页面的头部
<template><div class="header"><div class="header-left"><div class="left">KGC后台管理系统</div></div><div class="header-right"><div class="header-right__logout"><el-button type="danger" size="20" @click="logout">退出</el-button></div><div class="header-right__info"><div class="right">{{ name }}</div></div></div></div></template><script>import { mapState } from "vuex";export default {name: "Header",data() {return {name: "",};},mounted() {this.name = window.sessionStorage.getItem("username");},methods: {logout() {this.$confirm("您确定要退出吗, 是否继续?", "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",}).then(() => {window.sessionStorage.clear();this.$message({message: "你已经退出登陆!请重新登录账号",type: "warning",});this.$router.push({ path: "/" });}).catch((err) => err);},},computed: {...mapState(["user"]),},};</script><style >.header {height: 50px;line-height: 50px;background-color: rgb(73, 80, 96);padding: 0 50px;color: #fff;}.left {color: #fff;float: left;}.header-right__info {float: right;margin: 0 20px;}.header-right__logout {float: right;}</style>
axios.js:直接在生成好的模板的let config={里面写入此接口}
baseURL:'http://localhost:3000'
Login.vue页面:!!这个页面主要就是布局一下登陆页面,然后对登录按钮进行一个验证,如果数据中的账号中不存在所输入的账号,那么就会判断没有这个账号;
如果所输入的账号与数据中的账号相匹配,那么会判断是否为管理员账号,如果是管理员账号并且输入的密码与数据中的密码相匹配,那么就进入管理员页面;
如果是普通用户的账号,并且输入的密码与数据中的密码相匹配那么就进入用户页面
<template><div class="home"><div class="homebox" v-loading="loading"><h3>KGC后台管理系统</h3><el-inputclass="input"v-model="username"style="width: 500px"placeholder="用户名"></el-input><el-inputclass="input"placeholder="密码"style="width: 500px"v-model="password"show-password></el-input><el-buttontype="primary"size="medium "@click="login"style="width: 500px">登陆</el-button></div></div></template><script>export default {name: "Login",data() {return {username: "admin",password: 123,loading: false,};},mounted() {},methods: {login() {this.$axios.get("/users").then((v) => {this.loading = true;const uname = [];const passw = [];console.log(v);const res = v.data;for (var i = 0; i < res.length; i++) {uname.push(res[i].name);passw.push(res[i].pwd);}console.log(uname);console.log(passw);console.log(uname.indexOf(this.username) === -1);setTimeout(() => {if (uname.indexOf(this.username) === -1) {this.loading = false;this.$message.error("账号不存在,请重新输入!");} else if(uname.indexOf(this.username) != -1 && this.username == 'admin'){var index = uname.indexOf(this.username);console.log(passw[index]);if (passw[index] == this.password) {this.loading = false;this.$message({message: "欢迎来到管理员页面!您已经超过了99%的用户",type: "success",});window.sessionStorage.setItem('username',this.username)this.$router.push("./Page");} else {this.loading = false;this.$message.error("密码错误,请重新输入");}}else{ var index = uname.indexOf(this.username);console.log(passw[index]);if (passw[index] == this.password) {this.loading = false;this.$message({message: "欢迎登陆用户页面!!!",type: "success",});window.sessionStorage.setItem('username',this.username)this.$router.push("./Page2");} else {this.loading = false;this.$message.error("密码错误,请重新输入");}}}, 2000);});},},};</script><style>body {background-color: rgb(238, 243, 250);}.homebox {text-align: center;position: absolute;top: 50%;left: 50%;margin-top: -150px;margin-left: -300px;width: 600px;height: 300px;background-color: rgb(255, 255, 255);}h3 {padding: 20px 0;}.input {margin-bottom: 20px;}</style>
Page.vue页面:这个页面就是显示了用户管理和商品管理两个导航菜单,当每次点击时会进入所对应的数据页面,也就是存放用户管理中的数据和商品管理中的数据页面
<template><div><el-container><el-col :span="3"><el-menu default-active="1" class="el-menu-vertical-demo"><el-menu-item index="1" @click="btn1"><i class="el-icon-menu"></i><span slot="title">用户管理</span></el-menu-item><el-menu-item index="2" @click="btn2"><i class="el-icon-setting"></i><span slot="title">商品管理</span></el-menu-item></el-menu></el-col><el-main><router-view></router-view></el-main></el-container></div></template><script>import Header from "../components/Header";export default {name: "Page",data() {return {loading: false,};},mounted() {},components: {Header,},methods: {btn1() {this.$router.push("./user");},btn2() {this.$router.push("./commodity");},handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);},},};</script><style scoped></style>
Page2.vue页面:这个页面就是普通用户的页面,只有一个商品管理的一个导航菜单
<template><div><el-container><el-col :span="3"><el-menu default-active="1" class="el-menu-vertical-demo"><el-menu-item index="2"><i class="el-icon-setting"></i><span slot="title">商品管理</span></el-menu-item></el-menu></el-col><el-main><router-view></router-view></el-main></el-container></div></template><script>import Header from "../components/Header";export default {name: "Page",data() {return {loading: false,};},mounted() {},components: {Header,},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);},},};</script><style scoped>/* .el-main {padding: 0;} */</style>
User.vue页面:这个页面主要是写了数据项包括后面的一个删除按钮,删除按钮是假删除有两种方法,第二种方法我这里给注释掉了。这里直接获取数据用:data="tableData"获取数据
<template><div><el-table :data="tableData" v-loading="loading"><el-table-column prop="id" label="编号" width="180"> </el-table-column><el-table-column prop="name" label="用户名" width="180"></el-table-column><el-table-column prop="role" label="角色"> </el-table-column><el-table-column prop="phone" label="手机号码"> </el-table-column><el-table-column prop="email" label="邮箱"> </el-table-column><el-table-column prop="role" label="操作"><template v-slot="scope"><el-buttontype="danger"size="mini"@click="deleteData(scope.$index.tableData)">删除</el-button><!--@click="deleteData(scope.row.name)" --><el-dialog title="提示" width="30%"><span class="warcont"><i class="el-icon-warning"></i>是否确定要删除该用户</span><span slot="footer" class="dialog-footer"><el-button>取 消</el-button><el-button type="primary">确 定</el-button></span></el-dialog></template></el-table-column></el-table></div></template><script>import { mapState } from "vuex";export default {name: "User",data() {return {loading: false,};},computed: {...mapState(["tableData"]),},mounted() {this.loading = true; setTimeout(() => { this.loading = false;this.$axios.get("/users").then((res) => {const home = res.data;this.$store.commit("addrecord", home);}); }, 500);},methods: {//deleteData(name)deleteData(index,row){this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {this.$message({type: 'success',message: '删除成功!'});/*var index = this.tableData.findIndex(item => {return item.name === name;});this.tableData.splice(index,1) */this.tableData.splice(index,1)}).catch(() => {this.$message({type: 'info',message: '已取消删除'});});},handleClick(tab, event) {console.log(tab, event);},},};</script>
Commodity.vue页面:与user.vue页面方法一致,只不过这个页面是商品管理页面的数据
<template><el-tableborderstyle="width: 100%":data="table"v-loading="loading"element-loading-text="拼命加载中"><el-table-column prop="id" label="编号" width="180"> </el-table-column><el-table-column prop="name" label="商品名称" width="180"></el-table-column><el-table-column prop="price" label="单价"> </el-table-column><el-table-column prop="number" label="库存"> </el-table-column></el-table></template><script>import { mapState } from "vuex";export default {name: "Commodity",data() {return {loading: false,};},mounted() {this.loading = true;clearTimeout(clear)var clear = setTimeout(() => { this.$axios.get("/goods").then((v) => {const com = v.data;this.$store.commit("record", com);this.loading = false})}, 300);},computed: {...mapState(["table"]),},};</script>
*404页面:这个页面就是防止页面出错以及复制管理员地址所产生的报错页面,这里没有用到,可以忽略
<template><div class="not-found"><h1>啊哦!找不到相关页面o(╥﹏╥)o。</h1><router-link to><p @click="$router.back(-1)">返回上一级页面</p></router-link></div></template><script>export default {name:'Found'}</script><style lang="less" scoped>.not-found {width: 100%;height: 100vh;background-color: #6495ED;display: flex;justify-content: center;align-items: center;h1 {margin: 0;color: #fff;}a {color: #E0FFFF;font-size: 14px;font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;transform: translateY(10px);}}</style>
接下来就是路由页面了:
router.js页面:这个页面最为重要,当页面为/时会重定向到Login登录页面,用导航守卫去限制不必要的链接把Page页面和Page2页面作为父路由,把user以及commodity作为子路由进行绑定。并且重写了原型上的push方法,解决一些不知道会报啥错误的信息
import Vue from "vue";import VueRouter from "vue-router";import Login from "../views/Login.vue";import Page from "../views/Page.vue";import Page2 from "../views/Page2.vue";import User from "../views/User.vue";import Commodity from "../views/Commodity.vue";import Header from "../components/Header.vue";Vue.use(VueRouter);const routes = [{path: "/",redirect: "/Login",},{path: "/Login",name: "Login",component: Login,},{path: "/page",name: "Page",components: {default: Page,Header,},children: [{path: "/page",redirect: "/page/user",},{path: "/page/user",name: "User",component: User,},{path: "/page/commodity",name: "Commodity",component: Commodity,},],},{path: "/page2",name: "Page2",components: {default: Page2,Header,},children: [{path: "/page2",redirect: "/page2/commodity",},{path: "/page2/commodity",name: "Commodity",component: Commodity,},],},];const router = new VueRouter({routes,mode: "history",});router.beforeEach((to, from, next) => {if (to.path == "/login") {next();} else {let token = window.sessionStorage.getItem("username");console.log(token);if (!token) {next("/login");} else {next();}}});const originalPush = VueRouter.prototype.push;// 重写了原型上的push方法,统一的处理了错误信息VueRouter.prototype.push = function push(location) {return originalPush.call(this, location).catch((err) => err);};export default router;
store.js页面:这个页面主要是用来存储获取到的数据并把他们放在数组中,使用载荷的方式去其他页面进行调用
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {tableData:[],table:[],user:JSON.parse(window.sessionStorage.getItem('user') || '[]'),},// 存储用户管理页面数据mutations: {addrecord(state,preload){state.tableData = preloadwindow.sessionStorage.setItem('rightsList',JSON.stringify(preload))},// 存储商品管理数据record(state,preload){state.table = preloadconsole.log(state.table);window.sessionStorage.setItem('liftList',JSON.stringify(preload))},setUser(state,preload){state.user = preload;window.sessionStorage.setItem('user',JSON.stringify(state.user));},},actions: {},modules: {}})
接下来就是一些常用的配置文件页面
main.js
import Vue from 'vue'import './plugins/axios'import App from './App.vue'import store from './store'import router from './router'import './plugins/element.js'Vue.config.productionTip = falsenew Vue({store,router,render: h => h(App)}).$mount('#app')
App.vue页面:主要是用来渲染公共样式
<template><div id="app"><router-view name="Header"></router-view><router-view></router-view></div></template><script>export default {name: "app",};</script><style>*{margin: 0;padding: 0;}</style>
element.js
import Vue from 'vue'import Element from 'element-ui'import 'element-ui/lib/theme-chalk/index.css'Vue.use(Element)