SpringBoot+Vue前後端分離及互動

德克薩斯的松鼠發表於2020-12-07

什麼是前後端分離?

將一個應用的前後端程式碼分開寫

為什麼要前後端分離?

傳統的Javaweb開發中,往往是前端人員寫好html後,再由後端人員將java整合其中,變成JSP。 如此一來就造成了溝通不便、降低效率、前後端耦合度高等問題。

前後端分離是如何解決此問題的呢?

前端寫客戶端程式碼,後端寫服務端程式碼並提供介面
前端通過ajax請求訪問介面,將model展示到view中
如此前後端只需要約定介面文件(URL、引數、資料型別。注意:前後端是通過API進行互動的),之後便分別獨立開發。前端可以通過json造假資料進行測試,後端用postman進行測試。如此,前後端開發過程中互不依賴,只需最後前後端整合即可,這真正實現了前後端的解耦合
前端HTML→ajax→Restfull後端介面資料

圖解分析前後端分離

傳統開發:
在這裡插入圖片描述

前後端分離開發:
在這裡插入圖片描述
前後端分離就是將一個單體應用拆分為兩個獨立應用,前後端應用以json格式進行資料互動

前後端分離具體實現

SpringBoot + Vue

前端開發

前端專案搭建

Vue3及以上版本支援圖形介面建立Vue專案(前提是先裝好Vue環境)。在黑視窗中執行vue ui即可開啟圖形介面。在這裡插入圖片描述
在左上角開啟專案管理器在這裡插入圖片描述
然後建立專案(建立專案時自行選擇目錄)
在建立過程中可以把Git先勾掉在這裡插入圖片描述
在下一步中選擇手動預設在這裡插入圖片描述
再然後,選擇開啟Router、VueX功能,將Linter和Formatter功能關閉在這裡插入圖片描述
然後下一步選擇開啟歷史記錄(Use history mode for router)
最後,建立專案,選擇建立專案,不儲存預設在這裡插入圖片描述
建立成功後,點選頁面左上角任務,選中點選server執行,成功後就可以輸出(兩個訪問地址:localhost和Network均可訪問,且均為本地訪問)。最後,在黑視窗中Ctrl+C關閉視窗。此時便可以在idea中開啟專案(注意要在idea中安裝外掛:Vue.js)。idea代開專案後,左下角Terminal(這是一個內嵌伺服器),可以執行vue指令進行除錯。
在這裡插入圖片描述
Vue是單頁面(App.vue)應用,頁面的跳轉都是通過路由跳轉元件來更新的
什麼是路由?

