考試之前臨時趕工做了個馬原刷題工具,考試後有了時間順便把它拓展成了馬原毛概刷題工具,添加了隨機刷題,考試模擬,錯題本等功能,但平心而論,python的命令行程序還是不太易於使用,因此考慮將其改為網頁版本,目前該項目已經開源在了 github(在此前並沒有接觸過前端,所以可能會有很多不足之處)。
後端#
後端使用go的輕量 web 框架gin,代碼在這兒!
其通過讀取當前目錄的mayuan.json/maogai.json,根據不同的路由返回不同的結果:
| 訪問地址 | 返回結果 |
|---|---|
| /$subject/position/ | 返回該 subject 位置為 num 的題目 |
| /$subject/random/ | 返回該 subject 隨機一道題目 |
| /$subject/random/radio | 返回該 subject 隨機一道單選題目 |
| /$subject/random/checkbox | 返回該 subject 隨機一道多選題目 |
前端#
前端使用vue.js,準備學習的時候,在官方文檔中發現了這句話:
官方指南假設你已了解關於 HTML、CSS 和 JavaScript 的中級知識。如果你剛開始學習前端開發,將框架作為你的第一步可能不是最好的主意 —— 掌握好基礎知識再來吧!之前有其它框架的使用經驗會有幫助,但這不是必需的。
而我對前端知識一無所知,因此先去freecodecamp學習了HTML基礎和前幾節CSS(因為CSS內容實在是太多了!),然後去廖雪峰教程把JavaScript學到了函數部分,之後一邊參考官方文檔學習一邊上手開發。
首先使用webpack腳手架創建vue項目,接著安裝並引入muse-ui組件庫。
-
路由
import Vue from 'vue' import Router from 'vue-router' import index from '../components/index' import temp from '../components/temp' import exam from '../components/exam' import order from '../components/order' import about from '../components/about' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'index', component: index }, { path: '/馬原', name: 'mayuan', component: temp }, { path: '/毛概', name: 'maogai', component: temp }, { path: '/馬原/順序刷題', name: 'mayuanorder', component: order }, { path: '/毛概/順序刷題', name: 'maogaiorder', component: order }, { path: '/馬原/考試模擬', name: 'mayuanexam', component: exam }, { path: '/毛概/考試模擬', name: 'maogaiexam', component: exam }, { path: '/關於', name: 'about', component: about } ] }) -
組件
-
App.vue中寫入通用的頂欄,側邊欄等內容,監聽路由變化修改標題。 -
index.vue和about.vue使用純HTML/CSS寫成。 -
temp.vue用於選擇刷題方式。 -
order.vue為順序刷題界面,使用mu-pagination進行翻頁,exam.vue為考試模擬界面,使用mu-load-more實現題目部分加載。 -
question.vue為單位題目,是order.vue和exam.vue的子組件,監聽props中num的變化,調用getQuestion()加載相應題目並判斷是單選還是多選。在選擇選項時使用ifRight()判斷答案是否正確。// ifRight ifRight: function () { let answer if (this.isRadio === false) {// 多選將答案array排序並鏈接為字符串 answer = this.yourAnswer.sort().join("") } else {// 單選直接獲取 answer = this.yourAnswer } if (answer === this.question["Answer"]) { this.isRight = true let that = this if (this.timer) clearTimeout(this.timer) this.timer = setTimeout(function () {// 顯示2s的通知 that.isRight = false }, 2000) } else { this.isRight = false } } // getQuestion getQuestion () { this.yourAnswer=[] //根據父組件的path和當前num獲取要請求的地址 if (this.type === "/馬原/順序刷題") { this.url = "https://.../api/mayuan/position/" + (this.num - 1) } else if (this.type === "/毛概/順序刷題") { this.url = "https://.../api/maogai/position/" + (this.num - 1) } else if (this.type === "/馬原/考試模擬") { if (this.num <= 40) { this.url = "https://.../api/mayuan/random/radio" } else { this.url= "https://.../api/mayuan/random/checkbox" } } else if (this.type === "/毛概/考試模擬") { if (this.num <= 40) { this.url = "https://.../api/maogai/random/radio" } else { this.url = "https://.../api/maogai/random/checkbox" } } axios// 使用axios請求api獲取題目 .get(this.url) .then(response => { this.question = response.data if (this.question['Answer'].length > 1) {// 判斷是單選還是多選 this.isRadio = false } else { this.isRadio = true } }) }
-
部署#
在部署的時候遇到了不少問題。
開始在本地調試時發現無法加載出題目。查看chrome console中的錯誤信息,查詢後發現是因為後端沒有配置跨域,因此在後端路由中加上了:
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
調試正常,但部署到github pages後發現仍然無法加載,查看錯誤信息,得知在https網頁中不能加載http資源,因此任務變成了給gin加上https。
查閱發現一般方法是申請子域名和免費證書,但我懶得整那麼多了,正好手頭有個https域名,直接給nginx的當前server塊配個反向代理:
location /api{
proxy_pass http://localhost:8080;
}
然後在github pages中請求這個地址,但不知道是不是因為中間隔了個nginx,又出現了跨域問題,一時沒有查到解決方法,因此不得已把前端也部署在了nginx上,問題解決(唯一問題是我的伺服器沒有備案,所以只能手動輸入端口訪問)。