考試之前臨時趕工做了個馬原刷題工具,考試後有了時間順便把它拓展成了馬原毛概刷題工具,添加了隨機刷題,考試模擬,錯題本等功能,但平心而論,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
上,問題解決(唯一問題是我的伺服器沒有備案,所以只能手動輸入端口訪問)。