update
This commit is contained in:
parent
83cca9fbd1
commit
be7002e3d6
@ -12,4 +12,18 @@ export default [
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/userinfo",
|
||||
method: "get",
|
||||
timeout: 100,
|
||||
response: {
|
||||
code: 200,
|
||||
message: "获取用户信息成功",
|
||||
data: {
|
||||
id: 1,
|
||||
userName: 'admin',
|
||||
avatar: "@image('48x48', '#fb0a2a')"
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
8
src/api/app.js
Normal file
8
src/api/app.js
Normal file
@ -0,0 +1,8 @@
|
||||
import request from '@/utils/request'
|
||||
// 获取用户信息
|
||||
export const GetUserinfo = () => {
|
||||
return request({
|
||||
url: "/api/userinfo",
|
||||
method: "get"
|
||||
});
|
||||
};
|
||||
126
src/layout/components/Sidebar/index.vue
Normal file
126
src/layout/components/Sidebar/index.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div
|
||||
class="left"
|
||||
:class="{collapse:collapse}"
|
||||
>
|
||||
<div class="brand">
|
||||
<img
|
||||
class="logo"
|
||||
src="~@/assets/logo.png"
|
||||
>
|
||||
<div class="title">ERP管理系统</div>
|
||||
</div>
|
||||
<el-menu
|
||||
class="menu"
|
||||
:collapse="collapse"
|
||||
:uniqueOpened="true"
|
||||
default-active="2"
|
||||
background-color="#2d3a4b"
|
||||
text-color="#fff"
|
||||
active-text-color="#fff"
|
||||
>
|
||||
<el-submenu index="1">
|
||||
<template #title>
|
||||
<i class="el-icon-location"></i>
|
||||
<span>导航一</span>
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<template #title>分组一</template>
|
||||
<el-menu-item index="1-1">选项1</el-menu-item>
|
||||
<el-menu-item index="1-2">选项2</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-menu-item-group title="分组2">
|
||||
<el-menu-item index="1-3">选项3</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-submenu index="1-4">
|
||||
<template #title>选项4</template>
|
||||
<el-menu-item index="1-4-1">选项1</el-menu-item>
|
||||
</el-submenu>
|
||||
</el-submenu>
|
||||
<el-menu-item index="2">
|
||||
<i class="el-icon-menu"></i>
|
||||
<template #title>导航二</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
index="3"
|
||||
disabled
|
||||
>
|
||||
<i class="el-icon-document"></i>
|
||||
<template #title>导航三</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="4">
|
||||
<i class="el-icon-setting"></i>
|
||||
<template #title>导航四</template>
|
||||
</el-menu-item>
|
||||
<el-submenu index="5">
|
||||
<template #title>
|
||||
<i class="el-icon-location"></i>
|
||||
<span>导航一</span>
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<template #title>分组一</template>
|
||||
<el-menu-item index="5-1">选项1</el-menu-item>
|
||||
<el-menu-item index="5-2">选项2</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-menu-item-group title="分组2">
|
||||
<el-menu-item index="5-3">选项3</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, computed } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore();
|
||||
const collapse = computed(() => !!store.state.app.sidebar.collapse);
|
||||
|
||||
return {
|
||||
collapse,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.left {
|
||||
width: 210px;
|
||||
background: #2d3a4b;
|
||||
transition: all 0.3s;
|
||||
overflow: hidden;
|
||||
&.collapse {
|
||||
width: 64px;
|
||||
.brand .title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.brand {
|
||||
height: 48px;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.logo {
|
||||
max-width: 32px;
|
||||
max-height: 32px;
|
||||
}
|
||||
.title {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
margin-left: 8px;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
}
|
||||
.menu {
|
||||
border: none;
|
||||
}
|
||||
::v-deep(.el-menu-item.is-active) {
|
||||
background: #0174df !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
9
src/layout/components/Tabsbar/index.vue
Normal file
9
src/layout/components/Tabsbar/index.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div class="tabs"></div>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
.tabs {
|
||||
height: 32px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
}
|
||||
</style>
|
||||
68
src/layout/components/Topbar/Breadcrumbs.vue
Normal file
68
src/layout/components/Topbar/Breadcrumbs.vue
Normal file
@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<el-breadcrumb
|
||||
separator="/"
|
||||
class="breadcrumb"
|
||||
>
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, index) in breadcrumbs"
|
||||
:key="item.path"
|
||||
:class="{no_link: index === breadcrumbs.length - 1}"
|
||||
:to="index < breadcrumbs.length - 1 ? item.path : ''"
|
||||
>
|
||||
{{item.meta.title}}
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
<script>
|
||||
import { defineComponent, ref, onBeforeMount } from "vue";
|
||||
import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const routes = router.getRoutes();
|
||||
const breadcrumbs = ref([]);
|
||||
|
||||
const getBreadcrumbs = (route) => {
|
||||
const res = [{ path: "/", meta: { title: "首页" } }];
|
||||
const { parentBreadcrumb } = route.meta;
|
||||
if (!!parentBreadcrumb) {
|
||||
const parents = routes.filter((item) =>
|
||||
parentBreadcrumb.includes(item.name)
|
||||
);
|
||||
res.push(...parents);
|
||||
}
|
||||
if (route.name !== "home") res.push(route);
|
||||
breadcrumbs.value = res;
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
getBreadcrumbs(route);
|
||||
});
|
||||
|
||||
onBeforeRouteUpdate((to) => {
|
||||
getBreadcrumbs(to);
|
||||
});
|
||||
|
||||
return {
|
||||
breadcrumbs,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.breadcrumb {
|
||||
margin-left: 10px;
|
||||
::v-deep(a),
|
||||
::v-deep(.is-link) {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.no_link {
|
||||
::v-deep(.el-breadcrumb__inner) {
|
||||
color: #97a8be !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
src/layout/components/Topbar/Hamburger.vue
Normal file
38
src/layout/components/Topbar/Hamburger.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<i
|
||||
class="fold-btn el-icon-s-fold"
|
||||
:class="{collapse:collapse}"
|
||||
@click="handleToggleMenu"
|
||||
></i>
|
||||
</template>
|
||||
<script>
|
||||
import { defineComponent, computed } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore();
|
||||
const collapse = computed(() => !!store.state.app.sidebar.collapse);
|
||||
const handleToggleMenu = () => {
|
||||
store.commit("app/setCollapse", +!collapse.value);
|
||||
};
|
||||
return {
|
||||
collapse,
|
||||
handleToggleMenu,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.fold-btn {
|
||||
line-height: 48px;
|
||||
padding: 0 10px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
&.collapse {
|
||||
transform: scale(-1, 1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
65
src/layout/components/Topbar/Userinfo.vue
Normal file
65
src/layout/components/Topbar/Userinfo.vue
Normal file
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<el-dropdown>
|
||||
<div class="userinfo">
|
||||
<template v-if="!userinfo">
|
||||
<i class="el-icon-user" /> admin
|
||||
</template>
|
||||
<template v-else>
|
||||
<img
|
||||
class="avatar"
|
||||
:src="userinfo.avatar"
|
||||
/> {{userinfo.userName}}
|
||||
</template>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
<el-dropdown-item>修改密码</el-dropdown-item>
|
||||
<el-dropdown-item>锁定屏幕</el-dropdown-item>
|
||||
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, defineComponent } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { useRouter } from "vue-router";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
const userinfo = computed(() => store.state.app.userinfo);
|
||||
const logout = () => {
|
||||
store.commit("app/clearToken");
|
||||
router.push("/login");
|
||||
};
|
||||
return {
|
||||
userinfo,
|
||||
logout,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.userinfo {
|
||||
padding: 0 16px;
|
||||
line-height: 48px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.el-icon-user {
|
||||
font-size: 16px;
|
||||
}
|
||||
.avatar {
|
||||
margin-right: 8px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
37
src/layout/components/Topbar/index.vue
Normal file
37
src/layout/components/Topbar/index.vue
Normal file
@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="navigation">
|
||||
<hamburger />
|
||||
<breadcrumbs />
|
||||
</div>
|
||||
<div class="action">
|
||||
<userinfo />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import Hamburger from "./Hamburger.vue";
|
||||
import Breadcrumbs from "./Breadcrumbs.vue";
|
||||
import Userinfo from "./Userinfo.vue";
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Hamburger,
|
||||
Breadcrumbs,
|
||||
Userinfo,
|
||||
},
|
||||
setup() {},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.header {
|
||||
height: 48px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.navigation {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
63
src/layout/index.vue
Normal file
63
src/layout/index.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<sidebar />
|
||||
<div class="right">
|
||||
<div class="top">
|
||||
<topbar />
|
||||
<tabsbar />
|
||||
</div>
|
||||
<div class="main">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { defineComponent, onBeforeMount } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import Sidebar from "./components/Sidebar/index.vue";
|
||||
import Topbar from "./components/Topbar/index.vue";
|
||||
import Tabsbar from "./components/Tabsbar/index.vue";
|
||||
import { GetUserinfo } from "@/api/app";
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Sidebar,
|
||||
Topbar,
|
||||
Tabsbar,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
const getUserinfo = async () => {
|
||||
const { code, data } = await GetUserinfo();
|
||||
if (+code === 200) {
|
||||
store.commit("app/setUserinfo", data);
|
||||
}
|
||||
};
|
||||
onBeforeMount(() => {
|
||||
getUserinfo();
|
||||
});
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.wrapper {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.top {
|
||||
background: #fff;
|
||||
}
|
||||
.main {
|
||||
flex: 1;
|
||||
background: #f0f2f5;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,18 +1,24 @@
|
||||
// index.js
|
||||
import { createRouter, createWebHistory } from "vue-router"
|
||||
import home from './modules/home'
|
||||
import { createRouter, createWebHashHistory } from "vue-router"
|
||||
import layout from '@/layout/index.vue'
|
||||
import login from './modules/login'
|
||||
import home from './modules/home'
|
||||
import user from './modules/user'
|
||||
|
||||
import { TOKEN } from '@/store/modules/user'
|
||||
import { TOKEN } from '@/store/modules/app'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
history: createWebHashHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/home'
|
||||
component: layout,
|
||||
redirect: '/home',
|
||||
children: [
|
||||
...home,
|
||||
...user
|
||||
]
|
||||
},
|
||||
...home,
|
||||
...login
|
||||
],
|
||||
});
|
||||
|
||||
@ -6,5 +6,8 @@ export default [
|
||||
path: "/home",
|
||||
name: "home",
|
||||
component: Home,
|
||||
meta: {
|
||||
title: "首页",
|
||||
}
|
||||
}
|
||||
]
|
||||
23
src/router/modules/user.js
Normal file
23
src/router/modules/user.js
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
const User = () => import("@/views/user/index.vue");
|
||||
const AddUser = () => import("@/views/user/AddUser.vue");
|
||||
|
||||
export default [
|
||||
{
|
||||
path: "/user",
|
||||
name: "user",
|
||||
component: User,
|
||||
meta: {
|
||||
title: "用户管理",
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/user/add",
|
||||
name: "addUser",
|
||||
component: AddUser,
|
||||
meta: {
|
||||
title: "添加用户",
|
||||
parentBreadcrumb: ["user"]
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,9 +1,9 @@
|
||||
//index.js
|
||||
import { createStore } from "vuex";
|
||||
import user from "./modules/user";
|
||||
import app from "./modules/app";
|
||||
|
||||
export default createStore({
|
||||
modules: {
|
||||
user,
|
||||
app
|
||||
},
|
||||
});
|
||||
@ -5,6 +5,10 @@ export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
authorization: getItem(TOKEN),
|
||||
sidebar: {
|
||||
collapse: getItem('collapse')
|
||||
},
|
||||
userinfo: null
|
||||
},
|
||||
mutations: {
|
||||
setToken (state, data) {
|
||||
@ -17,6 +21,21 @@ export default {
|
||||
// 保存到localStorage
|
||||
removeItem(TOKEN);
|
||||
},
|
||||
setCollapse (state, data) {
|
||||
state.sidebar.collapse = data;
|
||||
// 保存到localStorage
|
||||
setItem('collapse', data);
|
||||
},
|
||||
clearCollapse (state) {
|
||||
state.sidebar.collapse = '';
|
||||
// 保存到localStorage
|
||||
removeItem('collapse');
|
||||
},
|
||||
setUserinfo (state, data) {
|
||||
state.userinfo = data;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
||||
},
|
||||
actions: {},
|
||||
};
|
||||
@ -12,7 +12,7 @@ const service = axios.create({
|
||||
// 拦截请求
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
const authorization = store.state.user;
|
||||
const authorization = store.state.app;
|
||||
if (authorization) {
|
||||
config.headers.Authorization = `Bearer ${authorization.token}`;
|
||||
}
|
||||
@ -36,7 +36,7 @@ service.interceptors.response.use(
|
||||
// 响应拦截器中的 error 就是那个响应的错误对象
|
||||
if (error.response && error.response.status === 401) {
|
||||
// 校验是否有 refresh_token
|
||||
const { authorization } = store.state;
|
||||
const { authorization } = store.state.app;
|
||||
if (!authorization || !authorization.refresh_token) {
|
||||
router.push("/login");
|
||||
|
||||
@ -54,7 +54,7 @@ service.interceptors.response.use(
|
||||
});
|
||||
// 如果获取成功,则把新的 token 更新到容器中
|
||||
// console.log('刷新 token 成功', res)
|
||||
store.commit("setToken", {
|
||||
store.commit("app/setToken", {
|
||||
token: res.data.data.token, // 最新获取的可用 token
|
||||
refresh_token: authorization.refresh_token, // 还是原来的 refresh_token
|
||||
});
|
||||
@ -67,7 +67,7 @@ service.interceptors.response.use(
|
||||
// console.log('请求刷线 token 失败', err)
|
||||
router.push("/login");
|
||||
// 清除token
|
||||
store.commit("clearToken")
|
||||
store.commit("app/clearToken")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -97,7 +97,7 @@ export default defineComponent({
|
||||
router.push(!!targetPath ? targetPath : "/");
|
||||
},
|
||||
});
|
||||
store.commit("user/setToken", data);
|
||||
store.commit("app/setToken", data);
|
||||
} else {
|
||||
ctx.$message.error(message);
|
||||
}
|
||||
|
||||
3
src/views/user/AddUser.vue
Normal file
3
src/views/user/AddUser.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
addUser
|
||||
</template>
|
||||
3
src/views/user/index.vue
Normal file
3
src/views/user/index.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
user
|
||||
</template>
|
||||
27
项目开发手册.md
27
项目开发手册.md
@ -32,7 +32,6 @@ Vue3 + Element-plus + Vite
|
||||
|
||||
> 我们将使用vite和vue3手动进行前端项目架构。为方便大家从vue2过渡到vue3,本项目我们先不使用ts。
|
||||
>
|
||||
> ts项目我们后面再讲,并且我们将会使用更加集成化的框架,就不需要手动搭建项目了。
|
||||
|
||||
使用vite的命令创建项目:
|
||||
|
||||
@ -159,12 +158,12 @@ npm run dev
|
||||
|
||||
```js
|
||||
// index.js
|
||||
import { createRouter, createWebHistory } from "vue-router"
|
||||
import { createRouter, createWebHashHistory } from "vue-router"
|
||||
import home from './modules/home'
|
||||
import login from './modules/login'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
history: createWebHashHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
@ -242,10 +241,10 @@ npm run dev
|
||||
|
||||
> 状态管理也使用模块化的方式
|
||||
|
||||
在store目录中创建modules目录,modules中创建一个模块,比如叫user.js
|
||||
在store目录中创建modules目录,modules中创建一个模块app.js
|
||||
|
||||
```js
|
||||
// user.js
|
||||
// app.js
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {},
|
||||
@ -259,11 +258,11 @@ npm run dev
|
||||
```js
|
||||
//index.js
|
||||
import { createStore } from "vuex";
|
||||
import user from "./modules/user";
|
||||
import app from "./modules/app";
|
||||
|
||||
export default createStore({
|
||||
modules: {
|
||||
user,
|
||||
app,
|
||||
},
|
||||
});
|
||||
|
||||
@ -525,12 +524,12 @@ server: {
|
||||
password: '123456'
|
||||
})
|
||||
if (+code === 200) {
|
||||
store.commit("user/setToken", data);
|
||||
store.commit("app/setToken", data);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
store/modules/user.js
|
||||
store/modules/app.js
|
||||
|
||||
```js
|
||||
import { getItem, setItem, removeItem } from "@/utils/storage"; //getItem和setItem是封装的操作localStorage的方法
|
||||
@ -604,7 +603,7 @@ server: {
|
||||
// 拦截请求
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
const authorization = store.state.user;
|
||||
const authorization = store.state.app;
|
||||
if (authorization) {
|
||||
config.headers.Authorization = `Bearer ${authorization.token}`;
|
||||
}
|
||||
@ -628,7 +627,7 @@ server: {
|
||||
// 响应拦截器中的 error 就是那个响应的错误对象
|
||||
if (error.response && error.response.status === 401) {
|
||||
// 校验是否有 refresh_token
|
||||
const { authorization } = store.state;
|
||||
const { authorization } = store.state.app;
|
||||
if (!authorization || !authorization.refresh_token) {
|
||||
router.push("/login");
|
||||
|
||||
@ -646,7 +645,7 @@ server: {
|
||||
});
|
||||
// 如果获取成功,则把新的 token 更新到容器中
|
||||
// console.log('刷新 token 成功', res)
|
||||
store.commit("setToken", {
|
||||
store.commit("app/setToken", {
|
||||
token: res.data.data.token, // 最新获取的可用 token
|
||||
refresh_token: authorization.refresh_token, // 还是原来的 refresh_token
|
||||
});
|
||||
@ -659,7 +658,7 @@ server: {
|
||||
// console.log('请求刷线 token 失败', err)
|
||||
router.push("/login");
|
||||
// 清除token
|
||||
store.commit("clearToken")
|
||||
store.commit("app/clearToken")
|
||||
}
|
||||
}
|
||||
|
||||
@ -700,7 +699,7 @@ server: {
|
||||
|
||||
```js
|
||||
// 引入TOKEN变量
|
||||
import { TOKEN } from '@/store/modules/user'
|
||||
import { TOKEN } from '@/store/modules/app'
|
||||
|
||||
// 全局路由守卫,注意vue-router4的路由守卫不需要next跳转,而是通过return返回false或者一个路由地址
|
||||
router.beforeEach((to, from) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user