<router-link to="/student">Student</router-link>
/*
	有點html裡面的錨連結的感覺
	Student   表示路由的名字
	/student  表示要跳轉到的相應元件
	路由跳轉的實現前提是先要在router(路由)包下的index.js檔案中進行引入
	
	引入方式一:
	引入格式:
	import Student from '../views/Student.vue' 
	再在index.js檔案的routers陣列中新增物件。如:
		{
   		 path: '/student',
  	 	 name: 'Student',  //可忽略
   		 component: Home   //與引入元件時import後面修飾的名字一致
	  }
  
  	引入方式二:
  不需要在index.js開頭引入
  直接在routers陣列中新增物件,如:
  {
    path: '/student',
    name: 'Student',
    component: () => import('../views/Student.vue')
  }

前端專案測試

Vue測試假資料:
在目標頁面元件的vue檔案中script部分,找到export default {}入口。
寫入資料,如:

data(){
            return{
                msg:'Hello Vue',
                students:[
                    {
                        id:1,
                        name:'糰子',
                        age:15
                    },
                    {
                        id:2,
                        name:'熊二',
                        age:16
                    },
                    {
                        id:3,
                        name:'小熊',
                        age:15
                    }
                ]
            }
        }

在表格中訪問資料

<table>
            <tr>
                <td>id</td>
                <td>姓名</td>
                <td>年齡</td>
            </tr>
            <tr v-for="item in students">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.age}}</td>
            </tr>
        </table>

後端開發

後端專案搭建

建立springboot專案,勾選依賴如下:
Developer Tools中的lombok
Web中的spring web
SQL中的Spring Data JPAMySQL Driver
最後,建好專案後刪掉resources資料夾中的application.properties檔案,因為此處用yml配置(在此資料夾下新建application.yml)
yml配置檔案如下:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/school?zhuguangliangDJB
    username: root
    password: 580231
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql: true
server:
  port: 8181

基本的後端專案建好後:

  1. 新建entity包,在該包下建立實體類(對應資料庫中的表)
  2. 為實體類加==@Entity註解(通過對映關係把類名與表名繫結,注意類名首字母小寫後與表明相同)和@Data==註解(自動引入get()、set()等方法)
  3. 為實體類中的主鍵元素加@Id註解,如:
    @Id
    private Integer id;
    
  4. 建立repository包,在該包下建立實體類介面
  5. 在該介面後繼承JpaRepository介面,泛型中傳入一個實體型別,一個主鍵型別。如:
    public interface StudentRepository extends JpaRepository<Student,Integer> {
    }
    
  6. 點選介面名右鍵選中“Go To”,然後點選“Great new Test”,直接預設選擇Junity5測試,OK完成,建立新的測試類(個人覺得這樣看起來比較規範化)
  7. 在test包下找到自動生成的該測試類,為該類加註解:@SpringBootTest
  8. 以將要測試的介面為引用,在此測試類中宣告一個變數,並加註解:@Autowired。如:
    @Autowired
    private StudentRepository studentRepository;
    
  9. 再在該類中寫一個測試方法,併為該方法新增一個註解:@Test。然後在該方法中通過介面變數訪問實體類中的元素及方法進行測試。如:
    @Test
    void findAll(){
        System.out.println(studentRepository.findAll());
    }
    

外部呼叫資料

新建一個controller包,在該包下建一個StudentHandler類
為該類加註解:@RestController@RequestMapping(“/student”),其中/student表示的是訪問路徑,一般用實體類名小寫表示。——訪問該類
同樣的再在該類中通過@Autowired進行注入。如:

@Autowired
    private StudentRepository studentRepository;
    //private  介面名 介面物件;

再通過@GetMapping("/findAll")返回資料,進行一個訪問結果的回饋。其中/findAll同樣為訪問的路徑。如:

@GetMapping("/findAll")
    public List<Student> findAll(){
        return studentRepository.findAll();
    }

——通過類方法返回具體資料

前後端整合

只需要讓前端想辦法用Ajax訪問對應的後端地址(如:localhost:8181/student/findAll)獲取資料即可。

  1. 現在Vue控制檯通過Vue add axios安裝axios.js,安裝成功後src目錄下會多出一個plugins資料夾,裡面會有一個axios.js檔案
  2. 在目標獲取資料的元件(Student.vue)的script中下寫一個created()函式,如:
    <script>
        export default {
            name: "Student",
            data(){
    	        return{
    		        students:[
    		        	{
    			        	id:0,
    			        	name:"",
    			        	age:0
    		        	}
    		        ]
    	        }
            },
            created() {
                const _this = this
                axios.get('http://localhost:8181/student/findAll').then(function (resp) {
                	//在此不能直接用 this.students = resp.data,因為此處的this指的不是vue物件,而是回撥
                    _this.students = resp.data
                })
            }
        }
    </script>
    

注意:
從前端埠傳送請求訪問後端埠,埠名不同會出現跨域問題,通過前後端都可以解決此問題
後端解決方案:
1. 在後端專案中新建config包,在包下建立CrosConfig類,並新增註解:@Configuration。
2. 在該類後繼承WebMvcConfigurer類,並重寫addCorsMappings方法,此方法重寫格式固定:

	@Override
    public void addCorsMappings(CorsRegistry registry){
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET","HEAD","POST","PUT","DELETE","OPTIONS")
                .maxAge(3600)
                .allowedHeaders("*")
                .allowCredentials(true); //是否有請求頭
    }
```

相關文章