项目运行效果
前言
有正在学习springboot+vue开发的小伙伴可评论区留言,我们一起学习交流,或者对springboot+vue开发有疑问的小伙伴也可一起交流解决。文章主要讲解前后端之间的通信,交互,对后端控制层以外的代码不做过多暴露,想要springboot+vue项目源码可私信评论我
项目介绍
本文主要记录使用springboot和vue进行整合开发流程,实现前后端分离,具体步骤和知识点都会讲解记录或者是在注释中进行说明。使用Element工具提供组件,实现(CRM)客户关系管理的一个系统。开发工具使用Idea和Vscode,使用vue-cli搭建项目,实现前后端分离。下文将对项目的用户管理模块和积分管理模块进行讲解记录,管理员可对用户进行添加,删除,修改,查询等功能。积分模块在用户管理模块的基础上多了积分兑换功能,因此积分模块只对积分兑换功能进行讲解。后端控制层使用REST风格提供接口
项目搭建,
如果已经安装过vue-cli脚手架可跳过这一步,使用Idea的搭建springboot就不再叙述了**
第一步::全局安装脚手架工具:npm install -g vue-cli
创建成功
第二步:创建工程:访问到目标文件夹,点击地址栏切换到cmd,输入命令:vue init webpack vue-website。 vue-website是工程名
第三步:启动工程:npm run dev
自此vue-cli的项目搭建完成,系统自动产生这样的文件夹,使用Vscode去打开文件夹即可。
项目搭建完成,接下来进行开发
登录功能
效果展示
后端
使用@RequestMapping("/api/user")进行窄化路径,controller接口:
@PostMapping("/login")
public Map<String,Object> login(@RequestBody User cuser){
Map<String,Object> map = new HashMap<String,Object>();
System.out.println(cuser);
User user = userService.login(cuser.getUloginid(),cuser.getUpassword());
if(user!=null) {
map.put("status", 200);
map.put("msg","登录成功");
map.put("data", user);
}else {
map.put("status", 0);
map.put("msg","登录失败");
map.put("data", user);
}
return map;
}
因此访问全路径为:http://localhost:7070/api/user/login
前端Login.vue
<el-form label-width="60px" :rules="rules" :model="loginFormData" ref="loginFormRef">
<el-form-item label="密码" prop="upassword">
<el-input placeholder="用户密码" size="small" v-model="loginFormData.upassword" show-password></el-input>
</el-form-item>
1,model 表单数据对象,在标签中加上这个属性等于"loginFormData"将会找到export default中的 data() 中的 return 中的loginFormData,loginFormData存放的便是后端取得的对象
,2,rules 表单验证规则*,在标签中加上这个属性
表单将会自动绑定到export default中的 data() 中的 return 中的rules
3,prop,传入 Form 组件的 model 中的字段,由于model中绑定的是loginFormData,因此图中会找到loginFormData中的uloginid字段
4,v-model=“loginFormData.upassword”,在标签中使用它是的输入框的值与该字段绑定
5,show-password在标签中使用它使得输入框后面出现一个眼睛可以展示或者隐藏输入框的内容,通常用在密码框
export default {
data() {
return {
loginFormData:{
uloginid:'',
upassword:''
},
rules:{
uloginid:[
{
required: true, message: '账号不能为空', trigger: 'blur' },
{
min:3, max:10, message: '账号长度在 3 到 10 个字符之间', trigger: 'blur' }
],
upassword:[
{
required: true, message: '密码不能为空', trigger: 'blur' },
{
min: 3, max:10, message: '密码长度在 3 到 10 个字符之间', trigger: 'blur' }
]
}
}
},
6,resetField 对该表单项进行重置,将其值重置为初始值并移除校验结果,使用方法:@click=“resetForm”
<el-form-item>
<el-button type="info" size="small" @click="resetForm">重置表单</el-button>
</el-form-item>
在 methods:{ }定义该方法即可。
resetForm(){
this.$refs.loginFormRef.resetFields();
}
核心方法
<el-button type="primary" size="small" @click="userLogin">用户登录</el-button>
在用户登录按钮上绑定方法@click=“userLogin”,在methods:{ }中定义该方法,
实现userLogin方法一:
如果控制层使用对象来接收前端,需在控制层方法的参数区使用@RequestBody来反序列化,将json转成对象以供后端使用,在userLogin中实现步骤如下:
1,在验证通过后再触发ajax异步登录,
2,ajax 完成登录验证
3,动态通过路由管理器切换组件
4,在sessionStorage 对象中存用户的身份信息;
详细步骤在代码中已经注释
methods:{
userLogin(){
//必须在验证通过后再触发ajax异步登录,
//validate 任一表单项被校验后触发 被校验的表单项 prop 值,校验是否通过,错误消息(如果存在)
this.$refs.loginFormRef.validate(async valid=>{
if(!valid){
//验证未通过,在页面给出验证未通过提示信息.
this.$message.error('抱歉,表单验证未通过,登录未提交');
return;
}
//ajax 完成登录验证,后端用对象接收,已经在main.js中//设置ajax请求的基地址
//axios.defaults.baseURL='http://localhost:7070/api/',因此在post中只需要加上'user/login'即可。
//this.loginFormData传入前端绑定的用户名,密码组成的对象,把调用后端的返回结果data赋值给res
const {
data:res}= await this.$axios.post('user/login',this.loginFormData);//返回一个Promise对象
if(res.status==0)
{
this.$message.error('抱歉,登录失败');
return;
}
this.$message.success('登录成功........');
//动态通过路由管理器切换组件
this.$router.push('/home')
//在sessionStorage 对象中存用户的身份信息;
sessionStorage.setItem('cuser',res.data.uname)
});
实现userLogin方法二:
控制层通过参数接收前端
1,在export default加上import Qs from ‘qs’
2,把 const {data:res}= await this.$axios.post(‘user/login’,this.loginFormData);//返回一个Promise对象换成以下代码即可
//后端通过参数接收前端,记得先导入import Qs from 'qs'
const {
data:res}= await this.$axios({
method:'post',
url:'user/login',
data:Qs.stringify(this.loginFormData)
})
切换到主界面
this.$router.push('/home')
使用它之前需要在route中配置路由,因此在登录成功之后会切换到主界面。在主界面(/home)路由中有user这个子路由。
import Vue from 'vue'
import Router from 'vue-router'
//import HelloWorld from '@/components/HelloWorld'
import Login from '@/components/Login.vue'
import Home from '@/components/Home.vue'
import User from '@/components/User.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/login', name: 'Login',component: Login},
{
path: '/',redirect:'/login'},
{
path:'/home',name:'Home',component:Home,children:[
{
path: '/user', name: 'User',component: User},
]},
]
})
主界面
完成登录之后动态通过路由管理器切换组件到主界面,采用Element的导航,
效果展示
collapse 是否水平折叠收起菜单(仅在 mode 为 vertical 时可用)
menuData:[
{
mid:1001,
mtitle:'用户管理',
micon:'el-icon-user-solid',
children:[
{
sid:100101,stitle:'用户列表',sicon:'el-icon-s-custom',path:'/user'},
{
sid:100102,stitle:'导出用户',sicon:'el-icon-s-cooperation',path:'/quill'},
{
sid:100103,stitle:'导入用户',sicon:'el-icon-s-order',path:'/uimport'}
]
}
在home界面的导航中提供一个menuData为用户管理,用户管理中有子组件,user,因此点击用户列表可跳转到User.vue
用户管理之分页展示数据
效果展示
后端:
先在实体类中加入一个分页的类,startindex代表起始页,offset代表每页中的记录条数
在Mapper中
<select id="userpager" parameterType="map" resultType="user">
select * from tb_users where uloginid like '%${searchkey}%' limit #{startindex},#{offset}
</select>
在service中,主要步骤已经在代码中进行注释
//最终返回一个pager对象
@Override
public Pager<User> pager(int pageindex, int offset,String searchkey) {
//new 一个pager对象
Pager<