SpringBoot+Vue前后端分离
springboot+vue前后端分离入门demo
·
文章目录
前言
一个入门级SpringBoot+Vue前后端分离demo,实现登录并跳转
前端:vue+elemengui+router+axios
后台:SpringBoot
一、vue项目创建
跟着狂神的胡言乱语式教程将vue简单入门,能够实现一个纯前端的登录并跳转主页的demo
狂神视频教程
二、SpringBoot项目创建
使用IDEA创建一个简单的SpringBoot项目,这里随便百度,参考很多
三、前后端整合
1.vue配置跨域跳转
在vue项目中config目录下的index.js文件中设置跨域
proxyTable: {
'/apis':{
target: 'http://localhost:8089',//这里是你的sprintboot项目中的后台接口
changeOrigin: true,//允许跨域
pathRewrite: {//重写路径
'^/apis':'/apis'//写'/apis'就相当于写'http://localhost:8089/apis'
}
}
2.springboot项目中添加接口
新建LoginController响应登录接口,url为’/apis/login’
@CrossOrigin//支持跨域
@RequestMapping(value = "/apis/login", method = RequestMethod.POST)
@ResponseBody
public String login(@RequestBody user u){//user实体类接收参数
System.out.println(u.getUsername()+"-----"+u.getPassword());
return u.getUsername();
}
四、项目代码
1.vue项目结构
2.vue项目代码
Login.vue
<template>
<div>
<!--el-form一个表单,两个输入框-->
<el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
<h3 class="login-title">欢迎登陆</h3>
<el-form-item label="账号" prop="username">
<el-input type="text" placeholder="请输入账号" v-model="form.username"/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"/>
</el-form-item>
<el-form-item>
<!--登陆按钮绑定了一个onSubmit事件-->
<el-button type="primary" v-on:click="onSubmit('loginForm')">登陆</el-button>
</el-form-item>
</el-form>
<!--提示窗-->
<el-dialog
title="温馨提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<span>请输入账号和密码</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name:"Login",
data(){
return{
form:{
username:'',
password:''
},
rules:{
username: [
{required:true,message:'账号不可为空',trigger:'blur'}
],
password: [
{required:true,message:'密码不可为空',trigger:'blur'}
]
},
dialogVisible:false
}
},
methods:{
onSubmit(formName){
/*为表单绑定验证功能*/
this.$refs[formName].validate((valid)=>{
if(valid){
/*如果引用成功了,会去router中push到main,这种方式称为编程式导航*/
// this.$router.push("/main/"+this.form.username);
this.login()
}else {
this.dialogVisible=true;
return false;
}
});
},
login(){
this.axios.post('/apis/login',
{username:this.form.username,password:this.form.password}
).then(successResponse=>{
console.log(successResponse)
this.$router.push("/main/"+this.form.username);
})
}
}
}
</script>
<style lang="scss" scoped>
.login-box {
border: 1px solid #DCDFE6;
width: 350px;
margin: 180px auto;
padding: 35px 35px 15px 35px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
.login-title {
text-align: center;
margin: 0 auto 40px auto;
color: #303133;
}
</style>
main.vue
<template>
<el-container style="height: 500px; border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-message"></i>用户管理
</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<!-- 需要对象v-bind -->
<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<router-link to="/user/list">用户列表</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-menu"></i>内容管理
</template>
<el-menu-item-group>
<el-menu-item index="2-1">分类管理</el-menu-item>
<el-menu-item index="2-2">内容列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-menu"></i>系统管理
</template>
<el-menu-item-group>
<el-menu-item index="2-1">分类管理</el-menu-item>
<el-menu-item index="2-2">内容列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>{{name}}</span>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<style>
.el-header {
background-color: #b3c0d1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
<script>
export default {
props: ['name'],
data() {
const item = {
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
};
return {
tableData: Array(20).fill(item)
};
}
};
</script>
NotFound.vue
<template>
<div>
<h1>404</h1>
<h1>你的页面走丢了</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
App.vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
List.vue
<template>
<el-table
:data="tableData"
height="250"
border
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-08',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-06',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-07',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}]
}
}
}
</script>
<style scoped>
</style>
Profile.vue
<template>
<div>
<h1>个人信息</h1>
{{id}}
</div>
</template>
<script>
export default {
name: "UserProfile",
props: ['id'],
//过滤器,钩子函数
beforeRouteEnter:(to, from, next)=>{
console.log("进入路由之前")//加载数据
next(vm => {
vm.getData()
})
},
beforeRouteLeave:(to, from, next)=>{
console.log("进入路由之后")
next()
},
methods: {
getData: function () {
this.axios({
method: "get",
url: 'http://localhost:8080/static/mock/data.json'
}).then(function (response){
console.log(response)
})
}
}
}
</script>
<style scoped>
</style>
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import VueAxios from 'vue-axios'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI)
Vue.use(VueAxios, axios)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
router/index.js
import Vue from "vue";
import Router from 'vue-router'
import main from "../views/main";
import Login from "../views/Login";
import UserList from "../views/user/List"
import UserProfile from "../views/user/Profile"
import NotFound from "../views/NotFound";
Vue.use(Router)
export default new Router({
mode: "history",
routes: [
{
path: '/main/:name',
component: main,
props: true,
children: [
{path: '/user/profile/:id', name: 'UserProfile', component: UserProfile, props: true},
{path: '/user/list', component: UserList}
]
},
{
path: '/login',
component: Login
},{
path: '/goHome',
redirect: '/main'
},{
path: '*',
component: NotFound
}
]
})
config/index.js
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/apis':{
target: 'http://localhost:8089',
changeOrigin: true,
pathRewrite: {
'^/apis':'/apis'
}
}
},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
3.springboot项目结构
4.springboot代码
LoginController
package com.example.springbootvue.controller;
import com.example.springbootvue.entity.user;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
public class LoginController {
@CrossOrigin
@RequestMapping(value = "/apis/login", method = RequestMethod.POST)
@ResponseBody
public String login(@RequestBody user u){
System.out.println(u.getUsername()+"-----"+u.getPassword());
return u.getUsername();
}
@RequestMapping("/")
@ResponseBody
public String Hello(){
return "Hello";
}
}
user
package com.example.springbootvue.entity;
public class user {
private String username;
private String password;
public String getUsername(){
return username;
}
public String getPassword(){
return password;
}
}
总结
是个极简的demo,只是实现了前后端分离的跨域对接,没有写连接数据库与用户验证
另外需要注意,config中index.js文件修改后好想要关掉项目重新启动才会生效
更多推荐
已为社区贡献1条内容
所有评论(0)