完成注册请求
@@ -28,5 +28,8 @@ module.exports = {
|
||||
ignores: ['index'] // vue组件名称多单词组成(忽略index.vue)
|
||||
}
|
||||
]
|
||||
},
|
||||
globals: {
|
||||
ElMessage: 'readonly'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"lint-staged": "lint-staged"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"axios": "^1.7.4",
|
||||
"element-plus": "^2.8.0",
|
||||
"pinia": "^2.1.7",
|
||||
@@ -29,6 +30,7 @@
|
||||
"lint-staged": "^15.2.9",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.77.8",
|
||||
"unplugin-auto-import": "^0.18.2",
|
||||
"unplugin-vue-components": "^0.27.4",
|
||||
"vite": "^5.3.1"
|
||||
|
||||
33
pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@element-plus/icons-vue':
|
||||
specifier: ^2.3.1
|
||||
version: 2.3.1(vue@3.4.38)
|
||||
axios:
|
||||
specifier: ^1.7.4
|
||||
version: 1.7.4
|
||||
@@ -29,7 +32,7 @@ importers:
|
||||
version: 1.10.4
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.0.5
|
||||
version: 5.1.2(vite@5.4.1)(vue@3.4.38)
|
||||
version: 5.1.2(vite@5.4.1(sass@1.77.8))(vue@3.4.38)
|
||||
'@vue/eslint-config-prettier':
|
||||
specifier: ^9.0.0
|
||||
version: 9.0.0(eslint@8.57.0)(prettier@3.3.3)
|
||||
@@ -51,6 +54,9 @@ importers:
|
||||
prettier:
|
||||
specifier: ^3.2.5
|
||||
version: 3.3.3
|
||||
sass:
|
||||
specifier: ^1.77.8
|
||||
version: 1.77.8
|
||||
unplugin-auto-import:
|
||||
specifier: ^0.18.2
|
||||
version: 0.18.2(@vueuse/core@9.13.0(vue@3.4.38))(rollup@4.21.0)
|
||||
@@ -59,7 +65,7 @@ importers:
|
||||
version: 0.27.4(@babel/parser@7.25.3)(rollup@4.21.0)(vue@3.4.38)
|
||||
vite:
|
||||
specifier: ^5.3.1
|
||||
version: 5.4.1
|
||||
version: 5.4.1(sass@1.77.8)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -811,6 +817,9 @@ packages:
|
||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
immutable@4.3.7:
|
||||
resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
|
||||
|
||||
import-fresh@3.3.0:
|
||||
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -1132,6 +1141,11 @@ packages:
|
||||
run-parallel@1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
|
||||
sass@1.77.8:
|
||||
resolution: {integrity: sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
scule@1.3.0:
|
||||
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
|
||||
|
||||
@@ -1586,9 +1600,9 @@ snapshots:
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
|
||||
'@vitejs/plugin-vue@5.1.2(vite@5.4.1)(vue@3.4.38)':
|
||||
'@vitejs/plugin-vue@5.1.2(vite@5.4.1(sass@1.77.8))(vue@3.4.38)':
|
||||
dependencies:
|
||||
vite: 5.4.1
|
||||
vite: 5.4.1(sass@1.77.8)
|
||||
vue: 3.4.38
|
||||
|
||||
'@vue/compiler-core@3.4.38':
|
||||
@@ -2075,6 +2089,8 @@ snapshots:
|
||||
|
||||
ignore@5.3.2: {}
|
||||
|
||||
immutable@4.3.7: {}
|
||||
|
||||
import-fresh@3.3.0:
|
||||
dependencies:
|
||||
parent-module: 1.0.1
|
||||
@@ -2382,6 +2398,12 @@ snapshots:
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
|
||||
sass@1.77.8:
|
||||
dependencies:
|
||||
chokidar: 3.6.0
|
||||
immutable: 4.3.7
|
||||
source-map-js: 1.2.0
|
||||
|
||||
scule@1.3.0: {}
|
||||
|
||||
semver@7.6.3: {}
|
||||
@@ -2522,13 +2544,14 @@ snapshots:
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
vite@5.4.1:
|
||||
vite@5.4.1(sass@1.77.8):
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.4.41
|
||||
rollup: 4.21.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
sass: 1.77.8
|
||||
|
||||
vue-demi@0.14.10(vue@3.4.38):
|
||||
dependencies:
|
||||
|
||||
15
src/App.vue
@@ -1,20 +1,7 @@
|
||||
<script setup>
|
||||
import { userStore } from '@/stores'
|
||||
|
||||
const user = userStore()
|
||||
</script>
|
||||
<script setup></script>
|
||||
|
||||
<template>
|
||||
<div>我是APP</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<router-view></router-view>
|
||||
|
||||
<hr />
|
||||
<p>{{ user.token }}</p>
|
||||
<el-button type="primary" @click="user.setToken('111')">登录</el-button>
|
||||
<el-button type="danger" @click="user.setToken('')">退出</el-button>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
13
src/api/user.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import request from '@/utils/request'
|
||||
import { CLIENT_TYPE, CLIENT_NAME, CLIENT_VERSION } from '@/const/userConst'
|
||||
|
||||
export const userRegisterService = ({ username, password }) => {
|
||||
request.post('/user/register', {
|
||||
account: username,
|
||||
nickName: '',
|
||||
password: password,
|
||||
clientType: CLIENT_TYPE,
|
||||
clientName: CLIENT_NAME,
|
||||
clientVersion: CLIENT_VERSION
|
||||
})
|
||||
}
|
||||
BIN
src/assets/avatar.jpg
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
src/assets/cover.jpg
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
src/assets/default.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/assets/login_bg.jpg
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
src/assets/login_title.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src/assets/logo.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
src/assets/logo2.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
20
src/assets/main.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* fade-slide */
|
||||
.fade-slide-leave-active,
|
||||
.fade-slide-enter-active {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.fade-slide-enter-from {
|
||||
transform: translateX(-30px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fade-slide-leave-to {
|
||||
transform: translateX(30px);
|
||||
opacity: 0;
|
||||
}
|
||||
3
src/const/userConst.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export const CLIENT_TYPE = 2
|
||||
export const CLIENT_NAME = 'web'
|
||||
export const CLIENT_VERSION = '0.0.1'
|
||||
@@ -3,6 +3,7 @@ import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import pinia from './stores/index'
|
||||
import '@/assets/main.scss'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
|
||||
@@ -7,10 +7,6 @@ const router = createRouter({
|
||||
path: '/login',
|
||||
component: () => import('@/views/LoginPage.vue')
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
component: () => import('@/views/RegisterPage.vue')
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('@/views/layout/LayoutContainer.vue'),
|
||||
|
||||
@@ -3,7 +3,7 @@ import { userStore } from '@/stores'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import router from '@/router'
|
||||
|
||||
const baseURL = 'http://127.0.0.1:8080'
|
||||
const baseURL = '/api' //配合vite.config.js中的代理配置解决跨域问题
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL,
|
||||
|
||||
@@ -1 +1,176 @@
|
||||
<template>登录</template>
|
||||
<script setup>
|
||||
import { User, Lock } from '@element-plus/icons-vue'
|
||||
import { ref } from 'vue'
|
||||
import { userRegisterService } from '@/api/user.js'
|
||||
const isRegister = ref(true)
|
||||
// 提交的整个form表单的数据
|
||||
const formModel = ref({
|
||||
username: '',
|
||||
password: '',
|
||||
repassword: ''
|
||||
})
|
||||
// 表单对象
|
||||
const form = ref()
|
||||
|
||||
// 表单的校验规则
|
||||
const rules = {
|
||||
username: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
{ min: 5, max: 10, message: '用户名必须是5-10位的字符', trigger: 'blur' }
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '请输入密码', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^\S{6,15}$/,
|
||||
message: '密码必须是6-15位的非空字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
repassword: [
|
||||
{ required: true, message: '请再次输入密码', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^\S{6,15}$/,
|
||||
message: '密码必须是6-15的非空字符',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value !== formModel.value.password) {
|
||||
callback(new Error('两次输入密码不一致!'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const register = async () => {
|
||||
await form.value.validate() // 注册之前预校验
|
||||
console.log('开始注册请求')
|
||||
await userRegisterService(formModel.value)
|
||||
ElMessage.success('注册成功')
|
||||
isRegister.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-row class="login-page">
|
||||
<el-col :span="12" class="bg"></el-col>
|
||||
<el-col :span="6" :offset="3" class="form">
|
||||
<el-form
|
||||
:model="formModel"
|
||||
:rules="rules"
|
||||
ref="form"
|
||||
size="large"
|
||||
autocomplete="off"
|
||||
v-if="isRegister"
|
||||
>
|
||||
<el-form-item>
|
||||
<h1>注册</h1>
|
||||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="formModel.username"
|
||||
:prefix-icon="User"
|
||||
placeholder="请输入用户名"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="formModel.password"
|
||||
:prefix-icon="Lock"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="repassword">
|
||||
<el-input
|
||||
v-model="formModel.repassword"
|
||||
:prefix-icon="Lock"
|
||||
type="password"
|
||||
placeholder="请输入再次密码"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
@click="register"
|
||||
class="button"
|
||||
type="primary"
|
||||
auto-insert-space
|
||||
>
|
||||
注册
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item class="flex">
|
||||
<el-link type="info" :underline="false" @click="isRegister = false">
|
||||
← 返回
|
||||
</el-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form ref="form" size="large" autocomplete="off" v-else>
|
||||
<el-form-item>
|
||||
<h1>登录</h1>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input
|
||||
name="password"
|
||||
:prefix-icon="Lock"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="flex">
|
||||
<div class="flex">
|
||||
<el-checkbox>记住我</el-checkbox>
|
||||
<el-link type="primary" :underline="false">忘记密码?</el-link>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="button" type="primary" auto-insert-space
|
||||
>登录</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item class="flex">
|
||||
<el-link type="info" :underline="false" @click="isRegister = true">
|
||||
注册 →
|
||||
</el-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-page {
|
||||
height: 100vh;
|
||||
background-color: #fff;
|
||||
.bg {
|
||||
background:
|
||||
url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
|
||||
url('@/assets/login_bg.jpg') no-repeat center / cover;
|
||||
border-radius: 0 20px 20px 0;
|
||||
}
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
.title {
|
||||
margin: 0 auto;
|
||||
}
|
||||
.button {
|
||||
width: 100%;
|
||||
}
|
||||
.flex {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<template>注册</template>
|
||||
@@ -21,5 +21,16 @@ export default defineConfig({
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
// 配置代理
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
// 获取请求中带 /api 的请求
|
||||
target: 'http://localhost', // 后台服务器的源
|
||||
changeOrigin: true, // 修改源
|
||||
rewrite: (path) => path.replace(/^\/api/, '') // /api 替换为空字符串
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||