Vue + elementui + springboot는 간단한 프런트 엔드 및 백 엔드 분리 프레임 워크 프로젝트를 빌드합니다.
관련 기사 링크 :
Eclipse와 IDEA는 Maven Java 웹 프로젝트를 만듭니다.
보기 전 팁 :
이 기사에 사용 된 IDEA 버전은 2019.1 궁극이며 JDK 버전은 1.8.0_141입니다.
1. node.js 설치
참조 문서 : Win10에 Node.js 설치
2. cnpm 설치
npm 설치 플러그인은 외부 서버에서 다운로드되기 때문에 네트워크의 영향을 많이 받고 비정상 일 수 있으므로 Taobao 미러의 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는 브라우저 및 node.js에서 사용할 수있는 약속 기반 HTTP 라이브러리입니다. 아약스로 이해할 수 있습니다.
다음 명령을 실행하여 axios를 설치하십시오.
cnpm install axios --save
5.3 vue-router 설치
Vue Router는 Vue.js의 공식 경로 관리자입니다.
상세 링크 URL : 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를 설치하십시오.
cnpm install vuex --save
6. IDEA가 Vue.js 플러그인을 설치합니다.
파일-> 설정 ...을 클릭
하십시오. 플러그인-> 검색 상자를 선택하고 vue-> 설치-> 확인-> IDEA를 다시 시작하여 플러그인을 적용하십시오.
Vue.js 플러그인을 설치 했으므로 설치됨으로 표시됩니다.
파일-> 설정…-> 언어 및 프레임 워크-> JavaScript-> JavaScript 언어 버전에서 ECMAScript 6 선택-> 확인
7. IDEA가 빈 프로젝트를 만듭니다.
빈 프로젝트-> 다음을 선택
하여 프로젝트 이름을 입력하십시오- > 마침
8. 새로운 vue 프로젝트 소개
새로 생성 된 vue 프로젝트를 Project Structure에 소개합니다.
프로젝트-> 기본값을 선택한 후 첫 번째 항목 기존 소스에서 모듈 만들기-다음 및
완료를 계속하십시오.
package.json 파일을 확인하고 관련 구성 요소도 정상적으로 설치되었는지 확인합니다.
프로젝트 실행
9. 새로운 springboot 프로젝트
프로젝트 구조에서 새 Springboot 모듈 만들기
참조 기사 : Eclipse와 IDEA는 Maven Java 웹 프로젝트 2.2.1 장을 만듭니다.
10. 간단한 프런트 엔드 상호 작용 구현
10.1 vue 프로젝트 작성
디렉토리 구조는 다음과 같습니다.
main.js 작성 , element-ui 제어, 라우터 소개.
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>
라우터 폴더 아래에 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 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다.
다음 문제가 발생하면 도메인 간 문제를 처리하지 않은 것입니다.
섹션 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 不同源,端口不同