目录
背景描述
在上一篇的基础上开始开发,element-plus+vue3
上一篇说道详细迁移的过程,如下:
所以我这篇开始了第一步,中途涉及其他东西,会引入其他篇。
我找的模板是使用的这个:GitHub - jzfai/vue3-admin-ts: 🎉 the ts version of vue3-admin-template
开发流程梳理
首先登录功能,需要两个页面,一个登录页,一个登录后跳转到页面,这里叫它首页吧。
- 先在views底下新建两个页面:首页,登录页
- 添加两个页面的路由表,这一步把路由表基础部分做了
- 画登录页和首页的界面
- 登录,需要向服务发送请求=> 做一下请求拦截和封装
- 发送请求
- 响应后存储用户信息,跳转页面
- 开发首页的样式
详细开发流程
一、新建页面
二、添加页面路由
这里只显示简单的几个页面的路由表,暂时不添加有权限的部分的路由,所以是比较简单的。
import { createRouter, createWebHashHistory } from 'vue-router'
import basicDemo from './modules/basic-demo.js' //比如有权限控制的路由表
import Layout from '@/layout/index.vue'
export const constantRoutes = [
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect')
}
]
},
{
path: '/login',
component: () => import('@/views/login/index.vue'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/error-page/404.vue'),
hidden: true
},
{
path: '/401',
component: () => import('@/views/error-page/401.vue'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue'),
//using el svg icon, the elSvgIcon first when at the same time using elSvgIcon and icon
meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
}
]
},
//。。。
basicDemo,
{ path: '/:pathMatch(.*)', redirect: '/404', hidden: true }
]
//角色和code数组动态路由
export const roleCodeRoutes = []
/**
* asyncRoutes
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes = [
// 404 page must be placed at the end !!!
]
const router = createRouter({
history: createWebHashHistory(),
scrollBehavior: () => ({ top: 0 }),
routes: constantRoutes
})
export default router
三、开发界面
因为用的模板,所以有大概的登录和首页界面。
但是还是需要改改代码,更改样式,首先是登录页,需要获取系统的图标,以及更改背景颜色和输入框的样式等,这里已经对主题颜色进行了更改,可以看这篇:vue3 实现主题色以及修改主题色
登录页面
更改后的登录页面大概如下:
背景颜色用的渐变色填充的,太单调所以加了一个动画,虽然丑,但是先暂时放着,等之后找好看的来换。
这个页面的代码如下:
<template>
<div class="login-container columnCC">
<el-card class="login_panel_form">
<el-form ref="refLoginForm" class="login-form" :model="subForm" :rules="formRules">
<div class="title-container">
<h3 class="title text-center">{{ settings.title }}</h3>
</div>
<el-form-item prop="keyword" :rules="formRules.isNotNull('usename不能为空')">
<el-input v-model.trim="subForm.keyword" placeholder="请输入用户名" size="large">
<template #prepend>
<el-icon><User /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password" :rules="formRules.isNotNull('密码不能为空')">
<el-input v-model.trim="subForm.password" placeholder="请输入密码" show-password size="large">
<template #prepend>
<el-icon><Lock /></el-icon>
</template>
</el-input>
</el-form-item>
<div class="tip-message">{{ tipMessage }}</div>
<el-button :loading="subLoading" type="primary" class="login-btn" size="default" @click.prevent="handleLogin">
登录
</el-button>
</el-form>
</el-card>
</div>
</template>
<style lang="scss" scoped>
$dark_gray: #889aa4;
$light_gray: #eee;
@keyframes gradientAnimation {
0% {
background-position: 0% 0%;
}
50% {
background-position: 100% 100%;
}
100% {
background-position: 0% 0%;
}
}
.login-container {
height: 100vh;
width: 100%;
background: linear-gradient(to top, #6416a6, #62298d, #ae8ac9);
background-size: 200% 200%;
animation: gradientAnimation 5s ease infinite;
.login_panel_form {
padding: 30px;
margin-bottom: 20vh;
}
.login-form {
width: 360px;
}
.title-container {
.title {
font-size: 22px;
color: #333;
margin: 0 auto 25px auto;
text-align: center;
font-weight: bold;
}
}
}
.svg-container {
padding-left: 6px;
color: $dark_gray;
text-align: center;
width: 30px;
}
//错误提示信息
.tip-message {
color: #e4393c;
height: 30px;
margin-top: -12px;
font-size: 12px;
}
//登录按钮
.login-btn {
width: 100%;
margin-bottom: 30px;
}
.show-pwd {
width: 50px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
text-align: center;
}
</style>
登录页的样式写完了,那么先加一个路由跳转,到首页。
首页
首页一般就是一些欢迎进入系统,和一些快捷链接,我这里也是打算写一个这样的页面,目前这部分还是模板里的样子,然后之后补充这一款的代码。
四、登录请求
这一步,需要先配置Axios 实例,以及一些全局的请求和响应处理逻辑,还涉及到一些关于 token 处理和错误处理的逻辑,可以看这篇文章:vue3 全局配置Axios实例
这里可以查看登录的逻辑,发送了请求,并且获取到了token,并保存,至于保存在哪里,这里是用了store来管理,还差一个将用户信息存储。
<script setup lang="ts">
import { onMounted, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useBasicStore } from '@/store/basic'
import { elMessage, useElement } from '@/hooks/use-element'
import { loginReq } from '@/api/user'
/* listen router change and set the query */
const { settings } = useBasicStore()
//element valid
const formRules = useElement().formRules
//form
const subForm = reactive({
keyword: '',
password: ''
})
const state: any = reactive({
otherQuery: {},
redirect: ''
})
const route = useRoute()
const getOtherQuery = (query) => {
return Object.keys(query).reduce((acc, cur) => {
if (cur !== 'redirect') {
acc[cur] = query[cur]
}
return acc
}, {})
}
watch(
() => route.query,
(query) => {
if (query) {
state.redirect = query.redirect
state.otherQuery = getOtherQuery(query)
}
},
{ immediate: true }
)
/*
* login relative
* */
const subLoading = ref(false)
//tip message
const tipMessage = ref()
//sub form
const refLoginForm = ref()
const handleLogin = () => {
refLoginForm.value.validate((valid) => {
subLoading.value = true
if (valid) loginFunc()
})
}
const router = useRouter()
const basicStore = useBasicStore()
const loginFunc = () => {
loginReq({
username: subForm.keyword,
password: subForm.password
})
.then(({ data }) => {
elMessage('登录成功')
basicStore.setToken(data?.token)
router.push('/')
})
.catch((err) => {
tipMessage.value = err?.msg
})
.finally(() => {
subLoading.value = false
})
}
</script>
五、存储用户信息
这里会介绍怎么存储用户信息,会另外开一票篇来写
六、页面跳转
这个比较简单,但是涉及权限,因为后面要加权限的话,就需要配置路由守卫,所以先空置,之后加上。
七、修改首页样式
等过两天首页写完了就加上。
总结
暂时先写到这里,下面的慢慢记上!
overl