你好,【程序职场】专注于:Spring Boot ,微服务 和 前端APP开发,闲暇之余一起聊聊职场规划,个人成长,还能带你一起探索 副业赚钱渠道,在提升技术的同时我们一起交流 敏捷流程 提高工作效率,从技术到管理一步步提升自我!
 
标签:一个执着的职场程序员!

上篇文章为大家讲述了 Spring Boot + Vue前后端分离(二)前端Vue启动流程;本篇文章接着上篇内容继续为大家介绍 如何前后端分离实现登录功能。

本文是Spring Boot + Vue前后端分离 系列的第三篇,了解前面的文章有助于更好的理解本文:


1.Spring Boot + Vue前后端分离(一)前端Vue环境搭建
2.Spring Boot + Vue前后端分离(二)前端Vue启动流程


前言

(一).前端登录页面实现

(二).后端登录功能实现

上一篇大家都学习到了vue前端的启动流程,相信对于小伙伴来说都是很easy的,我们今天主要说一下前后端分离实现登录功能,让我们知道前后端分离到底是什么?是怎么实现的?

(一).前端登录页面实现
#登录页面

前端页面开发比较简单,我们这里也不做过多的渲染,后期会做这些界面效果。

右键项目目录 src\components ,操作 New -> Vue Component,命名为 Login

内容如下:

<template>  <div>    账号: <input type="text" v-model="loginForm.username" placeholder="请输入账号"/>    <br><br>    密码: <input type="password" v-model="loginForm.password" placeholder="请输入密码"/>    <br><br>    <button v-on:click="login">登录账号</button>  </div></template>
<script>
export default {  name: 'Login',  data () {    return {      loginForm: {        username: '',        password: ''      },      responseResult: []    }  },  methods: {    login () {      this.$axios        .post('/login', {          username: this.loginForm.username,          password: this.loginForm.password        })        .then(successResponse => {          if (successResponse.data.code === 200) {            this.$router.replace({path: '/index'})          } else {            alert('登录失败!')          }        })        .catch(failResponse => {        })    }  }}</script>
解释:
<template> 标签中简单的写了一个登录界面, methods 中定义了登录操作,即向后端 /login 接口发送数据,获得相应成功后,页面跳转到 /index(成功页面)。

#成功主页面HomePage.vue

<template>  <div>    恭喜你,登录成功啦!!!    公众号:【程序职场】  欢迎你  </div></template>
<script>export default {  name: 'HomePage'}</script>
<style scoped></style>
解释:

右键 src\components 文件夹,新建一个 目录 home,在 home 下新建一个 HomePage.vue ,即首页组件。

#设置反向代理

// 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'// 设置反向代理,前端请求默认发送到 http://localhost:8082/var axios = require('axios')axios.defaults.baseURL = 'http://localhost:8082/'// 全局注册,之后可在其他组件中通过 this.$axios 发送数据Vue.prototype.$axios = axiosVue.config.productionTip = false
/* eslint-disable no-new */new Vue({  el: '#app',  router,  components: { App },  template: '<App/>'})
解释:

这里需要注意的是,使用了模块 axios,如果没有安装过该模块的,会报错,所以需要进入到项目文件夹中,执行 npm install --save axios,以安装这个模块。

#配置页面路由​​​​​​​

