1、環境搭建
在coding以前,咱們先把環境搭好,包括數據庫的安裝配置以及thinkjs的安裝配置。javascript
一、數據庫安裝css
本項目使用關係型數據庫MySQL,電腦上沒有安裝上MySQL的同窗能夠自行上官網下載安裝,有關MySQL的知識能夠上菜鳥教程和慕課網學習,這裏很少說。html
二、ThinkJS安裝前端
這裏咱們使用ThinkJS 2.2版本,因此如下步驟都是針對2.2版本,想使用3.0版本的同窗能夠自行嘗試。可直接使用npm進行安裝,參考官方文檔。安裝完成後便可建立項目。java
三、模版引擎安裝mysql
使用thinkjs命令建立好項目好,經過npm install安裝依賴項,而後能夠安裝模版引擎,這裏以nunjucks爲例,安裝命令以下:jquery
npm install nunjucks --save
2、項目配置
主要進行兩項配置,一是數據庫配置,二是模版引擎配置。ajax
一、數據庫配置sql
配置文件db.js所在目錄以下圖(2.2版本):數據庫
配置代碼以下圖:
二、模版引擎的配置
配置文件view.js所在目錄以下圖(2.2版本):
nunjucks配置代碼以下圖:
3、數據表建立
項目的開始咱們要設計數據表,咱們能夠只建立一個表think_tododemo,它包含三個鍵,參考代碼以下:
CREATE TABLE IF NOT EXISTS `think_tododemo`( `id` INT UNSIGNED AUTO_INCREMENT, `title` VARCHAR(100) NOT NULL, `done` INT UNSIGNED NOT NULL, PRIMARY KEY ( `id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
其中id用做編號,title爲每項事務的內容,done表示是否已經完成(0表示正在進行,1表示已經完成)。固然你能夠設計不一樣的數據表。
4、後端接口設計
因爲咱們要實現的todolist是單頁應用,因此只須要一個控制器,在裏面實現相應的接口方法便可。
一、home/index/indexAction
首先,咱們實現home模塊中index控制器的indexAction方法,參考代碼以下:
async indexAction(){ let model = this.model('tododemo'); //查詢正在進行的待辦項數據 let todoData = await model.where({done: 0}).select(); //查詢已經完成的待辦項數據 let doneData = await model.where({done: 1}).select(); //變量賦值,傳遞給view this.assign('todoList', todoData); this.assign('doneList', doneData); this.assign('todoCount', todoData.length); this.assign('doneCount', doneData.length); return this.display(); }
這樣訪問這個控制器方法就能夠把數據庫中的數據賦值到變量中,而且渲染view中對應的index_index.html。
二、home/index/addAction
而後咱們實現addAction這個方法,用於添加新的待辦項,參考代碼以下:
async addAction(){ let model = this.model('tododemo'); if(this.isPost()){ let item = this.post('title'); let insertItem = await model.add({ title: item, done: 0 }); if(!insertItem){ return this.fail(1000, '添加待辦項失敗!'); } else{ return this.success(); } } else { return this.fail(2000, 'post傳遞參數不存在!'); } }
當待辦項被正確添加到數據庫中,能夠經過this.success(data)返回數據,不然能夠經過this.fail(errno, errmsg)返回錯誤提示。
其餘須要實現的方法包括updateAction、removeAction、clearAction等等,請同窗們自行實現。
5、前端結構設計
在view目錄中,咱們實現HTML的結構設計,即home模塊下的index_index.html。在完成這一步以前,須要先學習一下模版引擎,好比咱們這裏要用到nunjucks。參考代碼以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ToDoList</title> <link rel="stylesheet" type="text/css" href="/static/css/index.css"> <script type="text/javascript" src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script> </head> <body> <header> <form action="javascript:add()" method="POST"> <label for="title">ToDoList</label> <button id="btn" class="btn" type="submit">提交</button> <input type="text" id="title" name="title" placeholder="添加ToDo"> </form> </header> <section> <h2>正在進行 <span id="todocount"> {{ todoCount }} </span> </h2> <ol id="todolist" class="list"> {% for item in todoList %} <li> <input type="checkbox" onchange="update({{ item.id }}, 1)" /> <p id="p-{{item.id}}" onclick="edit({{ item.id }})">{{ item.title }}</p> <a href="javascript:remove({{ item.id }})">-</a> </li> {% endfor %} </ol> <h2>已經完成 <span id="donecount"> {{ todoCount }} </span> </h2> <ul id="donelist" class="list"> {% for item in doneList %} <li> <input type="checkbox" onchange="update({{ item.id }}, 0)" /> <p id="p-{{item.id}}" onclick="edit({{ item.id }})">{{ item.title }}</p> <a href="javascript:remove({{ item.id }})">-</a> </li> {% endfor %} </ul> </section> <footer>Copyright © 2017 <a href="javascript:clear()">clear</a> </footer> <script type="text/javascript" src="/static/js/index.js"></script> </body> </html>
這裏要注意css和js文件的存放位置以及引用路徑,並且這裏用到了jQuery,因此同時須要引用jQuery。同窗們能夠自行添加不一樣的css樣式。
6、前端JavaScript方法設計
前端js文件存放在www/static/js目錄下(2.2版本),咱們要實現其中的方法,好比添加待辦項的add方法,參考代碼以下:
function add(){ var title = document.querySelector("#title"); if(title.value == ""){ alert("內容不能爲空"); } else{ var item = title.value; $.ajax({ url: '/home/index/add', type: 'POST', dataType: 'json', data: { title: item }, success: res => { if(!res.errno) { window.location.reload(); } else alert(res.errmsg); } }); } }
在參考代碼中,實際上只有當後端返回成功提示時,頁面纔會刷新顯示新添加的數據,這並非一種良好的交互設計,因此可想辦法使得提交新待辦項後前端頁面能夠及時更新而不用等後端響應。
這裏只實現了add方法,其餘方法請自行實現。
7、拓展功能
除了上述功能外,能夠按照本身的想法實現一些新功能,好比正在進行的列表項能夠拖拽改變它們的順序。