Vue项目10:Vue + SpringBoot前后端分离项目

本博文主要介绍如何使用Vue +SpringBoot实现前后端分离,实现简单登录功能。

 

本项目分为前端(vue)和后端(SpringBoot)两大模块。

一、前端

1.新建vue-cli项目

进入cmd命令行,输入如下命令:

C:\Users\Administrator>f:

F:\>cd F:\Study\vue\projectpractice

F:\Study\vue\projectpractice>vue init webpack blogvue

? Project name blogvue
? Project description A Vue.js project
? Author xxx <xxx@qq.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm

   vue-cli · Generated "blogvue".
...
# Project initialization finished!
# ========================

To get started:

  cd blogvue
  npm run dev

Documentation can be found at https://vuejs-templates.github.io/webpack

切换到工程目录

cd blogvue

启动项目

npm run dev

浏览器访问 http://localhost:8080

 2.开发页面头、页面尾公共组件

用vscode打开vue项目,在src/components中新建common目录,在common目录中新建两个文件: BlogFooter.vue和BlogHeader.vue

BlogHeader.vue 页面头代码:

<template>
    <div>
        页面头部
    </div>
</template>

<script>
export default {
  name: 'BlogHeader'
}
</script>

BlogFooter.vue 页面尾部代码:

<template>
    <div>
        页面尾部
    </div>
</template>

<script>
export default {
  name: 'BlogFooter'
}
</script>

3.开发登录页面

在src/components目录新建出manage目录,在manage目录下新建BlogLogin.vue,

BlogLogin.vue代码如下:

<template>
  <div>
    <blog-header></blog-header>
    <hr/>
    <div>
      用户名:<input type="text" v-model="loginInfoVo.username" placeholder="请输入用户名" />
      <br/>
      密码:<input type="password" v-model="loginInfoVo.password" placeholder="请输入密码" />
      <br/>
      <button v-on:click="login">登录</button>
      <br/>
      登录验证情况:<textarea cols="30" rows="10" v-model="responseResult"></textarea>
    </div>
    <hr/>
    <blog-footer></blog-footer>
  </div>
</template>

<script>
import blogHeader from '@/components/common/BlogHeader.vue'
import blogFooter from '@/components/common/BlogFooter.vue'

export default {
  name: 'BlogLogin',
  // blogHeader、blogFooter组件给申明到components里面然后在template里面使用
  components: { blogHeader, blogFooter },
  data () {
    return {
      loginInfoVo: { username: '', password: '' },
      responseResult: []
    }
  },
  methods: {
    login () {
      this.$axios
        .post('/login', {
          username: this.loginInfoVo.username,
          password: this.loginInfoVo.password
        })
        .then(successResponse => {
          this.responseResult = JSON.stringify(successResponse.data)
          if (successResponse.data.code === 200) {
            this.$router.replace({path: '/index'})
          }
        })
        .catch(failResponse => {})
    }
  }
}
</script>

4.开发首页页面组件

在src/components目录新建出home目录,在home目录下新建BlogIndex.vue,

BlogIndex.vue代码如下:

<template>
  <div>
    <blog-header></blog-header>
    <hr/>
    <div>
      这是首页,嘻嘻嘻。
    </div>
    <hr/>
    <blog-footer></blog-footer>
  </div>
</template>

<script>
import blogHeader from '@/components/common/BlogHeader.vue'
import blogFooter from '@/components/common/BlogFooter.vue'

export default {
  name: 'BlogIndex',
  // blogHeader/blogFooter组件给申明到components里面然后在template里面使用
  components: { blogHeader, blogFooter }
}
</script>

 

5.支持跨域,请求路由,页面路由开发

安装axios

cnpm install axios -g

安装axios依赖

npm install --save axios

报如下警告:

npm WARN ajv-keywords@3.4.1 requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself.

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):

npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

 

+ axios@0.19.0

added 4 packages from 8 contributors and audited 11771 packages in 13.481s

found 10 vulnerabilities (6 moderate, 4 high)

  run `npm audit fix` to fix them, or `npm audit` for details

解决警告方法:安装ajv和ajv-keywords

npm install ajv ajv-keywords -g

再次执行安装axios依赖

npm install --save axios

router/index.js 页面路由代码:

import Vue from 'vue'
import App from './App'
import router from './router'
// 引用axios,并设置基础URL为后端服务api地址
var axios = require('axios')
axios.defaults.baseURL = 'https://localhost:8443/api'
// 将API方法绑定到全局
Vue.prototype.$axios = axios
Vue.config.productionTip = false

/* eslint-disable */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

router/index.js 页面路由代码:
import Vue from 'vue'
import Router from 'vue-router'
import BlogLogin from '@/components/manage/BlogLogin.vue'
import BlogIndex from '@/components/home/BlogIndex.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      redirect: '/login'
    },
    {
      path: '/index',
      name: 'BlogIndex',
      component: BlogIndex
    },
    {
      path: '/manage',
      redirect: '/login'
    },
    {
      path: '/login',
      name: 'BlogLogin',
      component: BlogLogin
    }
  ]
})

config/index.js 跨域支持代码:

找到文件中的proxyTable位置修改为以下内容添加请求到后端的跨域支持。