import Vue from 'vue'import Router from 'vue-router'// 导入刚才编写的组件import HomePage from '@/components/home/HomePage'import Login from '@/components/Login'
Vue.use(Router)
export default new Router({  routes: [    // 下面都是固定的写法    {      path: '/login',      name: 'Login',      component: Login    },    {      path: '/index',      name: 'HomePage',      component: HomePage    }  ]})

文件目录:src\router\index.js

该内容不错过多说明了,很简单的操作。

#跨域支持

为了让后端能够访问到前端的资源,需要配置跨域支持。

在 config\index.js 中,找到 proxyTable 位置,做跨域的支持。​​​​​​​​​​​​​​

'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: {      '/': {        target: 'http://localhost:8082',        changeOrigin: true,        pathRewrite: {          '^/': ''        }      }    },    // 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-
    // Use Eslint Loader?    // If true, your code will be linted during bundling and    // linting errors and warnings will be shown in the console.    useEslint: true,    // If true, eslint errors and warnings will also be shown in the error overlay    // in the browser.    showEslintErrorsInOverlay: false,
    /**     * 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  }}

好了,到这里前端页面已经做好了,运行项目可以看到 登录页面了。

执行 npm run dev,或双击 dev(start 也一样)脚本,查看登录页面效果。

我所有的操作都是用的 cnpm  相对比npm快。

(二).后端登录功能实现

后端开发我是用的是 idea  首先需要新建一个项目,选择web,mysql,jpa等 ,这里我就不做截图说明了,pom文件内容如下:

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>2.2.4.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <groupId>com.cxzc.mycxzc</groupId>    <artifactId>demo</artifactId>    <version>0.0.1-SNAPSHOT</version>    <packaging>war</packaging>    <name>demo</name>    <description>Demo project for Spring Boot</description>
    <properties>        <java.version>1.8</java.version>    </properties>
    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>
        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-data-jpa</artifactId>        </dependency>
        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.40</version>        </dependency>
        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-tomcat</artifactId>            <scope>provided</scope>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>            <exclusions>                <exclusion>                    <groupId>org.junit.vintage</groupId>                    <artifactId>junit-vintage-engine</artifactId>                </exclusion>            </exclusions>        </dependency>    </dependencies>
    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build>
</project>
#数据库创建和数据添加

后端的数据库我们用到了mysql,首先需要我们创建数据库名字cxzc-vue,然后执行如下命令添加数据。​​​​​​​

-- ------------------------------ Table structure for user-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  `username` varchar(255) DEFAULT NULL,  `password` varchar(255) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ------------------------------ Records of user-- ----------------------------INSERT INTO `user` VALUES ('1', 'admin', 'admin');
#数据库配置​​​​​​​
server.port=8082
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/cxzc-vue?characterEncoding=UTF-8spring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.jpa.hibernate.ddl-auto = none

#新建 User​​​​​​​

package com.cxzc.mycxzc.demo.bean;import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
@Entity@Table(name = "user")@JsonIgnoreProperties({"handler","hibernateLazyInitializer"})
public class User {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    @Column(name = "id")    int id;
    String username;    String password;
    public int getId() {        return id;    }
    public void setId(int id) {        this.id = id;    }
    public String getUsername() {        return username;    }
    public void setUsername(String username) {        this.username = username;    }
    public String getPassword() {        return password;    }
    public void setPassword(String password) {        this.password = password;    }}

@Entity 表示这是一个实体类
@Table(name=“user”) 表示对应的表名是 user

#数据访问对象 UserDAO​​​​​​​

package com.cxzc.mycxzc.demo.dao;import com.cxzc.mycxzc.demo.bean.User;import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDAO extends JpaRepository<User,Integer> {    User findByUsername(String username);    User getByUsernameAndPassword(String username,String password);}

Data Access Object(数据访问对象,DAO)即用来操作数据库的对象,这个对象可以是我们自己开发的,也可以是框架提供的。这里我们通过继承 JpaRepository 的方式构建 DAO。

由于使用了 JPA,无需手动构建 SQL 语句,而只需要按照规范提供方法的名字即可实现对数据库的增删改查。

如 findByUsername,就是通过 username 字段查询到对应的行,并返回给 User 类。

# UserService 数据对象的实现​​​​​​​

package com.cxzc.mycxzc.demo.service;import com.cxzc.mycxzc.demo.bean.User;import com.cxzc.mycxzc.demo.dao.UserDAO;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class UserService {    @Autowired    UserDAO userDAO;
    public boolean isExist(String username) {        User user = getByName(username);        return null!=user;    }
    public User getByName(String username) {        return userDAO.findByUsername(username);    }
    public User get(String username, String password){        return userDAO.getByUsernameAndPassword(username, password);    }
    public void add(User user) {        userDAO.save(user);    }}

这里是对 UserDAO 做了一次封装,一般来讲,我们在 DAO 中只定义基础的增删改查操作,而具体的操作,需要由 Service 来完成。当然,由于我们做的操作原本就比较简单,所以这里看起来只是简单地重命名了一下,比如把 “通过用户名及密码查询并获得对象” 这种方法命名为 get。

#控制器 LoginController​​​​​​​

package com.cxzc.mycxzc.demo.controller;import com.cxzc.mycxzc.demo.bean.User;import com.cxzc.mycxzc.demo.response.Result;import com.cxzc.mycxzc.demo.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.*;import org.springframework.web.util.HtmlUtils;
import java.util.Objects;
@Controllerpublic class LoginController {    @Autowired    UserService userService;
    @CrossOrigin    @PostMapping(value = "/login")    @ResponseBody    public Result login(@RequestBody User requestUser) {        String username = requestUser.getUsername();        username = HtmlUtils.htmlEscape(username);
        User user = userService.get(username, requestUser.getPassword());        if (null == user) {            return new Result(400);        } else {            return new Result(200);        }    }}

登录控制器是主要控制部分,通过 UserService 提供的 get 方法查询数据库,如果返回的对象为空,则验证失败,否则就验证成功。

到这里后端的开发也完成了,让我们 启动后端项目,同时运行前端项目 ,访问 http://localhost:8080/#/login,输入用户名 admin,密码 admin,成功进入 localhost:8080/#/index

源码链接: https://github.com/ProceduralZC/itcxzc/tree/master/vue_test

好了,通过前后端分离 实现登录功能到这里就ok了,敬请期待下篇。。。​​​​​​​

作者:小小蒲公英

Logo

前往低代码交流专区

更多推荐