今天下了Vue,想試一試前后端分離的實現,沒想到坑還不少,這里就記錄一下我遇到的坑和我的代碼:
一、Vue的下載安裝:從網上找就好了,沒什么問題,除了下載以后,要把鏡像庫改成淘寶的,要不然太慢了。
二、推薦一個很好用的軟件 HBuilder X,可以在上面寫前端的項目,直接就能打開瀏覽器看到效果,還可以自動下載依賴。
三、前端代碼:
首先,先創建一個Vue項目,新建以后項目自帶的程序結構如圖:
因為我也是剛剛接觸vue,對里面的東西也不是很了解,只是從網上找了一些項目,邊看邊學,感覺里面重要的就是main.js、router還有components這三個,當然config里應該是配置文件,也很重要,但在這個初學的項目里,並沒有涉及太多里面的東西。
首先,先看一下main.js里面的東西:
里面的東西不多,可以看到大多數都是添加依賴,使用Vue.use()指定全局使用的包之類的功能。
這里一定要注意,比如這個程序添加了ElementUI這樣的外部依賴,那么一定要在這里用Vue.use()使用起來,表示全局都載入了這個庫,否則的話,在頁面顯示的時候,沒有內容,使用F12查看網頁代碼,會出現:
Unknown custom element: <xxx> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
這樣的提示,這時候就要檢查一下自己是否只是Import但是忘了use了。
接着看一下App.vue,這是項目的根組件:
在這里,我為了做測試,在上面加了一個啊咧,就會發現,不管跳轉到哪個頁面,頁面上都會有“啊咧”這兩個字,而另一方面,如果去掉下面的<router-view>的話,不管用什么訪問路徑,都只有這一個頁面,無法獲得其他頁面,也就是說其實這個App.vue,是程序的入口,在此基礎上,通過<router-view>來找到對應路徑的頁面,給予顯示。這有點像SpringBoot里面的Application,程序都是從那里開始啟動的。
最后,是Index.js,這里面規定了各個路徑對應的頁面,在這里,我已經寫好了兩個組件,一個是登錄的組件,一個是初始頁面:
這里,path就是配置的路徑名,而component對應着每一個組件,組件就可以表示一個頁面。
下面,就看一看登錄的頁面代碼:
這里主要參考了https://www.jianshu.com/p/4eecd628782a
import Vue from 'vue' import App from './App' import router from './router' import Element from 'element-ui' import VueResource from 'vue-resource' Vue.use(Element) <template> <div> <el-form :model="login" status-icon :rules="rule" ref="login"> <b>用戶名</b> <el-form-item prop="username" > <el-input prefix-icon="el-icon-ump-yonghu" v-model="login.username" auto-complete="off" /> </el-form-item> <b>密碼</b> <el-form-item prop="password"> <el-input prefix-icon="el-icon-ump-mima" type="password" v-model="login.password" auto-complete="off" /> </el-form-item> <el-form-item> <el-button class="btn" type="primary" @click="submitForm('login')">登錄</el-button> </el-form-item> </el-form> <p><a href="#" class="tips">還沒有賬號?點我去注冊</a></p> </div> </template> <script> export default { name: 'login', data() { var checkUsername = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入用戶名')); } else { callback(); } }; var checkPassword = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入密碼')); } else { callback(); } }; return { checked: false, token: '', login: { username: '', password: '' }, rule: { username: [{ validator: checkUsername, trigger: 'blur' } ], password: [{ validator: checkPassword, trigger: 'blur' }] } } }, methods: { submitForm(login){ this.$refs[login].validate((valid)=>{ if(valid){ this.$http.post('http://127.0.0.1:8080/login',{ username: this.login.username, password:this.login.password },{emulateJSON:true}).then(result =>{ console.log(result); if(result.bodyText ==='index'){ this.$router.push({path:'home'}); }else{ console.log("登錄失敗"); return false; } }); }else{ console.log("error submit!!"); return false; } }); }, }, } </script> <style> </style>
這個程序里面,有一些點需要說明:
①上面的<el-form>這樣的標簽,是在ElementUI里面的,所以一定要在main.js中使用Vue.use()來導入依賴
②對於 :model,他相當於v-bind和v-on的集合,它負責監聽用戶的輸入事件,從而更新數據,具體的解釋和實例可以參考:https://www.jianshu.com/p/20e485cb65d9
③:rules:用來添加對表單字段的檢驗,通常使用語法是:{validator:驗證方式,trigger:驗證觸發},如果是自己定義的驗證方式,應該傳入函數名,而不加參數。
④下面的methods里,要注意的就是post的地址不要出錯,不要寫localhost,寫127.0.0.1進行測試,端口號寫自己服務器端部署的端口號。
這樣子,前端就算完成了,可以運行了,但是我們看vue項目config下面的index.js(或者運行的時候,看命令行也可以),我們可以看到這樣的內容,項目運行的端口地址是8080,而這個又是服務器默認運行的端口,這兩個不可以在同一個端口上運行,所以必須修改一個端口,不妨把前端的端口改為8081:
其中,home的代碼,隨便寫一寫就好了:
<template> <div> <h2>這是主頁</h2> </div> </template> <script> export default{ name:"name" } </script> <style> </style>
四、后端代碼:
新建SpringBoot項目:在Controller層直接寫平常寫的代碼即可:
@RestController public class TestController { @CrossOrigin(origins = "*") @RequestMapping("/login") public String login( @RequestParam(value = "username", required = false) String username, @RequestParam(value = "password",required = false) String password, Model model ){ System.out.println("用戶名為"+username); System.out.println("密碼為"+password); if (username.equals("11")){ return "index"; }else{ return "login"; } } }
只不過要注意的就是 最上面的注解變成了@RestController:這個注解就是@Controller和在方法上加@ResponseBody的結合,這樣使得返回值自動寫入返回響應中,方便了前端讀取。
在部署的時候,第一個問題就是:
①:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package
這個是因為啟動的程序Application放的位置不對,應該把它放到,包含所有java文件的包下,而不能在java包下,比如這樣子放才是正確的姿勢
②:運行了以后,發現可以使用postMan傳送數據,但是卻接收不到來自前段的數據:這是因為前段的數據格式不是JSON的,要轉成JSON才可以接收到:
需要在傳送數據的時候,加上這樣一行:
③上面的寫完以后,后端接收到了數據,但是前端沒有反應:這時候,是因為跨域問題:詳細可以參見https://blog.csdn.net/xcbeyond/article/details/84453832
而SpringBoot的解決方案十分簡單:直接在方法上加@CrossOrigin()注解即可: