电商管理系统(PC端)项目实施
一、创建项目
1.安装 vue-cli
$ npm install -g @vue/cli
2.创建项目
$ vue create management
第一步:
第二步:
第三步:
第四步:
第五步:
第六步:
项目创建成功:
二、安装使用 Element UI
1.安装 Element UI
$ npm i element-ui -S
2.引入使用Element UI
修改 main.js
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
三、添加登录页
1.views
文件夹新建 LoginView.vue
2.添加访问路由
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView')
},
3.修改 LoginView.vue
<template>
<div class="login">
<section>
<h2>电商管理系统</h2>
<el-form
:model="loginForm"
status-icon
:rules="rules"
ref="loginForm"
>
<el-form-item prop="username">
<el-input v-model="loginForm.username" prefix-icon="el-icon-user" placeholder="用户名"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" v-model="loginForm.password" prefix-icon="el-icon-lock" placeholder="密码"></el-input>
</el-form-item>
<el-form-item>
<el-button style="width: 100%" type="primary" @click="handleLogin('loginForm')">登录</el-button>
</el-form-item>
</el-form>
</section>
</div>
</template>
<script>
export default {
data() {
return {
loginForm: {
username: 'admin123',
password: 'admin123',
code: ''
},
rules: {
username: [
{ required: true, message: '用户名不能为空', trigger: 'blur' },
],
password: [
{ required: true, message: '密码不能为空', trigger: 'blur' },
],
}
}
},
methods: {
handleLogin(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
//
} else {
console.log('error submit!')
return false
}
})
}
}
}
</script>
<style scoped>
.login {
display: flex;
align-items: center;
justify-content: center;
background: url("../assets/login-background.jpg") no-repeat center / cover;
height: 100vh;
}
.login h2 {
text-align: center;
color: #707070;
}
.login section {
border-radius: 6px;
background: #fff;
width: 400px;
padding: 25px 25px 5px 25px;
}
</style>
4.添加登录功能
1)导入数据库
drop database if exists litemall;
drop user if exists 'litemall'@'%';
-- 支持emoji:需要mysql数据库参数: character_set_server=utf8mb4
create database litemall default character set utf8mb4 collate utf8mb4_unicode_ci;
use litemall;
create user 'litemall'@'%' identified by 'litemall123456';
grant all privileges on litemall.* to 'litemall'@'%';
flush privileges;
导入
litemall_table.sql
文件创建数据表导入
litemall_data.sql
文件创建数据
2)启动 litemall-admin-api-0.1.0-exec.jar
$ java -jar litemall-admin-api-0.1.0-exec.jar
3)安装 axios
$ npm i axios -S
4)修改 main.js
import axios from "axios";
Vue.prototype.$axios = axios
5)完善 LoginView.vue
登录方法
handleLogin(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.$axios({
method: 'POST',
url: 'http://localhost:8080/admin/auth/login',
data: {
...this.loginForm
}
}).then(res => {
// console.log(res.data.data)
localStorage.setItem('X-Litemall-Admin-Token', res.data.data.token)
this.$router.push({
name: 'home'
})
}).catch(e => {
console.log(e)
})
} else {
console.log('error submit!')
return false
}
})
}
四、创建 Layout 布局组件
1. components/
文件夹创建 Layout.vue
<template>
<el-container>
<el-header>
<span>
<el-image
style="width: 50px; height: 50px"
:src="require('../assets/logo.png')"
fit="cover"/>
<b>电商管理系统</b>
</span>
<span>
<el-image
style="width: 50px; height: 50px"
:src="$store.state.userinfo.avatar"
fit="cover"/>
<span></span>
</span>
</el-header>
<el-container class="container">
<el-aside width="200px">
<ul>
<li><router-link to="/">首页</router-link></li>
</ul>
</el-aside>
<el-main>
<slot></slot>
</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
name: "Layout",
}
</script>
<style scoped>
.container {
height: calc(100vh - 60px);
}
.el-header {
background-color: #B3C0D1;
color: #333;
display: flex;
justify-content: space-between;
align-items: center;
}
.el-header span {
display: flex;
align-items: center;
}
.el-header span .el-image {
margin-right: 5px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
}
.el-aside ul {
list-style: none;
}
.el-aside ul li {
height: 40px;
line-height: 40px;
}
.el-aside a {
text-decoration: none;
color: #333333;
}
.el-aside a.router-link-exact-active {
color: #42b983;
}
.el-main {
background-color: #E9EEF3;
color: #333;
}
</style>
2.main.js
注册组件
import Layout from "@/components/Layout";
Vue.component(Layout.name, Layout)
五、完善主页
修改 views/HomeView.vue
<template>
<layout class="home">
<el-row :gutter="20" class="data">
<el-col :span="6">
<el-statistic group-separator="," :value="dashboard.goodsTotal" title="商品总量"></el-statistic>
</el-col>
<el-col :span="6">
<el-statistic group-separator="," :value="dashboard.userTotal" title="用户数量"></el-statistic>
</el-col>
<el-col :span="6">
<el-statistic group-separator="," :value="dashboard.productTotal" title="商品数量"></el-statistic>
</el-col>
<el-col :span="6">
<el-statistic group-separator="," :value="dashboard.orderTotal" title="订单总量"></el-statistic>
</el-col>
</el-row>
</layout>
</template>
<script>
export default {
name: 'HomeView',
data() {
return {
dashboard: {
goodsTotal: 0,
userTotal: 0,
productTotal: 0,
orderTotal: 0
}
};
},
created() {
this.$axios({
headers: {
'X-Litemall-Admin-Token': localStorage.getItem('X-Litemall-Admin-Token')
},
url: 'http://localhost:8080/admin/dashboard',
}).then(res => {
this.dashboard = res.data.data
})
}
}
</script>
<style scoped>
.home .data {
margin-top: 300px;
}
</style>
六、添加商品管理页
1.views/
文件夹创建 GoodsList.vue
<template>
<layout>
<el-card class="box-card">
<div slot="header" style="display: flex; justify-content: space-between">
<span>商品列表</span>
<el-button type="primary" size="mini">上架商品</el-button>
</div>
<el-table
:data="goodsList"
style="width: 100%">
<el-table-column label="商品名称" prop="name"/>
<el-table-column label="商品图片">
<template slot-scope="scope">
<el-image style="width: 100px;" :src="scope.row.picUrl" fit="cover"/>
</template>
</el-table-column>
<el-table-column label="简介" prop="brief"/>
<el-table-column label="销售价" prop="retailPrice" width="100" align="center"/>
<el-table-column label="库存价" prop="counterPrice" width="100" align="center"/>
<el-table-column label="创建时间" prop="addTime"/>
<el-table-column label="更新时间" prop="updateTime"/>
<el-table-column label="是否上架" prop="isOnSale" width="100" align="center">
<template slot-scope="scope">
<el-switch
v-model="!scope.row.deleted"
active-color="#13ce66"
inactive-color="#ff4949"/>
</template>
</el-table-column>
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
background
layout="prev, pager, next"
:page-count="pager.pages"
:current-page="pager.page"
@current-change="handlePageChange"
>
</el-pagination>
</el-card>
</layout>
</template>
<script>
export default {
name: "GoodsList",
data() {
return {
goodsList: [],
pager: {
page: 1,
limit: 20,
total: 1,
pages: 1
}
}
},
created() {
this.$axios({
headers: {
'X-Litemall-Admin-Token': localStorage.getItem('X-Litemall-Admin-Token')
},
url: "http://localhost:8080/admin/goods/list?page=1&limit=20&goodsSn&name&sort=add_time&order=desc&goodsId"
}).then(res => {
// console.log(res.data.data)
this.goodsList = res.data.data.list
this.pager = {
total: res.data.data.total,
pages: res.data.data.pages,
page: res.data.data.page,
limit: res.data.data.limit,
}
})
},
methods: {
handlePageChange(page) {
this.$axios({
headers: {
'X-Litemall-Admin-Token': localStorage.getItem('X-Litemall-Admin-Token')
},
url: `http://localhost:8080/admin/goods/list?page=${page}&limit=20&goodsSn&name&sort=add_time&order=desc&goodsId`
}).then(res => {
// console.log(res.data.data)
this.goodsList = res.data.data.list
this.pager = {
total: res.data.data.total,
pages: res.data.data.pages,
page: res.data.data.page,
limit: res.data.data.limit,
}
})
},
handleEdit(row) {
console.log(row.id)
},
handleDelete(row) {
this.$confirm('此操作将永久删除该商品, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
}
}
</script>
<style scoped>
</style>
2.添加访问路由
{
path: '/goods',
name: 'goods-list',
component: () => import('../views/GoodsList')
},
七、添加商品分类页
1.views/
文件夹创建 CategoryList.vue
<template>
<layout>
<el-card class="box-card">
<div slot="header" style="display: flex; justify-content: space-between">
<span>分类列表</span>
<el-button type="primary" size="mini" @click="$router.push({ name: 'category-create' })">新建分类</el-button>
</div>
<el-table
:data="categoryList"
style="width: 100%;"
row-key="id"
border
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column label="名称" prop="name"/>
<el-table-column label="层级" prop="level" width="70" align="center"/>
<el-table-column label="图片">
<template slot-scope="scope">
<el-image style="width: 100%;" :src="scope.row.picUrl" fit="cover"/>
</template>
</el-table-column>
<el-table-column label="图标" width="100" align="center">
<template slot-scope="scope">
<el-image style="width: 50px;" :src="scope.row.iconUrl" fit="cover"/>
</template>
</el-table-column>
<el-table-column label="描述" prop="desc"/>
<el-table-column label="操作" width="130" align="center">
<template slot-scope="scope">
<el-button size="mini" circle type="primary" icon="el-icon-view" @click="handleDetail(scope.row)"/>
<el-button size="mini" circle type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)"/>
<el-button size="mini" circle type="danger" icon="el-icon-delete" @click="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
</el-card>
</layout>
</template>
<script>
export default {
name: "CategoryList",
data() {
return {
categoryList: []
}
},
created() {
this.getList()
},
methods: {
getList() {
this.$axios({
headers: {
'X-Litemall-Admin-Token': localStorage.getItem('X-Litemall-Admin-Token')
},
url: 'http://localhost:8080/admin/category/list'
}).then(res => {
this.categoryList = res.data.data.list
// console.log(res.data.data)
})
},
handleDetail(row) {
this.$router.push({
name: 'category-detail',
params: {
id: row.id
}
})
},
handleEdit(row) {
this.$router.push({
name: 'category-edit',
params: {
id: row.id
}
})
},
handleDelete(row) {
}
}
}
</script>
<style scoped>
</style>
2.添加路由访问
{
path: '/category',
name: 'category-list',
component: () => import('../views/CategoryList')
},
八、添加分类创建页
1.views/
文件夹创建 CategoryCreate.vue
<template>
<layout>
<el-card class="box-card">
<div slot="header" style="display: flex; justify-content: space-between">
<span>新建分类</span>
</div>
<el-tabs type="border-card" v-model="levelVal" @tab-click="handleTabChange">
<el-tab-pane label="一级类目" name="L1">
<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" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="图片" prop="picUrl">
<el-upload
class="avatar-uploader"
action="http://localhost:8080/admin/storage/create"
:headers="headers"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<img v-if="ruleForm.picUrl" :src="ruleForm.picUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item label="描述" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></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>
</el-tab-pane>
<el-tab-pane label="二级类目" name="L2">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="父分类" prop="pid">
<el-select v-model="ruleForm.pid" placeholder="请选择父分类">
<el-option
v-for="item of level1"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="ruleForm.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="图片" prop="picUrl">
<el-upload
class="avatar-uploader"
action="http://localhost:8080/admin/storage/create"
:headers="headers"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<img v-if="ruleForm.picUrl" :src="ruleForm.picUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item label="描述" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></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>
</el-tab-pane>
</el-tabs>
</el-card>
</layout>
</template>
<script>
export default {
name: "CategoryCreate",
data() {
return {
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
},
ruleForm: {
pid: '',
name: '',
desc: '',
iconUrl: '',
picUrl: '',
level: "L2",
},
rules: {
pid: [{ required: true, message: '请选择父分类', trigger: 'change' }],
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
},
level1: [],
levelVal: 'L2',
}
},
created() {
this.$axios({
url: 'http://localhost:8080/admin/category/l1',
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
}
}).then(res => {
// console.log(res.data.data)
this.level1 = res.data.data.list
})
},
methods: {
handleTabChange(t) {
console.log(t.name)
switch (t.name) {
case 'L1':
this.ruleForm = {
name: '',
desc: '',
iconUrl: '',
picUrl: '',
level: "L1",
}
this.rules = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
}
break
case 'L2':
this.ruleForm = {
pid: '',
name: '',
desc: '',
iconUrl: '',
picUrl: '',
level: "L2",
}
this.rules = {
pid: [{ required: true, message: '请选择父分类', trigger: 'change' }],
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
}
break
}
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$axios({
method: 'POST',
url: ' http://localhost:8080/admin/category/create',
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
},
data: {
...this.ruleForm
}
}).then(res => {
// console.log(res)
if (res.data.errno === 0) {
this.$router.replace({
name: 'category-list'
})
}
}).catch(e => {
console.log(e)
})
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
handleAvatarSuccess(res, file) {
this.ruleForm.picUrl = res.data.url;
}
}
}
</script>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
2.添加路由访问
{
path: '/category/create',
name: 'category-create',
component: () => import('../views/CategoryCreate')
},
九、添加分类详情页
1.views/
文件夹创建 `CategoryDetail.vue
2.添加路由访问
{
path: '/category/:id',
name: 'category-detail',
component: () => import('../views/CategoryDetail')
},
十、添加分类编辑页
1.views/
文件夹创建 CategoryEdit.vue
<template>
<layout>
<el-card class="box-card">
<div slot="header" style="display: flex; justify-content: space-between">
<span>分类编辑</span>
</div>
<el-tabs type="border-card" v-model="levelVal" @tab-click="handleTabChange">
<el-tab-pane label="一级类目" name="L1">
<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" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="图片" prop="picUrl">
<el-upload
class="avatar-uploader"
action="http://localhost:8080/admin/storage/create"
:headers="headers"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<img v-if="ruleForm.picUrl" :src="ruleForm.picUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item label="描述" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="二级类目" name="L2">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="父分类" prop="pid">
<el-select v-model="ruleForm.pid" placeholder="请选择父分类">
<el-option
v-for="item of level1"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="ruleForm.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="图片" prop="picUrl">
<el-upload
class="avatar-uploader"
action="http://localhost:8080/admin/storage/create"
:headers="headers"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<img v-if="ruleForm.picUrl" :src="ruleForm.picUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item label="描述" prop="desc">
<el-input type="textarea" v-model="ruleForm.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</el-card>
</layout>
</template>
<script>
export default {
name: "CategoryEdit",
data() {
return {
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
},
ruleForm: {
pid: '',
name: '',
desc: '',
iconUrl: '',
picUrl: '',
level: "L2",
},
rules: {
pid: [{ required: true, message: '请选择父分类', trigger: 'change' }],
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
},
level1: [],
levelVal: 'L2',
}
},
created() {
this.$axios({
url: 'http://localhost:8080/admin/category/l1',
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
}
}).then(res => {
// console.log(res.data.data)
this.level1 = res.data.data.list
})
this.$axios({
method: 'GET',
url: 'http://localhost:8080/admin/category/read?id='+this.$route.params.id,
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
}
}).then(res => {
console.log(res)
this.levelVal = res.data.data.level
this.ruleForm = res.data.data
switch (this.levelVal) {
case 'L1':
this.rules = {
pid: [{ required: true, message: '请选择父分类', trigger: 'change' }],
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
}
break
case 'L2':
this.rules = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
}
break
}
})
},
methods: {
handleTabChange(t) {
switch (t.name) {
case 'L1':
this.rules = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
}
break
case 'L2':
this.rules = {
pid: [{ required: true, message: '请选择父分类', trigger: 'change' }],
name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
picUrl: [{ required: true, message: '图片不能为空', trigger: 'change' }]
}
break
}
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$axios({
method: 'POST',
url: ' http://localhost:8080/admin/category/update',
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
},
data: {
...this.ruleForm
}
}).then(res => {
// console.log(res)
if (res.data.errno === 0) {
this.$router.replace({
name: 'category-list'
})
}
}).catch(e => {
console.log(e)
})
} else {
console.log('error submit!!');
return false;
}
});
},
handleAvatarSuccess(res, file) {
this.ruleForm.picUrl = res.data.url;
}
}
}
</script>
<style scoped>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
2.添加路由访问
{
path: '/category/edit/:id',
name: 'category-edit',
component: () => import('../views/CategoryEdit')
},
十一、添加分类编辑删除功能
handleDelete(row) {
this.$confirm('此操作将永久删除该分类, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$axios({
method: 'POST',
url: 'http://localhost:8080/admin/category/delete',
headers: {
'X-Litemall-Admin-Token': window.localStorage.getItem('X-Litemall-Admin-Token')
},
data: {
...row
}
}).then(res => {
this.getList()
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(e => {
console.log(e)
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
十二、添加用户信息展示
1.修改 store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from "axios";
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userinfo: {
avatar: require('../assets/logo.png')
}
},
getters: {
},
mutations: {
SET_USERINFO(state, data) {
state.userinfo = data
}
},
actions: {
getUserinfo({commit}) {
axios({
url: 'http://localhost:8080/admin/auth/info',
headers: {
'X-Litemall-Admin-Token': localStorage.getItem('X-Litemall-Admin-Token')
}
}).then(res => {
// console.log(res)
commit('SET_USERINFO', res.data.data)
})
}
},
modules: {
}
})
2.修改 Layout.vue
<script>
export default {
name: "Layout",
created() {
this.$store.dispatch('getUserinfo')
},
methods: {
handleLogout() {
this.$confirm('此操作将退出登录, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$axios({
url: 'http://localhost:8080/admin/auth/logout',
headers: {
'X-Litemall-Admin-Token': localStorage.getItem('X-Litemall-Admin-Token')
}
}).then(res => {
this.$router.replace({
name: 'login'
})
localStorage.removeItem('X-Litemall-Admin-Token')
this.$message({
type: 'success',
message: '退出登录成功!'
});
}).catch(e => {
console.log(e)
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消退出登录'
});
});
}
}
}
</script>
十三、添加导航守卫
router.beforeEach((to, from, next) => {
if (to.name !== 'login' && !localStorage.getItem('X-Litemall-Admin-Token')) {
next({ name: 'login' })
} else {
next()
}
})