vue+elementui+springboot构建简单的前后端分离框架项目

相关文章链接:

Win10安装Node.js

Eclipse与IDEA创建一个Maven的Java Web项目

观前提示:

本文所使用的IDEA版本为ultimate 2019.1,JDK版本为1.8.0_141。

1.安装node.js

参考文章:Win10安装Node.js

2.安装cnpm

因为npm安装插件是从国外服务器下载,受网络影响大,可能出现异常,所以我们要安装淘宝镜像的cnpm。

执行命令

npm install -g cnpm --registry=http://registry.npm.taobao.org

在这里插入图片描述
执行命令

cnpm -v

可以查看cnpm的版本
在这里插入图片描述

3.安装vue-cli

执行命令

cnpm install -g @vue/cli

在这里插入图片描述
执行命令

vue -V

可以查看安装的版本
在这里插入图片描述

4.创建Vue项目

执行命令

vue create 项目名

在这里插入图片描述
选择默认即可
在这里插入图片描述
在这里插入图片描述
进入项目中cd vuedemo
在这里插入图片描述

执行命令

npm run serve

在这里插入图片描述
访问一下
在这里插入图片描述
项目创建成功。

5.安装相关组件

5.1 安装element-ui

cnpm install element-ui --save

在这里插入图片描述

5.2 安装axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js中。可以理解为ajax。

详情链接网址:axios

执行以下命令安装axios

cnpm install axios --save

在这里插入图片描述

5.3 安装vue-router

Vue Router 是 Vue.js 官方的路由管理器。

详情链接网址:Vue Router

执行以下命令安装vue-router

cnpm install vue-router --save

在这里插入图片描述

5.4 安装qs

qs可将对象序列化,防止传输到后台的数据接收不到。

执行以下命令安装qs

cnpm install qs --save

在这里插入图片描述

5.5 安装Vuex

Vuex是Vue.js应用程序的状态管理模式+库。它充当应用程序中所有组件的集中存储,其规则确保状态只能以可预测的方式进行更改。

详情链接网址:Vuex

执行以下命令安装Vuex

cnpm install vuex --save

在这里插入图片描述

6.IDEA安装Vue.js插件

点击File->Settings…
在这里插入图片描述
选择Plugins -> 搜索框输入vue -> Install -> OK -> 重启IDEA使插件生效。

这里由于我已经安装过Vue.js插件了,所以显示Installed。
在这里插入图片描述
点击File -> Settings… -> Languages & Frameworks -> JavaScripts -> 在JavaScript language version选择ECMAScript 6 -> OK

在这里插入图片描述

7.IDEA新建一个空项目

选择Empty Project->Next
在这里插入图片描述
填写项目名称->Finish
在这里插入图片描述

8.引入新建的vue项目

在Project Structure中引入新建好的vue项目。
在这里插入图片描述
选择好项目后->默认第一项Create module from existing sources-Next
在这里插入图片描述
一直Next到Finish即可。

查看一下package.json文件,发现相关组件也是正常安装的。

在这里插入图片描述

运行项目
在这里插入图片描述
在这里插入图片描述

9.新建springboot项目

在Project Structure新建一个Springboot的Module

参考文章:Eclipse与IDEA创建一个Maven的Java Web项目第2.2.1章节

10.简单的前后端交互实现

10.1 编写vue项目

目录结构如下
在这里插入图片描述

编写 main.js,引入element-ui控件,router。

import Vue from 'vue'
import App from './App.vue'
import router from './router'
//引入element-ui控件
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.config.productionTip = false
//使用use命令后才起作用
Vue.use(ElementUI)

new Vue({
    
    
  router,
  render: h => h(App),
}).$mount('#app')

编写 App.vue

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <router-view/>
  </div>
</template>

<script>

  export default {
    name: 'App',
  }
</script>

<style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>

编写router文件夹下的 index.js

import Vue from 'vue'
import Router from 'vue-router'
//使用懒加载的方式来引入,只有路由被访问的时候才加载
import home from '@/components/Home'
import login from '@/components/Login'

Vue.use(Router)
let router =  new Router({
    
    
  routes: [
    {
    
    
      path:'/',
      name :'login',
      component:login
    },
    {
    
    
      path:'/login',
      name :'login',
      component:login
    },
    {
    
    
      path:'/home',
      name :'home',
      component:home
    }
  ]
})

export default router

编写登录页面 Login.vue

<template>

  <el-form ref='AccountFrom' :model='account' :rules='rules' lable-position='left' lable-width='0px' class='demo-ruleForm login-container'>
    <h3 class="title">登录系统首页</h3>
    <el-form-item prop="username">
      <el-input type="text" v-model="account.username" auto-complete="off" placeholder="账号"></el-input>
    </el-form-item>
    <el-form-item prop="pwd">
      <el-input type="password" v-model="account.pwd" auto-complete="off" placeholder="密码"></el-input>
    </el-form-item>
    <el-checkbox v-model="checked" checked class="remember">记住密码</el-checkbox>
    <el-form-item style="width:100%;">
      <el-button type="primary" style="width:100%;" @click.native.prevent='handleLogin'>登录</el-button>
    </el-form-item>
  </el-form>

