1、项目技术栈
- Vue
- Vue-Router
- Element-UI
- Axios
- Echarts
2、项目初始化
- 安装Vue脚手架
- 通过脚手架创建项目(手动配置)
- 路由配置
- 配置Element-UI,安装[babel-plugin-component],实现按需导入
- 配置Axios
- 实现Axios的发呢改装
3、Element-UI全局引入。
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
一.Api 封装
要把常用的API拆分出去最后导入main.js中就可以了
二. 登陆鉴权
三.登陆代码
判断是否有token值 若是有 就保存在store若是没有值就重新登陆 有验证规则
<template>
<div class="login">
<!-- 登录大盒子区域 -->
<div class="login_box">
<!-- log区域 -->
<div class="log_box">
<img src="../assets/logo.png" alt="" />
</div>
<!-- 表单区域 -->
<el-form
:model="loginForm"
:rules="rules"
ref="loginForm"
class="login_form"
>
<!-- 账号区域 -->
<el-form-item prop="username">
<el-input
prefix-icon="iconfont icon-user"
v-model="loginForm.username"
></el-input>
</el-form-item>
<!-- 密码区域 -->
<el-form-item prop="password">
<el-input
prefix-icon="iconfont icon-3702mima"
v-model="loginForm.password"
type="password"
></el-input>
</el-form-item>
<!-- 按钮区域 -->
<el-form-item class="right">
<el-button type="primary" @click="submitForm">登录</el-button>
<el-button type="info" @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import loginApi from '@/request/userApi'
export default {
data() {
return {
loginForm: {
username: "admin",
password: "123456",
},
rules: {
username: [
{ required: true, message: "请输入活动名称", trigger: "blur" },
{
min: 3,
max: 12,
message: "长度在 3 到 12 个字符",
trigger: "blur",
},
],
password: [
{ required: true, message: "请输入活动名称", trigger: "blur" },
{
min: 3,
max: 18,
message: "长度在 3 到 18 个字符",
trigger: "blur",
},
],
},
};
},
methods: {
submitForm() {
this.$refs.loginForm.validate(async (valid) => {
// console.log(valid);
if (!valid) return;
// let {data:res} = await this.$http.post("login", this.loginForm);
let {data:res} = await loginApi.login(this.loginForm);
// console.log(res);
if (res.meta.status !==200) return this.$message.error(res.meta.msg)
this.$message.success(res.meta.msg)
window.sessionStorage.setItem('token',res.data.token)
this.$router.push('/home')
});
},
resetForm(){
this.$refs.loginForm.resetFields();
}
},
};
</script>
<style lang="scss" scoped>
.login {
width: 100%;
height: 100%;
background-color: #2b5b6b;
}
.login_box {
width: 450px;
height: 300px;
background: #fff;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 3px;
box-shadow: 0 0 10px #ddd;
}
.log_box {
width: 130px;
height: 130px;
padding: 10px;
background: #fff;
border-radius: 50%;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 10px #ddd;
img {
width: 100%;
height: 100%;
border-radius: 50%;
border: 1px solid #efefef;
background: #efefef;
}
}
.login_form {
position: absolute;
bottom: 0;
width: 100%;
padding: 0 20px;
}
.right {
text-align: right;
}
</style>
四. 首页布局
主要用element-ui中的menu组件布局 然后获取左侧侧边栏的数据进行渲染
<template>
<div class="home">
<el-container>
<!-- 头部区域 -->
<el-header>
<div>
<img src="../assets/logo.png" alt="" />
<span>电商后台管理系统</span>
</div>
<el-button type="info" @click="logout">退出</el-button>
</el-header>
<!-- 内容区域 -->
<el-container>
<!-- 左侧列表区域 -->
<el-aside :width="toggieFlag ? '64px' : '200px'">
<!-- 侧边栏菜单区域 -->
<el-menu
router
:collapse="toggieFlag"
unique-opened
:collapse-transition="false"
background-color="#333744"
text-color="#fff"
active-text-color="#409Eff"
:default-active="$route.path"
>
<div class="toggle-button" @click="toggieCollapse">|||</div>
<!-- 一级菜单 -->
<el-submenu
:index="item.id + ''"
v-for="item in lists"
:key="item.id"
>
<!-- 一级菜单模板 -->
<template slot="title">
<i :class="icon[item.id]" class="icon"></i>
<span>{
{ item.authName }}</span>
</template>
<!-- 二级菜单 -->
<el-menu-item
:index="'/' + it.path"
v-for="it in item.children"
:key="it.id"
@click="higHlight(item.authName, it.authName)"
>
<!-- 二级模板区域 -->
<template slot="title">
<i class="el-icon-menu"></i>
<span>{
{ it.authName }}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<!-- 右侧内容区域 -->
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import loginApi from '@/request/userApi'
export default {
name: "Home",
components: {},
data() {
return {
// 左侧菜单数据
lists: [],
icon: {
125: "iconfont icon-users",
103: "el-icon-reading",
101: "iconfont icon-shangpin",
102: "iconfont icon-danju",
145: "iconfont icon-baobiao",
},
// 左侧菜单开关
toggieFlag: false,
// 高亮显示
activePath: "",
};
},
mounted() {
this.getList();
this.activePath = window.sessionStorage.getItem("activePath");
},
methods: {
logout() {
window.sessionStorage.removeItem("token");
window.sessionStorage.removeItem("activePath");
this.$router.push("/login");
},
async getList() {
const { data: res } = await loginApi.getLeltList();
// console.log(res);
if (res.meta.status !== 200) return this.$message.error(res.meta.msg);
this.lists = res.data;
// console.log(this.lists);
},
// 左侧菜单开关
toggieCollapse() {
this.toggieFlag = !this.toggieFlag;
},
// 面包屑导航
higHlight(one, two) {
// window.sessionStorage.setItem("activePath", activePath);
// this.activePath = activePath;
const obj = {
one: one,
two: two,
};
window.sessionStorage.setItem("name", JSON.stringify(obj));
},
},
// watch: {
// // 浏览器页面回退高亮显示
// $route(to, from) {
// this.activePath = to.path;
// window.sessionStorage.setItem("activePath", to.path);
// },
// },
};
</script>
<style lang="scss" scoped>
.home {
height: 100%;
}
.el-container {
height: 100%;
}
.el-header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #373d41;
color: #333;
// padding-left: 0;
div {
display: flex;
align-items: center;
img {
width: 60px;
height: 60px;
border-radius: 50%;
background-color: #eaedea;
}
span {
color: #fff;
font-size: 20px;
margin-left: 15px;
}
}
}
.el-aside {
background-color: #333744;
color: #333;
}
.el-main {
background-color: #eaedea;
color: #333;
}
.el-menu {
border-right: 0;
}
.toggle-button {
background-color: #4a5064;
font-size: 10px;
line-height: 24px;
color: #fff;
text-align: center;
letter-spacing: 0.2em;
}
.icon {
margin-right: 15px;
}
</style>
五.用户管理界面
主要应用到了 曾删改查 还有分页 进行页面渲染
<template>
<div>
<!-- 面包屑区域 -->
<Breadcrumb></Breadcrumb>
<el-card>
<el-row :gutter="20">
<!-- 搜索框区域 -->
<el-col :span="9">
<el-input
placeholder="请输入内容"
v-model="queryInfo.query"
clearable
@clear="getUsersList"
@change="getUsersList"
>
<el-button
slot="append"
icon="el-icon-search"
@click="getUsersList"
></el-button>
</el-input>
</el-col>
<!-- 添加用户区域 -->
<el-col :span="4">
<el-button type="primary" @click="addUsersShow = true"
>添加用户</el-button
>
</el-col>
</el-row>
<!-- 用户列表区域 -->
<el-table :data="usersList" border stripe style="width: 100%">
<el-table-column type="index" label="#"></el-table-column>
<el-table-column prop="username" label="姓名"></el-table-column>
<el-table-column prop="email" label="邮箱"></el-table-column>
<el-table-column prop="mobile" label="电话"></el-table-column>
<el-table-column prop="role_name" label="角色"></el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-switch
v-model="scope.row.mg_state"
@change="switchChange(scope.row)"
>
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="220">
<template slot-scope="scope">
<!-- 编辑区域 -->
<el-button
size="mmini"
type="primary"
icon="el-icon-edit"
@click="modifyBackfillShow(scope.row)"
></el-button>
<!-- 删除区域 -->
<el-button
size="mmini"
type="danger"
icon="el-icon-delete"
@click="removeUser(scope.row.id)"
></el-button>
<!-- 设置区域 -->
<el-button
size="mmini"
type="warning"
icon="el-icon-setting"
@click="setRole(scope.row)"
></el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页器区域 1.监听每页多少条 2.监听当前页变化 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryInfo.pagenum"
:page-sizes="[1, 2, 5, 10]"
:page-size="queryInfo.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</el-card>
<!-- 添加用户对话框区域 -->
<el-dialog title="添加用户" :visible.sync="addUsersShow">
<