最近,因爲工做須要開始瞭解微信小程序,雖然小程序已經出了好久了,剛出的那段時間很火,看到不少關於小程序的技術文章,不過如今彷佛沒那麼火了,anyway,咱們仍是能夠學習下的。html
1.理念:小程序開發框架的目標是經過儘量簡單、高效的方式讓開發者能夠在微信中開發具備原生 APP 體驗的服務。
2.框架:框架的核心是一個響應的數據綁定系統。整個系統分爲兩塊視圖層(View)和邏輯層(App Service),框架可讓數據與視圖很是簡單地保持同步。當作數據修改的時候,只須要在邏輯層修改數據,視圖層就會作相應的更新。
3.相關資料:調試工具下載,簡易教程git
初步瞭解這些基本信息後,咱們先來看下TODOS這個應用作出來的最終效果github
功能演示:
json
目錄結構:
小程序
主要功能模塊爲:微信小程序
下面咱們詳細介紹下數組
{ "pages":[ "pages/index/index", // 設置頁面路徑,項目打開後找到這個路徑下的文件 "pages/logs/logs" ], "window":{ // 設置默認頁面的窗口表現 "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "TODOS", "navigationBarTextStyle":"black" }, "tabBar": { // 設置底部tab的表現 "borderStyle": "white", "backgroundColor": "#f5f5f5", "selectedColor": "#222", "list": [ // 對應底部下面兩個菜單項;TODOS和LOGS { "pagePath": "pages/index/index", "text": "TODOS", "iconPath": "images/home.png", "selectedIconPath": "images/home-actived.png" }, { "pagePath": "pages/logs/logs", "text": "LOGS", "iconPath": "images/note.png", "selectedIconPath": "images/note-actived.png" } ] } }
App() 函數用來註冊一個小程序。接受一個 object 參數,其指定小程序的生命週期函數等。App() 必須在 app.js 中註冊,且不能註冊多個。
示例代碼緩存
App({ onLaunch: function() { // Do something initial when launch. }, onShow: function() { // Do something when show. }, onHide: function() { // Do something when hide. }, onError: function(msg) { console.log(msg) }, globalData: 'I am global data' })
在這個項目中不須要加什麼代碼在App({})中,因此文件中只有一個App({})
app.wxss文件主要能夠設置一些全局樣式微信
page { height: 100%; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
Page() 函數用來註冊一個頁面。接受一個 object 參數,其指定頁面的初始數據、生命週期函數、事件處理函數等。網絡
// ===== 頁面數據對象 ===== data: { input: '', todos: [], leftCount: 0, allCompleted: false, logs: [], addOneLoading: false, loadingHidden: true, loadingText: '', toastHidden: true, toastText: '', clearAllLoading: false },
初始化數據做爲頁面的第一次渲染。data將會以JSON的形式由邏輯層傳至渲染層,其數據能夠是:字符串,數字,布爾值,對象,數組。
渲染層能夠經過WXML對數據進行綁定。
<input class="new-todo" value="{{ input }}" placeholder="Anything here..." auto-focus bindinput="inputChangeHandle" bindchange="addTodoHandle"/>
如上述代碼中的input.
// ===== 頁面生命週期方法 ===== onLoad: function () { // 從緩存獲取任務列表數據,並用setData設置 var todos = wx.getStorageSync('todo_list') // 調用 WX API 從本地緩存中獲取數據 if (todos) { var leftCount = todos.filter(function (item) { return !item.completed }).length this.setData({ todos: todos, leftCount: leftCount }) } // 設置logs數據 var logs = wx.getStorageSync('todo_logs') if (logs) { this.setData({ logs: logs }) } },
addTodoHandle: function (e) { if (!this.data.input || !this.data.input.trim()) return this.setData( { addOneLoading: true }); //open loading this.setData( { loadingHidden: false, loadingText: 'Waiting...' }); var todos = this.data.todos todos.push({ name: this.data.input, completed: false }) var logs = this.data.logs logs.push({ timestamp: new Date().toLocaleString(), action: '新增', name: this.data.input }) this.setData({ input: '', todos: todos, leftCount: this.data.leftCount + 1, logs: logs }) this.save() }, save: function () { wx.setStorageSync('todo_list', this.data.todos) wx.setStorageSync('todo_logs', this.data.logs) //close loading and toggle button loading status var self = this; setTimeout( function() { self.setData( { loadingHidden: true, addOneLoading: false, loadingText: '' }); }, 100); },
主要把時間new Date().toLocaleString(), action:'新增',事件名 name: this.data.input這三個字段push到todos這個data數據中;而後在save()中經過wx.setStorageSync('todo_list', this.data.todos)設置緩存。
toggleTodoHandle: function (e) { var index = e.currentTarget.dataset.index var todos = this.data.todos todos[index].completed = !todos[index].completed var logs = this.data.logs logs.push({ timestamp: new Date().toLocaleString(), action: todos[index].completed ? '標記完成' : '標記未完成', name: todos[index].name }) this.setData({ todos: todos, leftCount: this.data.leftCount + (todos[index].completed ? -1 : 1), logs: logs }) this.save() },
var index = e.currentTarget.dataset.index 獲取當前索引,對應的wxml代碼爲:
<view class="item{{ item.completed ? ' completed' : '' }}" wx:for="{{ todos }}" wx:key="{{ index }}" bindtap="toggleTodoHandle" data-index="{{ index }}"> <!-- completed: success, todo: circle --> <icon class="checkbox" type="{{ item.completed ? 'success' : 'circle' }}"/> <text class="name">{{ item.name }}</text> <icon class="remove" type="clear" size="16" catchtap="removeTodoHandle" data-index="{{ index }}"/> </view>
bindtap: 當用戶點擊該組件的時候會在該頁面對應的Page中找到相應的事件處理函數
最後考慮到了loading的效果,要利用button組件的loading屬性來實現。可是loading僅僅是一個樣式的控制,它不會控制這個按鈕是否能重複點擊。因此還要利用button的disabled屬性,防止重複點擊。
<button type="primary" size="mini" bindtap="addTodoHandle" loading="{{addOneLoading}}" disabled="{{addOneLoading}}"> + Add </button>
js:
loadingChange: function() { this.setData({ loadingHidden: true, loadingText: '' }); }, toastChange: function() { this.setData( { toastHidden: true, toastText: '' }); }
LOGS頁面比較簡單,主要經過var logs = wx.getStorageSync('todo_logs')
獲取logs列表,而後在頁面渲染,這裏就不貼代碼了。
至此,基本瞭解了TODOS應用的構建過程,經過代碼詳解、參考微信小程序官方文檔瞭解了微信自家開發的視圖層描述語言WXML和WXSS,以及基於 JavaScript 的邏輯層框架;與HTML頁面結構類似,對應HTML,CSS,JAVASCRIPT; 因此學習起來比較容易。不過僅僅經過這個TODOS應用,還只是瞭解小程序這個平臺的一些基本用法。複雜一點,頁面跳轉,網絡請求等都須要咱們去實踐,才能對小程序瞭解得更多。
完整代碼:
源代碼
參考資料:
1.https://github.com/zce/weapp-todos
2.http://www.cnblogs.com/lyzg/p/5906496.html