</template>

<script>
  import axios from 'axios';
  axios.defaults.baseURL = 'http://localhost:8090'
  import qs from 'qs';
  export default {
    name: 'login',
    data() {
      return {
        account: {
          username: '',
          pwd: ''
        },
        rules: {
          username: [{
            required: true,
            message: '请输入账号',
            trigger: 'blur'
          }],
          pwd: [{
            required: true,
            message: '请输入密码',
            trigger: 'blur'
          }]
        },
        checked: true
      }
    },
    methods:{
      handleLogin(){
        this.$refs.AccountFrom.validate((valid)=>{

          if(valid){
            //将提交的数据进行封装
            var param = {username : this.account.username,pwd:this.account.pwd};

            axios.post("/system/login", qs.stringify(param)).then((result) => {
              if(result.data.code == '200'){
                //用vue路由跳转到后台主界面
                this.$router.push({path:'/home'});
              } else {
                this.$message({
                  message:result.data.msg,
                  type:'error'
                });
              }
            });

          }else{
            console.log('error submit');
            return false;
          }
        });
      }
    }
  }
</script>

<style>
  body {
    background: #DFE9FB;
  }

  .login-container {
    width: 350px;
    margin-left: 35%;
  }
</style>

编写成功登陆页面 Home.vue

<template>
  <div></div>
</template>

<script>
  export default {
      mounted: function () {
        this.loadData();
      },
    methods: {
      loadData() {
        const h = this.$createElement;

        this.$notify({
          title: '标题名称',
          message: h('i', { style: 'color: teal'}, '登录成功')
        });
      }
    }
  }
</script>

<style>
  body {
    background: #DFE9FB;
  }
</style>

10.2 编写springboot项目

目录结构
在这里插入图片描述

pom.xml引入相关依赖

<dependency>
   <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.48</version>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.10</version>
</dependency>

编写 application.properties

#服务端口配置
server.port=8090

#数据库连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root

#Mybatis配置
mybatis.mapper-locations=classpath:mapper/**.xml

编写 DemoApplication.java

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.demo.dao")
public class DemoApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(DemoApplication.class, args);
    }

}

编写 CorsFilter.java 解决跨域问题

package com.example.demo.filter;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CorsFilter implements Filter{
    
    

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requseted-With, Content-Type, Accept");
        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
    
    

    }
}

编写 LoginController.java

package com.example.demo.controller;

import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/system")
public class LoginController {
    
    

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public Map<String, Object> Login(User user){
    
    
        Map<String, Object> result = new HashMap<>();

        User user1 = userService.selectByNameAndPWD(user);

        if(user1 == null ){
    
    
            result.put("code", 500);
            result.put("msg", "登录失败");
            return result;
        }

        result.put("code", 200);
        result.put("msg", "登录成功");
        return result;
    }
}

编写 UserService.java

package com.example.demo.service;

import com.example.demo.dao.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    
    

    @Autowired
    private UserMapper userMapper;

    public User selectByNameAndPWD(User user){
    
    
        return userMapper.selectByNameAndPWD(user);
    }
}

编写 UserMapper.java

package com.example.demo.dao;

import com.example.demo.model.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper {
    
    

    User selectByNameAndPWD(User user);
}

编写 User.java

package com.example.demo.model;

public class User {
    
    
    private String id;
    private String username;
    private String pwd;

    public String getId() {
    
    
        return id;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public String getUsername() {
    
    
        return username;
    }

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

    public String getPwd() {
    
    
        return pwd;
    }

    public void setPwd(String pwd) {
    
    
        this.pwd = pwd;
    }
}

编写 UserMapper.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserMapper">
    <select id="selectByNameAndPWD" resultType="com.example.demo.model.User" parameterType="com.example.demo.model.User">
        select
            id,username,pwd
        from user
        where username = #{username}
            and pwd = #{pwd}
    </select>
</mapper>

11.可能遇到的问题

11.1 No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

如果遇到以下问题,那就是你没有处理跨域问题。
在这里插入图片描述
参考 第10.2节中 编写 CorsFilter.java 解决跨域问题 编写一个过滤器即可。

补充

补充1 同源与跨域

同源:协议、域名、端口均相同即为同源。

跨域:协议、域名、端口只要有一项不同即为跨域。

例:http://www.baidu.com,http://为协议,www.baidu.com为域名,80为端口(默认端口可以省略)。

一下为是否与http://demo/login同源的例子

http://demo/usr				同源
https://demo/usr 			不同源,协议不同
http://a.demo/usr 			不同源,域名不同
http://demo:8082/usr		不同源,端口不同

猜你喜欢

转载自blog.csdn.net/weixin_43611145/article/details/105628890