proxyTable: {
  '/api': {
    target: 'https://localhost:8443',
    changeOrigin: true,
    pathRewrite: {
        '^/api': ''
    }
  }
}

启动项目

npm run dev

浏览器访问 http://localhost:8080 

此时在用户名和密码输入一些信息后,点击登录按钮后页面没有任何反应,因为没有后台进行数据验证处理,接下来需要开发后端代码。

 

二、后端

1.初始化SpringBoot项目

访问 https://start.spring.io/

 

点击Generate the project生成项目,得到blog.zip文件,解压zip文件

用IDEA打开解压后的文件,按如下项目目录结构新建出相应的package和java文件

 

2.编写相关代码

VueLoginInfoVo.java

package com.javalsj.blog.pojo.vo;


import javax.validation.constraints.NotNull;

/**
 * @description Vue登录页面demo信息对象实体
 * @author WANGJIHONG
 * @date 2018年4月5日 下午10:57:53
 * @Copyright 版权所有 (c) www.javalsj.com
 * @memo 备注信息
 */
public class VueLoginInfoVo {

    @NotNull(message="用户名不允许为空")
    private String username;

    @NotNull(message="密码不允许为空")
    private String password;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

 

Result.java:

package com.javalsj.blog.result;


/**
 * @description 统一 API响应结果封装
 * @author WANGJIHONG
 * @date 2018年3月13日 下午8:44:29
 * @Copyright 版权所有 (c) www.javalsj.com
 * @memo 控制Result权限,构建结果Result对象统一使用com.javalsj.blog.vo.ResultFactory工厂类来创建
 */
public class Result {
    /**
     * 响应状态码
     */
    private int code;
    /**
     * 响应提示信息
     */
    private String message;
    /**
     * 响应结果对象
     */
    private Object data;

    Result(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

}

 

ResultCode.java:

package com.javalsj.blog.result;


/**
 * @description 响应码枚举,参考 HTTP状态码的语义
 * @author WANGJIHONG
 * @date 2018年3月13日 下午8:35:00
 * @Copyright 版权所有 (c) www.javalsj.com
 * @memo 无备注说明
 */
public enum ResultCode {
    /**
     * 成功
     */
    SUCCESS(200),
    /**
     * 失败
     */
    FAIL(400),

    /**
     * 未认证(签名错误)
     */
    UNAUTHORIZED(401),

    /**
     * 接口不存在
     */
    NOT_FOUND(404),

    /**
     * 服务器内部错误
     */
    INTERNAL_SERVER_ERROR(500);

    public int code;

    ResultCode(int code) {
        this.code = code;
    }

}

 

ResultFactory.java:

package com.javalsj.blog.result;


/**
 * @description 响应结果生成工厂类
 * @author WANGJIHONG
 * @date 2018年3月13日 下午8:36:58
 * @Copyright 版权所有 (c) www.javalsj.com
 * @memo 无备注说明
 */
public class ResultFactory {

    public static Result buildSuccessResult(Object data) {
        return buidResult(ResultCode.SUCCESS, "成功", data);
    }

    public static Result buildFailResult(String message) {
        return buidResult(ResultCode.FAIL, message, null);
    }

    public static Result buidResult(ResultCode resultCode, String message, Object data) {
        return buidResult(resultCode.code, message, data);
    }

    public static Result buidResult(int resultCode, String message, Object data) {
        return new Result(resultCode, message, data);
    }
}

LoginController 代码:

package com.javalsj.blog.controller;

import com.javalsj.blog.pojo.vo.VueLoginInfoVo;
import com.javalsj.blog.result.Result;
import com.javalsj.blog.result.ResultFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Objects;

@Controller
public class LoginController {

    /**
     * 登录控制器,前后端分离用的不同协议和端口,所以需要加入@CrossOrigin支持跨域。
     * 给VueLoginInfoVo对象加入@Valid注解,并在参数中加入BindingResult来获取错误信息。
     * 在逻辑处理中我们判断BindingResult知否含有错误信息,如果有错误信息,则直接返回错误信息。
     */
    @CrossOrigin
    @RequestMapping(value = "/api/login", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
    @ResponseBody
    public Result login(@Valid @RequestBody VueLoginInfoVo loginInfoVo, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String message = String.format("登陆失败,详细信息[%s]。", bindingResult.getFieldError().getDefaultMessage());
            return ResultFactory.buildFailResult(message);
        }
        if (!Objects.equals("admin", loginInfoVo.getUsername()) || !Objects.equals("admin", loginInfoVo.getPassword())) {
            String message = String.format("登陆失败,详细信息[用户名、密码信息不正确]。");
            return ResultFactory.buildFailResult(message);
        }
        return ResultFactory.buildSuccessResult("登陆成功。");
    }


}

 

3.配置https访问

参考:https://blog.csdn.net/qq_42881421/article/details/95080440

 

4.启动Springboot项目

 

测试验证:

返回浏览器,访问localhost:8080

1)输入错误信息:

用户名输入:1

密码输入:1

点击登录

点击登录按钮,将提示错误信息,如下:

2)输入正确信息:

用户名输入:admin

密码输入:admin

点击登录按钮,页面自动跳转到index页面

 

 

项目参考链接:https://segmentfault.com/a/1190000014211773

 

 

完成! enjoy it!

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值