1.创建项目文件
news:为后端IDE文件
news_client:为前端VSCode文件
在 ..\news\news_client 中启用cmd/PowerShell
查看当前 npm 配置的注册表(registry)地址是否在https://registry.npmmirror.com
如果不在,可在cd new_client后设置npm镜像源
此步骤流程:
cd new_client1126
npm config get registry 【查看镜像源地址】
npm config set registry https://registry.npmmirror.com 【更改镜像源地址】
npm install
npm run dev
2.整理创建的项目文件
2.1 安装JavaScript包
npm install element-plus --save
npm install axios
npm install -D 【D:代表开发者模式】
2.2 整理文件
删除文件:
src\views\AboutView.vue
src\views\HomeView.vue
src\components\HelloWorld.vue
src\components\TheWelcome.vue
src\components\WelcomeItem.vuesrc\components\icons及其中所有文件
新建文件夹:
src\apis\...
src\utils\...
2.3 文件整理代码
文件地址:src\App.vue
<script setup></script>
<template></template>
<style scoped></style>
文件地址:src\router\index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
// {
// path: '/',
// name: 'home',
// component: HomeView,
// },
],
})
export default router
2.4 导入elementUI
文件地址:src\main.js
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'👈
import 'element-plus/dist/index.css'👈
const app = createApp(App)
app.use(router)
app.use(ElementPlus)👈
app.mount('#app')
3.配置 Axios 实例与响应拦截器
文件地址:src\utils\request.js
//axios用于向服务端发起请求的工具
import axios from 'axios'
//定义变量记录访问的目标地址
const baseURL = 'http://localhost:8080'
//获得axios对象
const instance = axios.create({baseURL})
//添加拦截器
instance.interceptors.response.use(
//如果响应结果没有错误,则放行。
result=>{
return result.data;
},
err=>{//如果响应结果出现错误(异常),则拦截
alert('服务异常')
return Promise.reject(err)
//Promise是用于JavaScript源生的异步请求工具,axios底层由Promise构建而成
}
)
export default instance;
4.注册与登录
文件地址:src\views\Login.vue
4.1 script行为模块:
trigger:'blur':光标移开后触发校验规则
registerData:是双向绑定数据,在javaScript中调用该数据,需要通过.value属性
<script setup>
import { ref, onMounted } from 'vue';
import { User, Lock } from '@element-plus/icons-vue';
//控制显示注册页面或登录页面的变量
const isRegister = ref(false)
//定义数据模型
const registerData = ref({
username: '',
password: '',
rePassword: ''
})
//定义函数,注册、登录切换时,用于清空数据模型的数据
const clearRegisterData = () => {
registerData.value = {
username: '',
password: '',
rePassword: ''
}
}
//定义表单校验规则
//自定义校验/重置密码函数
const checkRePassword = (rule,value,callback)=>{
if(value===''){
callback(new Error('请再次输入确认密码'))
}else if(value !== registerData.value.password){
callback(new Error('请确保两次密码一致'))
}else{
callback()
}
}
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为5-16位的非空字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为5-16位的非空字符', trigger: 'blur' }
],
rePassword: [
{validator:checkRePassword,trigger:'blur'}
]
}
</script>
4.2 template结构模块
4.2.1 注册表单
<template>
<el-row class="login-page">
<el-col :span="8"></el-col>
<el-col :span="8" class="form">
<!-- 注册表单 -->
<el-form size="large" autocomplete="off" v-if="isRegister" :rules="rules" :model="registerData">
<el-form-item>
<h1 class="title">
注册
</h1>
</el-form-item>
<el-form-item prop="username">
<el-input placeholder="请输入用户名" :prefix-icon="User" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="请输入密码" type="password" :prefix-icon="Lock"
v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item prop="rePassword">
<el-input placeholder="请确认密码" type="password" :prefix-icon="Lock"
v-model="registerData.rePassword"></el-input>
</el-form-item>
<el-form-item>
<el-button class="button" type="primary" @click="register">
注册
</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" @click="isRegister = false; clearRegisterData()">
<span>返回</span>
</el-link>
</el-form-item>
</el-form>
<!-- 登录表单 -->
<!-- ... -->
</el-col>
<el-col :span="8"></el-col>
</el-row>
</template>
4.2.2 登录表单
<template>
<el-row class="login-page">
<el-col :span="8"></el-col>
<el-col :span="8" class="form">
<!-- 注册表单 -->
<!-- ... -->
<!-- 登录表单 -->
<el-form size="large" autocomplete="off" v-else :rules="rules" :model="registerData">
<el-form-item>
<h1 class="title">
登录
</h1>
</el-form-item>
<el-form-item prop="username">
<el-input placeholder="请输入用户名" :prefix-icon="User" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="请输入密码" type="password" :prefix-icon="Lock"
v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item class="button">
<el-button type="primary" class="button">登录</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" @click="isRegister = true; clearRegisterData()">
<span>注册</span>
</el-link>
</el-form-item>
</el-form>
</el-col>
<el-col :span="8"></el-col>
</el-row>
</template>
4.3 style样式模块
<style lang="scss" scoped>
.login-page{
height: 100vh;
background-color: #fff;
.form{
display: flex;//自适应
flex-direction: column;//列为准线
justify-content: center;//居中
.title{
margin: 0 auto;//边距
}
.button{
width: 100%;
}
.flex{
width: 100%;
display: flex;
justify-content:space-between;
}
}
}
</style>
4.4 挂载路由
文件地址:src\App.vue
<script setup></script>
<template>
<RouterView></RouterView>
</template>
<style scoped></style>
文件地址: src\router\index.js
import { createRouter, createWebHistory } from 'vue-router'
import Login from '@/views/Login.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'login',
component: Login,
},
],
})
export default router
5.提供注册接口
文件地址:src\apis\user.js
通过 request.post
方法封装了 HTTP POST 请求,
使得在组件或其他服务中调用注册接口变得更加简单和统一。
//导入request.js请求工具
import request from '@/utils/request';
//暴露注册接口
export const userRegisterService = (registerData)=>{
const params = new URLSearchParams()
for(let key in registerData){
params.append(key,registerData[key])
}
return request.post('/user/register',params)
}
6.配置接口地址
文件地址:vite.config.js
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({
plugins: [ ... ],
resolve: { ... },
server:{
proxy:{
'/api':{
target:'http://localhost:8080',
changeOrigin:true,
rewrite:(path)=>path.replace(/^\/api/,'')
}
}
}
})
文件地址:src\utils\request.js
7.增加弹窗效果
文件地址:src\views\Login.vue
<script setup>
import { ElMessage } from 'element-plus'
//调用请求函数实现业务处理(注册)
import { userRegisterService } from '@/apis/user'
const register = async()=>{
let result = await userRegisterService(registerData.value);
console.log(result)
ElMessage.success(result.msg?result.msg:'注册成功')
}
</script>
8.效果视图
9.附录:
src\views\Login.vue完整代码
<script setup>
import { ref, onMounted } from 'vue';
import { User, Lock } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus'
//控制显示注册页面或登录页面的变量
const isRegister = ref(false)
//定义数据模型
const registerData = ref({
username: '',
password: '',
rePassword: ''
})
//定义函数,注册、登录切换时,用于清空数据模型的数据
const clearRegisterData = () => {
registerData.value = {
username: '',
password: '',
rePassword: ''
}
}
//定义表单校验规则
//自定义校验/重置密码函数
const checkRePassword = (rule,value,callback)=>{
if(value===''){
callback(new Error('请再次输入确认密码'))
}else if(value !== registerData.value.password){
callback(new Error('请确保两次密码一致'))
}else{
callback()
}
}
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为5-16位的非空字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为5-16位的非空字符', trigger: 'blur' }
],
rePassword: [
{validator:checkRePassword,trigger:'blur'}
]
}
//调用请求函数实现业务处理(注册)
import { userRegisterService } from '@/apis/user'
const register = async()=>{
let result = await userRegisterService(registerData.value);
console.log(result)
ElMessage.success(result.msg?result.msg:'注册成功')
}
</script>
<template>
<el-row class="login-page">
<el-col :span="8"></el-col>
<el-col :span="8" class="form">
<!-- 注册表单 -->
<el-form size="large" autocomplete="off" v-if="isRegister" :rules="rules" :model="registerData">
<el-form-item>
<h1 class="title">
注册
</h1>
</el-form-item>
<el-form-item prop="username">
<el-input placeholder="请输入用户名" :prefix-icon="User" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="请输入密码" type="password" :prefix-icon="Lock"
v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item prop="rePassword">
<el-input placeholder="请确认密码" type="password" :prefix-icon="Lock"
v-model="registerData.rePassword"></el-input>
</el-form-item>
<el-form-item>
<el-button class="button" type="primary" @click="register">
注册
</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" @click="isRegister = false; clearRegisterData()">
<span>返回</span>
</el-link>
</el-form-item>
</el-form>
<!-- 登录表单 -->
<el-form size="large" autocomplete="off" v-else :rules="rules" :model="registerData">
<el-form-item>
<h1 class="title">
登录
</h1>
</el-form-item>
<el-form-item prop="username">
<el-input placeholder="请输入用户名" :prefix-icon="User" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="请输入密码" type="password" :prefix-icon="Lock"
v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item class="button">
<el-button type="primary" class="button">登录</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" @click="isRegister = true; clearRegisterData()">
<span>注册</span>
</el-link>
</el-form-item>
</el-form>
</el-col>
<el-col :span="8"></el-col>
</el-row>
</template>
<style lang="scss" scoped>
.login-page{
height: 100vh;
background-color: #fff;
.form{
display: flex;//自适应
flex-direction: column;//列为准线
justify-content: center;//居中
.title{
margin: 0 auto;//边距
}
.button{
width: 100%;
}
.flex{
width: 100%;
display: flex;
justify-content:space-between;
}
}
}
</style>