一、环境
vue3.0
element-plus
axios
vue-router
spring-boot
mybatis-plus
二、开发工具
前端 VSCode
后端 IDEA
三、前端框架
项目结构如下:

然后我们看一下核心的代码
入口文件main.js
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')axios封装 request.js
import axios from 'axios'
const request = axios.create({
// baseURL: '/api', // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
timeout: 5000
})
// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
config.headers['Content-Type'] = 'application/json;charset=utf-8';
// config.headers['token'] = user.token; // 设置请求头
return config
}, error => {
return Promise.reject(error)
});
// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
response => {
let res = response.data;
// 如果是返回的文件
if (response.config.responseType === 'blob') {
return res
}
// 兼容服务端返回的字符串数据
if (typeof res === 'string') {
res = res ? JSON.parse(res) : res
}
return res;
},
error => {
console.log('err' + error) // for debug
return Promise.reject(error)
}
)
export default request路由router/inde.js
import {createRouter,createWebHistory} from "vue-router"
import LoginView from '@/components/LoginView'
import IndexView from '@/components/IndexView'
const routes=[
{
path:'/',
name:"LoginView",
component:LoginView
},
{
path:'/index',
name:"IndexView",
component:IndexView
}
]
export const router=createRouter({
history:createWebHistory(),
routes:routes
})
export default router登陆注册组件LoginView.vue
<template>
<el-tabs v-model="activeName" type="border-card" class="demo-tabs" @tab-click="handleClick">
<el-tab-pane label="登录" name="login">
<el-form :model="form" ref="ruleForms" :rules="rules" label-width="70px">
<el-form-item label="用户名" prop="username">
<el-input placeholder="请输入5-15位大小写字母数字或者下划线" style = "width: 80%" v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input placeholder="请输入5-20位密码" style = "width: 80%" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onLogin">提交</el-button>
<el-button @click="cannel">取消</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="注册" name="register">
<el-form :model="form" label-width="80px">
<el-form-item label="用户名">
<el-input style = "width: 80%" v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input style = "width: 80%" v-model="form.password"></el-input>
</el-form-item>
<el-form-item label="确认密码">
<el-input style = "width: 80%" v-model="form.password2"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onRegister">提交</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</template>
<script>
import {reactive,toRefs,ref} from "vue";
import request from "@/utils/request";
import { ElMessage } from 'element-plus';
import {useRouter} from 'vue-router';
export default{
setup() {
const router=useRouter()
const activeName = ref('login')
//使用ref定义dom对象
const ruleForms = ref();
const state=reactive({
form:{}
});
const rules= reactive({
username:[
{
required:true,
message:"请输入您的用户名",
trigger:"blur"
},
{
pattern:"^\\w{5,15}$",
message:"请输入5-15位大小写字母数字或者下划线",
trigger:"blur"
}
],
password:[
{
required:true,
message:"请输入您的密码",
trigger:"blur"
},
{
pattern:"^.{5,20}$",
message:"请输入5-20位的密码",
trigger:"blur"
}
]
})
function onLogin(){
console.log(ruleForms.value);
//通过ref的值触发验证
ruleForms.value.validate((valid) => {
if (valid) {
console.log("通过");
request.post("/api/user/login",state.form).then((res)=>{
console.log(res);
if(res.code==='0'){
ElMessage.success("登录成功");
router.push({path: '/index'});
}
else {
ElMessage.error(res.msg);
}
})
} else {
console.log("未通过");
}
});
}
function onRegister(){
console.log(state.form);
request.post("/api/user/register",state.form).then((res)=>{
console.log(res);
if(res.code==='0'){
ElMessage.success("注册成功");
router.push({path: '/'});
}
else {
ElMessage.error(res.msg);
}
})
}
function handleClick(){
state.form={};
}
function cannel(){
state.form={};
}
return{
...toRefs(state),
onLogin,
cannel,
onRegister,
handleClick,
activeName,
rules,
ruleForms
}
}
}
</script>四、后端框架
项目结构如下:

核心代码:
Result类
package com.example.springboot.config;
import lombok.Data;
@Data
public class Result<T> {
private String code; //状态码
private String msg; //返回信息
private T data; //返 回数据
public Result(T data){
this.data=data;
}
public Result() {
}
// 返回成功的信息
public static Result success(){
Result result=new Result<>();
result.setCode("0");
result.setMsg("成功");
return result;
}
public static <T> Result<T> success(T data){ //当作是固定用法吧
Result<T> result =new Result<>(data);
result.setCode("0");
result.setMsg("成功");
return result;
}
// 返回失败的信息
public static Result error(String code, String msg){
Result result=new Result<>();
result.setCode(code);
result.setMsg(msg);
return result;
}
}User类
package com.example.springboot.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@TableName("user")
@Data
public class User {
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
private String password;
private String nickName;
private Integer age;
private String sex;
private String address;
}UserMapper类
package com.example.springboot.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}控制器类UserController类
package com.example.springboot.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot.config.Result;
import com.example.springboot.entity.User;
import com.example.springboot.mapper.UserMapper;
import com.example.springboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
//@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;
@DeleteMapping("/{id}")
public Result<?> delete(@PathVariable int id){
userMapper.deleteById(id);
return Result.success();
}
@PostMapping
public Result<?> save(@RequestBody User user){
if(user.getPassword() == null){
user.setPassword("123456");
}
userMapper.insert(user);
return Result.success();
}
//表单更新
@PutMapping
public Result<?> update(@RequestBody User user){
userMapper.updateById(user);
return Result.success();
}
@GetMapping
public Result<?> findPage(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "10") Integer pageSize,@RequestParam(defaultValue = "") String search){
Page page = new Page(pageNum, pageSize);
LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery();
if (StrUtil.isNotBlank(search)){
wrapper.like(User::getNickName, search);
}
Page<User> userPage = userMapper.selectPage(page,wrapper);
return Result.success(userPage);
}
}五、前台界面



0条评论
点击登录参与评论