https://gitee.com/sansan533/bk2115_pc
npm i element-ui -S
//在main.js中 引入element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
//在main.js中 iconfont注册
import './assets/iconfont/iconfont.css'
npm install mockjs --save -dev
//在main.js 中引入mock
import './mock'
该插件封装了cookie 对应的操作方法
npm install js-cookie
在src 目录下的utils文件中,定义request.js 文件,用来封装axios请求。
src\utils\request.js
import {
getCookie } from './cookie.js';
import Vue from 'vue'
import axios from 'axios';
//2。创建server
const instance = axios.create({
baseURL: '',// index/index http://kumanxuan1.f3322.net:8001
timeout: 10000 //超时链接
})
//3.请求拦截 登陆放token的地方
instance.interceptors.request.use(config => {
config.headers['My_ToKen'] = getCookie('token')
return config
})
//4.响应拦截 解码加密 公共逻辑判断 项目中所有的错误 都可以在这个位置进行处理
instance.interceptors.response.use(res => {
console.log(res)
//全局错误提示
if (res.status === 200 || res.data.code == 200) {
return res.data
} else {
Vue.prototype.$message({
message: '网络不通',
type: 'error'
});
}
})
export default instance
在src目录下,新建router目录,在该目录下新建index.js 文件。路由配置如下:
src\router\index.js
//公共权限
const routes = [
{
path: '/',
redirect: '/layout'
},
{
path: '/layout',
name: 'Layout',
component: Layout,
children: [
{
path: '',
component: Home,
name: 'Home',
meta: {
title: '首页',
icon: 'el-icon-attract'
}
}, {
path: 'user',
name: 'User',
component: () => import('@/views/user/User.vue'),
meta: {
title: '用户管理',
icon: 'el-icon-coordinate'
}
}, {
path: 'msg', // 信息管理功能
name: 'Msg',
component: () => import('@/views/msg/Msg.vue'),
meta: {
title: '信息管理功能',
icon: 'el-icon-wallet'
},
children: [
{
path: 'mymsg', //个人信息
name: 'Mymsg',
component: () => import('@/views/msg/Mymsg.vue'),
meta: {
title: '个人信息',
icon: 'el-icon-set-up'
},
}
]
}
]
},
{
path: '/login',
name: 'Login',
component: Login
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
在src 目录下新建mock 目录,在mock目录下,创建index.js 文件,该文件中定义所有的接口请求如下:
src\mock\index.js
import Mock from 'mockjs'
import loginMock from './loginMock.js'
Mock.setup({
timeout: 400 //表示 400 毫秒 后才会返回响应内容
})
//mock语法:
//Mock.mock( rurl, rtype, function( options ) )
//记录用于生成响应数据的函数。当拦截到匹配 rurl 和 rtype 的 Ajax 请求时,函数 function(options)
//将被执行,并把执行结果作为响应数据返回。
// 定义所有接口
//1. 登陆接口
Mock.mock('/login', 'post', loginMock.login)
//2.角色获取权限列表
Mock.mock('/getPress', 'post', loginMock.getPress)
在src目录的mock文件中,新建loginMock.js文件,定义用于生成响应数据的函数
后端根据不同的role角色,返回不同的导航菜单
src\mock\loginMock.js
//Mock.mock( rurl, rtype, function( options ) )
//记录用于生成响应数据的函数。当拦截到匹配 rurl 和 rtype 的 Ajax 请求时,函数 function(options)
//将被执行,并把执行结果作为响应数据返回。
export default {
login: config => {
console.log(110, config)// config 含有 url、type 和 body 三个属性,body为参数
let {
name, pwd } = JSON.parse(config.body) // 获取参数
let token = '' //token是就是用户账号和密码按规则转化而来
let role = ''
// 自定义如下2个账号
if (name === 'admin' && pwd == '123456') {
//管理员账号
token = 'admin---token--XXXXX'
role = '管理员'
} else if (name === 'user' && pwd == '123456') {
//大壮的账号
token = 'user---token--XXXXX'
role = '普通用户'
} else {
return {
code: 101,
msg: '账号密码不存在',
data: null
}
}
// 如果是admin或user 账户,则返回如下
return {
code: 200,
msg: '登陆成功',
data: {
token: token,
role: role
}
}
},
// 后端根据不同的role角色,返回不同的导航菜单
getPress: config => {
//admin---管理员--导航菜单[审批管理,请假审批,我要请假]
//user---普通用户---导航菜单[我要请假]
let {
role } = JSON.parse(config.body) //管理员 普通用户
if (role == '管理员') {
return {
code: 200,
msg: '成功',
data: [
{
path: 'shenpi', //审批管理
meta: {
title: '审批管理',
icon: 'el-icon-bangzhu'
},
name: 'Shenpi' //componet
},
{
path: 'qingjia', //请假审批
meta: {
title: '请假审批',
icon: 'el-icon-bangzhu'
},
name: 'Qingjia' //componet
}, {
path: 'woqingjia', //我要请假
meta: {
title: '我要请假',
icon: 'el-icon-bangzhu'
},
name: 'Woqingjia' //componet
}
]
}
} else if (role == '普通用户') {
return {
code: 200,
msg: '成功',
data: [{
path: 'woqingjia', //我要请假
meta: {
title: '我要请假',
icon: 'el-icon-bangzhu'
},
name: 'Woqingjia' //componet
}
]
}
}
}
}
// 存放所有的接口请求
import instance from "../utils/request";
// 登录接口
export function loginApi(params) {
return instance({
url: '/login',
method: 'post',
data: params //axios是就是promise封装的ajax 工具类
})
}
//根据角色获取权限菜单列表接口
export function getPressApi(params) {
return instance({
url: '/getPress',
method: 'post',
data: params
})
}
登陆成功,在cookie中存放token,在localstorage中存储role(管理员或者普通用户)
在src文件下的views目录中创建Login.vue 文件,代码如下:
src\views\Login.vue
src\views\Login.vue
<!-- 登录页面 -->
<template>
<div class="container">
<div class="form">
<div class="title">
<span>千锋科技后台管理</span>
</div>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="用户名" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="密码" prop="pwd">
<el-input v-model="ruleForm.pwd"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>提交</el-button
>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import {
loginApi } from "@/http/http";
import {
setCookie } from "../utils/cookie.js";
export default {
data() {
return {
ruleForm: {
// 表单数据
name: "",
pwd: "",
},
rules: {
// 验证规则
name: [{
required: true, message: "用户名不能为空", trigger: "blur" }],
pwd: [{
required: true, message: "密码不能为空", trigger: "blur" }],
},
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// alert("submit!");
//验证通过
loginApi(this.ruleForm).then((res) => {
if (res.code === 200) {
//1.将token 存到cookie中
setCookie("token", res.data.token);
//2.将角色role保存到localStorage
localStorage.setItem("role", res.data.role);
//3. 跳转到首页
this.$router.push("/");
} else {
this.$message.error("账号不存在");
}
});
} else {
this.$message.error("账号密码错误");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
},
};
</script>
<style scoped lang='less'>
/* @import url(); 引入css类 */
.container {
width: 100%;
height: 100%;
background: url("../assets/bg9.jpg") no-repeat center;
background-size: cover;
.form {
width: 370px;
height: 298px;
padding: 5px 10px;
background-color: #fff;
border-radius: 10px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.title {
width: 100%;
line-height: 50px;
text-align: center;
font-size: 18px;
font-weight: bold;
}
/deep/.ivu-form {
width: 300px;
}
/deep/.ivu-btn {
width: 300px;
height: 30px;
}
}
}
</style>
1、在用户登录成功到跳转到首页之前,需要根据用户的角色role 请求角色菜单接口getPress,将请求返回的路由菜单添加到路由路由对象中,然后将更新后的路由数组存到vuex,在首页中从vuex 中获取路由数组,这样实现数据的全局获取和操作。可以将role 和 route数组 存到vuex全局变量中
npm install vuex --save
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
routes: [], //打算存routes这个数组
role: localStorage.getItem('role')//保存角色信息
},
getters: {
getRoutes(state) {
return state.routes
}
},
mutations: {
setRoutes(state, routes) {
state.routes = routes
},
clearRoute(state) {
state.routes = []
},
setRole(state, role) {
state.role = role
}
},
actions: {
setRoleAction({
commit }, role) {
commit('setRoutes', role)
}
},
modules: {
}
})
在router目录下的index.js 文件中,设置全局前置导航守卫,在登录成功后,页面跳转到首页前,对首页的左侧菜单栏根据角色接口返回的数据,动态修改左侧菜单栏,代码如下:
后端根据不同的role角色,返回不同的导航菜单
至于为什么要把添加后的路由添加到vuex的store的state中,这是在router/index.js文件中生成了路由,存到store中
在下面的MyAside.vue中,需要遍历动态生成的路由,渲染页面
src\router\index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter)
import {
getCookie
} from '@/utils/cookie'
import {
getPressApi
} from '@/http/http'
// 导入store
import store from '@/store'
//解决vue-router在3.0版本以上重复点菜单报错的问题
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
//公共权限
const routes = [{
path: '/',
redirect: '/layout'
},
{
path: '/layout',
name: 'Layout',
component: () => import('@/views/layout/Layout.vue'),
children: [{
path: '',
component: () => import('@/views/home/Home.vue'),
name: 'Home',
meta: {
title: '首页',
icon: 'el-icon-attract'
}
}, {
path: 'user',
name: 'User',
component: () => import('@/views/user/User.vue'),
meta: {
title: '用户管理',
icon: 'el-icon-coordinate'
}
}, {
path: 'msg', // 信息管理功能
name: 'Msg',
component: () => import('@/views/msg/Msg.vue'),
meta: {
title: '信息管理功能',
icon: 'el-icon-wallet'
},
children: [{
path: 'mymsg', //个人信息
name: 'Mymsg',
component: () => import('@/views/msg/Mymsg.vue'),
meta: {
title: '个人信息',
icon: 'el-icon-set-up'
},
}]
}]
},
{
path: '/login',
name: 'Login',
component: () => import('@/views/Login.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
let token = getCookie('token')
// console.log('333', token);
// 已经登录了
if (token) {
// 登录了,访问的是登录页
if (to.path === '/login') {
// 直接跳转到首页
next('/')
}
// 登录了,访问的不是登录页 动态添加路由
else {
console.log('查看', store.state.routes); //切换用户 没有清空
// 第一次,store.state.routes里没有值
if (store.state.routes.length === 0) {
//用户不同-角色不同--权限不同(菜单)
//admin---管理员--导航菜单[审批管理,请假审批,我要请假]
//user---普通用户---导航菜单[我要请假]
let role = localStorage.getItem('role') //获取角色
// 发送请求,获取不同角色,所对应的导航菜单
getPressApi({
role: role}).then((res) => {
if (res.code == 200) {
res.data.forEach(item=>{
console.log('添加前的routes',routes);
routes[1].children.push({
path: item.path,
name: item.name,
meta: {
title: item.meta.title,
icon: item.meta.icon
},
component: () => import('@/views/' + item.name)
})
})
console.log('添加后的route',routes);
store.dispatch('setRoleAction', routes).then(() => {
console.log('动态生成的路由', routes);
//在addRoutes()之后第一次访问被添加的路由会白屏,这是因为刚刚addRoutes()就立刻访问被添加的路由,然而此时addRoutes()没有执行结束,因而找不到刚刚被添加的路由导致白屏。因此需要从新访问一次路由才行。
router.addRoutes(routes) //动态添加路由
next({
...to, replace: true }) //解决动态添加路由白屏问题 bug
})
}
})
}else{
next() //放行
console.log('store.state.routes.',store.state.routes);
}
}
}
// 没登录,
else {
// 没登录,访问的不是登录页,直接去登录页
if (to.path != '/login') {
next('/login')
}
// 没登录,跳转的是登录页,直接放行
else {
next()
}
}
})
export default router
在views目录下,新建layout 目录,layout目录下新建layout.vue 文件,该页面是首页整体布局。代码如下
src\views\layout\Layout.vue
<!--首页-->
<template>
<el-container>
<!-- 头部组件 -->
<el-header>
<Header></Header>
</el-header>
<!-- 下方主体部分 -->
<el-container>
<!-- 左侧边栏 -->
<el-aside style="width: 200px">
<Aside></Aside>
</el-aside>
<!-- 右侧主体 -->
<el-container>
<!-- 面包屑导航 -->
<Bread></Bread>
<el-main>
<!-- 二级路由坑 -->
<router-view></router-view>
</el-main>
<el-footer>Footer</el-footer>
</el-container>
</el-container>
</el-container>
</template>
<script>
// 引入头部
import Header from "./Header";
//引入左侧导航栏
import Aside from "./Aside.vue";
//引入面包屑导航
import Bread from "./Bread.vue";
export default {
data() {
return {
};
},
components: {
Header,
Aside,
Bread,
},
};
</script>
<style scoped lang='less'>
/* @import url(); 引入css类 */
@mainColor: #eaebec; //正确的
.el-container {
width: 100%;
height: 100%;
}
.el-main {
background: @mainColor;
}
.el-footer {
background: lightblue;
}
</style>
在layout目录下,同时再新建header.vue头部组件,代码如下:
<template>
<div class="head-box">
<div class="logo">
<img src="../../assets/logo.png" alt="" />
<h3>千锋后台管理</h3>
</div>
<div class="right">
<el-dropdown @command="handleCommand">
<span class="el-dropdown-link">
你好,{
{
role }}
<img :src="avatar2" alt="" />
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="info">个人信息</el-dropdown-item>
<el-dropdown-item command="change">修改</el-dropdown-item>
<el-dropdown-item command="logout">退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import {
removeCookie } from '@/utils/cookie'
import avatar2 from "@/assets/avatar-2.jpg"; //推荐使用
export default {
name: 'myheader',
data() {
return {
role: '',
avatar2:avatar2
}
},
created() {
console.log('8888',);
this.role = localStorage.getItem('role')
},
methods: {
handleCommand(command) {
if (command === 'logout') {
// 删除cookie
removeCookie('token')
// 刷新页面
this.$router.go(0)
}
}
}
}
</script>
<style lang="less" scoped>
.head-box {
height: 60px;
.logo {
float: left;
width: 180px;
height: 100%;;
display: flex;
align-items: center;
img {
width: 36px;
height: 36px;
}
h3 {
}
}
.right {
float: right;
line-height: 60px;
img{
width: 24px;
height: 24px;
vertical-align: middle;
}
}
}
</style>
在layout目录下,新建Aside.vue侧边栏组件,由于显示首页左侧菜单导航,代码如下:
<!-- 侧边栏导航 -->
<template>
<div>
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
>
<template v-for="(item, index) in menu">
<!-- 一级导航 -->
<router-link :to="'/layout/' + item.path" :key="item.path">
<el-menu-item
:index="item.path + index"
:key="item.path"
v-if="!item.children"
>
<i :class="item.meta.icon"></i>
<span slot="title">{
{
item.meta.title }}</span>
</el-menu-item>
</router-link>
<!-- 二级导航 -->
<el-submenu
:index="item.path + index"
:key="item.path + index"
v-if="item.children"
>
<template slot="title">
<i :class="item.meta.icon"></i>
<span slot="title">{
{
item.meta.title }}</span>
</template>
<template v-for="(child, cindex) in item.children">
<router-link
:to="'/layout/' + item.path + '/' + child.path"
:key="child.path + cindex"
>
<el-menu-item :index="child.path + cindex">
<i :class="child.meta.icon"></i>
<span>{
{
child.meta.title }}</span>
</el-menu-item>
</router-link>
</template>
</el-submenu>
</template>
</el-menu>
</div>
</template>
<script>
export default {
data() {
return {
};
},
computed: {
menu() {
console.log("所有菜单", this.$store.getters.getRoutes);
return this.$store.getters.getRoutes[1].children;
},
},
methods: {
handleOpen() {
},
handleClose() {
},
},
};
</script>
<style scoped>
/* @import url(); 引入css类 */
</style>
在layout目录下,新建Bread.vue面包屑导航组件,引入到layout文件中
matched 顾名思义 就是 匹配,假如我们目前的路由是/a/aa-01
,那么此时 this.$route.matched
匹配到的会是一个数组,包含'/','/a','/a/aa-01'
,这三个path的路由信息。然后我们可以直接利用路由信息渲染我们的面包屑导航。
src\views\layout\Bread.vue
<!-- 面包屑导航 -->
<template>
<div class="container">
<i class="el-icon-s-fold"></i>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item v-for="(item, index) in breadArr" :key="index">
{
{
item.name }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default {
data() {
return {
breadArr: [], // 面包屑数组
};
},
watch: {
// $route(to, from) {
// // console.log(to)
// // 当前路由赋值
// this.currentPath = to.path;
// console.log(1, this.$route);
// this.breadcrumbArr = this.$route.matched; // 获取当前的路由记录
// },
$route: {
handler(val) {
// console.log(11, val); // val 即为监听的$route对象
// 先清空 breadArr,要不然越push 越多
this.breadArr = [];
val.matched.forEach((item, index) => {
if (index > 0) {
this.breadArr.push({
path: item.path,
name: item.meta.title,
});
}
});
//console.log(22, this.breadArr);
},
immediate: true, // 第一次页面加载就监听 而不是该对象发生变化才去监听
deep: true,
},
},
};
</script>
<style scoped lang='less'>
/* @import url(); 引入css类 */
@mainColor: #eaebec; //正确的
.container {
height: 30px;
width: 100%;
display: flex;
align-items: center;
background: @mainColor; // @mainColor;
i {
line-height: 30px;
font-size: 20px;
cursor: pointer;
padding-right: 20px;
}
}
</style>
在mock文件夹下的index.js文件中,定义接口如下:
//6.柱形图接口
Mock.mock('/getBarData', 'get', home.barData)
//7.饼形图接口
Mock.mock('/getPieData', 'get', home.pieData)
在mock文件夹下,创建homeMock.js文件,用来定义接口的数据返回:代码如下:
export default {
barData: () => {
// 返回柱形图数据
return {
code: 200,
msg: "柱形图数据",
data: {
name: "出勤率",
xAxisData: ["Mon", "Tue", "wed", "Thu", "Fri", "Sat"],
seriesData: [90, 85, 50, 100, 95, 92]
}
}
},
pieData: () => {
// 返回饼形图数据
return {
code: 200,
msg: "饼形图数据",
data: {
name: "",
seriesData: [{
// 数据项的名称
name: "HTML5",
// 数据项值8
value: 500,
},
{
// 数据项的名称
name: "JAVA",
// 数据项值8
value: 200,
},
{
// 数据项的名称
name: "大数据",
// 数据项值8
value: 100,
},
{
// 数据项的名称
name: "unity",
// 数据项值8
value: 50,
},
{
// 数据项的名称
name: "UI",
// 数据项值8
value: 50,
}]
}
}
}
}
在http目录下的http.js文件中,定义首页的数据请求,代码如下:
// 获取首页柱形图接口数据
export function getBarData(params) {
return instance({
url: '/getBarData',
method: 'get',
params: params
})
}
// 获取首页饼形图接口数据
export function getPieData(params) {
return instance({
url: '/getPieData',
method: 'get',
params: params
})
}
在home目录下的home.vue中,引入接口请求,然后渲染页面,代码如下:
<!-- 首页 -->
<template>
<div class="home">
<el-row>
<el-col :span="12">
<BarEchart></BarEchart>
</el-col>
<el-col :span="12">
<PieEchart></PieEchart>
</el-col>
</el-row>
</div>
</template>
<script>
// 引入柱形图组件
import BarEchart from "@/components/BarEchart";
// 引入饼形图
import PieEchart from "@/components/PieEchart";
export default {
data() {
return {
};
},
mounted() {
},
components: {
BarEchart,
PieEchart,
},
};
</script>
<style scoped lang='less'>
/* @import url(); 引入css类 */
.home {
width: 100%;
height: 500px;
}
</style>
在components目录下,将饼形图和柱状图分别定义成单独的组件。BarEchart.vue和PieEchart.vue如下:
BarEchart.vue 代码如下:
<!-- BarEchart.vue 柱形图组件 -->
<template>
<div id="Barbox">
<div id="barwrap"></div>
</div>
</template>
<script>
// 引入echarts
import * as echarts from "echarts";
// 引入请求接口
import {
getBarData } from "@/http/http";
export default {
data() {
return {
myChart: "",
};
},
mounted() {
// 基于准备好的dom,初始化echarts实例
this.myChart = echarts.init(document.getElementById("barwrap"));
// 绘制图表
getBarData().then((res) => {
if (res.code == 200) {
this.myChart.setOption(this.options(res.data));
}
});
},
methods: {
options(val) {
let option = {
title: {
text: "2115班每天出勤统计",
},
tooltip: {
formatter: "{b0}: {c0}%",
},
xAxis: {
data: val.xAxisData,
},
grid: {
},
yAxis: {
name: "出勤率",
axisLine: {
show: true, // 显示y轴轴线
lineStyle: {
type: "solid",
},
},
},
series: [
{
name: "出勤率",
type: "bar",
data: val.seriesData,
},
],
};
return option;
},
},
};
</script>
<style scoped lang='less'>
/* @import url(); 引入css类 */
#barwrap {
width: 100%;
height: 500px;
}
</style>
echart饼图示例: https://echarts.apache.org/examples/zh/editor.html?c=pie-simple
<!-- 饼形图组件 -->
<template>
<div class="pie_box">
<div id="pie_wrap"></div>
</div>
</template>
<script>
// 引入 echarts
import * as echarts from "echarts";
// 引入 接口请求
import {
getPieData } from "@/http/http";
export default {
data() {
return {
myechart: "",
};
},
mounted() {
this.myechart = echarts.init(document.getElementById("pie_wrap"));
getPieData().then((res) => {
if (res.code == 200) {
//给图表传参
this.myechart.setOption(this.options(res.data.seriesData));
}
});
},
methods: {
options(val) {
let option = {
title: {
text: "千锋各学科人数占比",
},
legend: {
right: 0,
top: "30px",
data: val.map((item) => {
return item.name;
}),
},
tooltip: {
},
series: [
{
type: "pie",
radius: [0, "50%"],
data: val,
},
],
};
return option;
},
},
};
</script>
<style scoped>
/* @import url(); 引入css类 */
#pie_wrap {
width: 100%;
height: 500px;
}
</style>
在mock下的index.js 文件中,定义首页后台数据接口
// 3.定义首页学生数据列表接口
// RegExp('/userList.*')
// 发现 Mockjs 本身对 GET 请求的支持并不是很友好。举个例子,使用 Mock.mock("/user/getUserInfo", "get", mockData) 的时候,它只会拦截url等于 /user/getUserInfo 的请求,而对于带参数的请求,如/user/getUserInfo?id=12,因为不等于 /user/getUserInfo 就拦截不到,报404错误。
// 使用正则进行匹配,Mock.mock(new RegExp(url + ".*"), "get", mockData)
// 其中表达式正则 .* 表示任意长度的任意字符;
Mock.mock(new RegExp('/getStudentList.*'), 'get', user.getTable)
在mock 目录下,新建userMock.js文件,定义该接口数据返回。
import Mock from 'mockjs'
let List = [] //全局list 保存所有的数据
let id = 1;
for (var i = 0; i < 100; i++) {
List.push(Mock.mock({
id: id++,
name: Mock.Random.cname(),
age: Mock.Random.integer(18, 30),
major: 'html5',
address: Mock.Random.county(true),
pay: Mock.Random.integer(0, 1),
graduateTime: Mock.Random.date('yyyy-MM-dd')
}))
}
// console.log(44, List)
export default {
getTable: (config) => {
// console.log(JSON.parse(config.body))
//搜索逻辑
const {
searchVal, page, pageSize } = JSON.parse(config.body)
//分页逻辑 mock 56
// page=1 pageSize=10
// page=2 pageSiz=10
// page=3 pageSiz=10
//公式: (page-1)*pageSize <= index< page* pageSize 0----9
let newList1 = List.filter(item => {
return item.name.indexOf(searchVal) != -1
})
let newList2 = newList1.filter((item, index) => {
return (page - 1) * pageSize <= index && index < page * pageSize
}) //10 ----- 19
// 20 ---- 29
return {
code: 200,
msg: '',
data: newList2, //10条数
total: List.length
}
},
editData: (config) => {
console.log(config)
let {
id, name, age, pay, major, address, graduateTime } = JSON.parse(config.body)
List.forEach(item => {
if (item.id == id) {
item.name = name;
item.age = age;
item.pay = pay;
item.major = major;
item.address = address;
item.graduateTime = graduateTime
}
})
return {
code: 200,
msg: '修改成功',
data: null
}
},
deleteData: (config) => {
//console.log(config);
let id = config.url.split('?')[1].split('=')[1]
let newList = List.filter((item) => {
return item.id != id
})
List = newList
return {
code: 200,
msg: "删除成功",
data: null
}
}
}
//获取用户管理页列表数据
export function getStudentList(params) {
return instance({
url: '/getStudentList',
method: 'get',
data: params
})
}
// 编辑用户接口
export function editUser(params) {
return instance({
url: '/editUser',
method: 'post',
data: params
})
}
// 删除用户接口
export function deleteUser(params) {
return instance({
url: '/deleteUser',
method: 'get',
params: params
})
}
在views 目录下,新建user.vue组件,用于展示首页右侧主体部分对应的首页页面。
筛选
批量删除
添加
{
{ scope.row.id }}
{
{ scope.row.name }}
{
{ scope.row.age }}
{
{ scope.row.major }}
{
{ scope.row.address }}
{
{ scope.row.pay }}
{
{ scope.row.graduateTime }}
编辑
删除