一、修改一些配置
- .eslintrc.js
//.eslintrc
module.exports = {
...
rules: {
'no-console': 'off',
'import/no-unresolved': [
2,
{
ignore: ['^@/'], // @ 是设置的路径别名
},
],
},
...
};
- tsconfig.json
//tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"noImplicitAny": false,
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
二、新建layout
- 在项目根目录新建layout目录
- 在layout目录新建index.vue
// @/layout/index.vue
<template>
<a-layout class="layout">
<a-layout-sider v-model:collapsed="collapsed" :trigger="null" collapsible>
<div class="logo" />
<a-menu theme="dark" mode="inline" v-model:selectedKeys="selectedKeys">
<a-menu-item key="/">
<dashboard-outlined />
<span>首页</span>
</a-menu-item>
</a-menu>
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0 20px">
<menu-unfold-outlined v-if="collapsed" class="trigger" @click="() => (collapsed = !collapsed)" />
<menu-fold-outlined v-else class="trigger" @click="() => (collapsed = !collapsed)" />
</a-layout-header>
<a-layout-content :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }">
<router-view />
</a-layout-content>
</a-layout>
</a-layout>
</template>
<script lang="ts">
import { DashboardOutlined, MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref } from 'vue';
export default defineComponent({
components: {
DashboardOutlined,
MenuUnfoldOutlined,
MenuFoldOutlined,
},
setup() {
return {
selectedKeys: ref<string[]>(['/']),
collapsed: ref<boolean>(false),
};
},
});
</script>
<style lang="less" scoped>
.layout {
box-sizing: border-box;
width: 100%;
height: 100%;
}
.logo {
margin: 20px auto;
width: 80%;
height: 40px;
background: #334454;
}
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color 0.3s;
}
#components-layout-demo-custom-trigger .trigger:hover {
color: #1890ff;
}
#components-layout-demo-custom-trigger .logo {
height: 32px;
background: rgba(255, 255, 255, 0.3);
margin: 16px;
}
.site-layout .site-layout-background {
background: #fff;
}
</style>
三、修改路由
- 在meta中加入layout参数
- 用这个参数区分当前页面是不是在layout布局中显示
// @/router/index.ts
.....
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/Home/index.vue'),
meta: {
title: '首页',
layout: true,
},
},
{
path: '/login',
name: 'Login',
component: () => import('../views/Login/index.vue'),
meta: {
title: '登录',
layout: false,
},
},
];
.......
四、修改App.vue
<template>
<layout v-if="$route.meta.layout" />
<router-view v-else />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import layout from '@/layout/index.vue';
export default defineComponent({
name: 'App',
components: {
layout,
},
});
</script>
<style lang="less">
#app {
width: 100%;
height: 100%;
}
</style>
- 修改好App.vue后运行项目
- 访问'/'时会看到layout布局中的首页
- 访问'/login'时会看到全屏显示的登录页
- 表示laout布局成功
五、axios请求封装
- src下新建request目录
- @/request下新建api目录
- @/request下新建base.ts
- @/request下新建http.ts
- @/request/api下新建loginAPI.ts
// @/request/base.ts
const base = {
baseurl: '/mock',
};
export default base;
// @/request/http.ts
import base from '@/request/base';
import axios, { AxiosRequestConfig } from 'axios';
// 设置超时时间
const instance = axios.create({
timeout: 1000 * 10,
});
// 设置公共路径 和 Content-Type
instance.defaults.baseURL = base.baseurl;
interface AxiosConfig extends AxiosRequestConfig {
loading: boolean;
}
const Fetch = ({
url = '',
method = 'GET',
data = {},
params = {},
headers = {
'Content-Type': 'application/json',
},
loading = true,
}: AxiosConfig) => {
if (loading) {
// loading
}
return new Promise((resolve, reject) => {
instance({
url,
method,
data,
params,
headers,
})
.then((res) => {
resolve(res.data.data);
})
.catch((err) => {
reject(err);
});
});
};
export default Fetch;
// @/request/api/loginAPI.ts
import Fetch from '@/request/http';
const LoginAPI = {
/**
* 账号密码登录
* @param {Object} data
*/
setLogin(data) {
return Fetch({
method: 'POST',
url: `/api/login`,
data,
});
},
};
export default LoginAPI;
六、修改登录页
//@/view/login/index.vue
......
<script lang="ts">
......
import LoginAPI from '@/request/api/loginAPI';
......
const onSubmit = () => {
loginFormRef.value.validate().then(() => {
LoginAPI.setLogin(toRaw(loginForm)).then((r) => {
console.log(res);
router.push({ path: '/' });
});
// axios({
// url: '/mock/api/login',
// method: 'POST',
// data: toRaw(loginForm),
// }).then((res) => {
// router.push({ path: '/' });
// });
});
};
......
</script>
- 测试一下登录功能
- 请求封装成功
七、源代码地址
https://github.com/jiangzetian/vue3-admin-template
八、视频演示及源码
本文演示视频:点击浏览
更多前端内容欢迎关注公众号:天小天个人网