赞
踩
前言:之前后台管理系统只是写了两个页面并没有分开布局
所用到的技术栈:
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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。