后台管理系统——附完整代码

 前言:之前后台管理系统只是写了两个页面并没有分开布局

详情

所用到的技术栈:

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-input
        class="input"
        v-model="username"
        style="width: 500px"
        placeholder="用户名"
      ></el-input>
      <el-input
        class="input"
        placeholder="密码"
        style="width: 500px"
        v-model="password"
        show-password
      ></el-input>
      <el-button
        type="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-button
            type="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-table
    border
    style="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 = preload
      window.sessionStorage.setItem('rightsList',JSON.stringify(preload))
    },
    // 存储商品管理数据
    record(state,preload){
      state.table = preload
      console.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 = false

new 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)

上一篇:vue路由router使用详解


下一篇:vue3学习之路小坎坷