小程式開發-開發實戰基礎
3.2 小程式之WXML 模板(常用)
- 具體詳情請檢視:微信公眾平臺-小程式-元件https://developers.weixin.qq.com/miniprogram/dev/component/
view
檢視容器
- 相當於
div
<view class="flex-item bc_green">1</view>
- 相當於
scroll-view
可滾動檢視區域- 相當於 允許橫向滾動,允許縱向滾動
div
,滑塊做法
<scroll-view scroll-y
- 相當於 允許橫向滾動,允許縱向滾動
swiper
滑塊檢視容器- 輪播圖元件
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
text
文字
- 相當於
span
<text class="page__title">image</text>
- 相當於
- 表單元件
- button
- checkbox
- form
- input
- label
- picker——普通選擇器,時間選擇器,日期選擇器,預設是普通選擇器
- picker-view——嵌入頁面的滾動選擇器
- radio
- slider——滑動選擇器
- switch——開關選擇器。
- textarea
- navigator 頁面連結。
- 相當於
a
標籤,可以跳轉頁面也可以跳轉新的小程式
open-type
跳轉方式
navigate
(預設) 保留當前跳轉,跳轉後可以返回當前頁(頁面左上角有一個<
可以返回上一頁),它與wx.navigateTo跳轉效果是一樣的;
<navigator url="/page/navigate/navigate?title=navigate">跳轉到新頁面</navigator>
<navigator target="miniProgram" open-type="navigate" app-id="" path="" extra-data="" version="release">開啟繫結的小程式</navigator>
redirect
關閉當前頁跳轉,是無法返回當前頁,它與wx.redirrectTO跳轉效果是一樣的;
<navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect" hover-class="other-navigator-hover">在當前頁開啟</navigator>
switchTab
跳轉底部標籤導航指定的頁面,它與wx.switchTab跳轉效果是一樣的;
- 我們可以設定底部和頂部導航,這時候跳轉到導航的連結就必須是
switchTab
; <navigator url="/page/index/index" open-type="switchTab" hover-class="other-navigator-hover">切換 Tab</navigator>
- 我們可以設定底部和頂部導航,這時候跳轉到導航的連結就必須是
- image 圖片。
- 相當於
img
標籤
<image style="width: 200px; height: 200px; background-color: #eeeeee;" mode="{{item.mode}}" src="{{src}}"></image>
- 相當於
3.3 小程式之WXSS 樣式
- 單位:一般我們做WEB前端頁面都是都是使用px(畫素)做單位的,那麼做小程式怎麼辦呢?
- 小程式的設計稿的寬都是750px,也就是市場上面流行的ip6,7,8的大小,WXSS 在底層支援新的尺寸單位 rpx, ;
- rpx(responsive pixel): 可以根據螢幕寬度進行自適應。規定螢幕寬為750rpx。
- 所以換算比例為1:1,例如設計稿上是66px的高,那麼小程式上面設定的高則是:66rpx;
3.4 小程式之WXML 模板 進階
簡單繫結
- 資料繫結使用 Mustache 語法(雙大括號)將變數包起來,可以作用於:
- 內容
<!-- index.wxml --> <view> {{ message }} </view>
//index.js Page({ data: { message: 'Hello MINA!' } })
- 元件屬性(需要在雙引號之內)
<!-- index.wxml --> <view id="item-{{id}}"> </view>
//index.js Page({ data: { id: 0 } })
總結: 我們在.js裡面的page()-data定義物件,例 "id:0",就可以在頁面上{{id}},輸出0, 還可以在後面的js程式碼中繫結事件,動態改變 data定義物件 的值,頁面的值就相應改變了; WEB的js程式碼需要找到元素,找到值,再給元素賦值,比較麻煩; 而小程式的js就一開始綁定了變數,然後再js裡面改變變數,然後頁面就可以相應改變了,省去了找元素這一步驟。
列表渲染 - wx:for
- 在元件上使用 wx:for 控制屬性繫結一個數組,即可使用陣列中各項的資料重複渲染該元件。
- 預設陣列的當前項的下標變數名預設為 index,陣列當前項的變數名預設為 item
<!-- index.wxml --> <view wx:for="{{array}}"> {{index}}: {{item.message}} </view>
//index.js Page({ data: { array: [{ message: 'foo', }, { message: 'bar' }] } })
- 使用 wx:for-item 可以指定陣列當前元素的變數名,使用 wx:for-index 可以指定陣列當前下標的變數名:
<!-- index.wxml --> <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"> {{idx}}: {{itemName.message}} </view>
wx:for 也可以巢狀,下邊是一個九九乘法表
<!-- index.wxml --> <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i"> <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j"> <view wx:if="{{i <= j}}"> {{i}} * {{j}} = {{i * j}} </view> </view> </view>
- block wx:for (注意:
<block/>
並不是一個元件,它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。) - 類似 block wx:if,也可以將 wx:for 用在標籤上,以渲染一個包含多節點的結構塊。例如:
<!-- index.wxml --> <block wx:for="{{[1, 2, 3]}}"> <view> {{index}}: </view> <view> {{item}} </view> </block>
總結: wx:for 列表渲染 相當於PHP的foreach迴圈,大同小異 php: foreach($data => $key => $value){ echo $key.'=>'.$value; } ThinkPHP 3.2 <volist name="data" id="value"> {$key}:{$value} </volist> ThinkPHP 5 {volist name="data" id="value"} {$key}:{$value} {/volist} 小程式: <view wx:for="{{data}}" wx:for-index="key" wx:for-item="value"> {{key}}: {{value}} </view>
條件渲染 - wx:if
- 在框架中,使用 wx:if=”{{condition}}” 來判斷是否需要渲染該程式碼塊:
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif 和 wx:else 來新增一個 else 塊:
<view wx:if="{{length > 5}}"> 1 </view> <view wx:elif="{{length > 2}}"> 2 </view> <view wx:else> 3 </view>
block wx:if
因為 wx:if 是一個控制屬性,需要將它新增到一個標籤上。如果要一次性判斷多個元件標籤,可以使用一個
<block/>
標籤將多個元件包裝起來,並在上邊使用 wx:if 控制屬性。<block wx:if="{{true}}"> <view> view1 </view> <view> view2 </view> </block>
注意:
<block/>
並不是一個元件,它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。
模板
- WXML提供模板(template),可以在模板中定義程式碼片段,然後在不同的地方呼叫。
- 定義模板
- 使用 name 屬性,作為模板的名字。然後在內定義程式碼片段,如:
<!-- index: int msg: string time: string --> <template name="msgItem"> <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template>
使用模板
- 使用 is 屬性,宣告需要的使用的模板,然後將模板所需要的 data 傳入,如:
<template is="msgItem" data="{{...item}}"/>
Page({ data: { item: { index: 0, msg: 'this is a template', time: '2016-09-15' } } })
- is 屬性可以使用 Mustache 語法,來動態決定具體需要渲染哪個模板:
<template name="odd"> <view> odd </view> </template> <template name="even"> <view> even </view> </template>
<block wx:for="{{[1, 2, 3, 4, 5]}}"> <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/> </block>
- 模板的作用域
- 模板擁有自己的作用域,只能使用 data 傳入的資料以及模版定義檔案中定義的 模組。
- 使用 is 屬性,宣告需要的使用的模板,然後將模板所需要的 data 傳入,如:
事件
什麼是事件
- 事件是檢視層到邏輯層的通訊方式。
- 事件可以將使用者的行為反饋到邏輯層進行處理。
- 事件可以繫結在元件上,當達到觸發事件,就會執行邏輯層中對應的事件處理函式。
- 事件物件可以攜帶額外資訊,如 id, dataset, touches。
事件的使用方式
- 點選事件
bindtap="tapName"
,在標籤上面繫結事件
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
Page({ //點選 上面的 view 即可觸發 tapName 函式 tapName: function(event) { console.log(event) } })
- 點選事件
3.6 引用
- WXML 提供兩種檔案引用方式import和include。
import
- import可以在該檔案中使用目標檔案定義的template,如:
- 在 item.wxml 中定義了一個叫item的template:
<!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template>
- 在 index.wxml 中引用了 item.wxml,就可以使用item模板:
<import src="item.wxml"/> <template is="item" data="{{text: 'forbar'}}"/>
include
- include 可以將目標檔案除了 外的整個程式碼引入,相當於是拷貝到 include 位置,如:
<!-- index.wxml --> <include src="header.wxml"/> <view> body </view> <include src="footer.wxml"/>
<!-- header.wxml --> <view> header </view>
<!-- footer.wxml --> <view> footer </view>
3.5 WXS
- WXS(WeiXin Script)是小程式的一套指令碼語言,結合 WXML,可以構建出頁面的結構。
- WXS開發手冊:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/
- 注意(來自官方文件)
- wxs 不依賴於執行時的基礎庫版本,可以在所有版本的小程式中執行。
- wxs 與 javascript 是不同的語言,有自己的語法,並不和 javascript 一致。
- wxs 的執行環境和其他 javascript 程式碼是隔離的,wxs 中不能呼叫其他 javascript 檔案中定義的函式,也不能呼叫小程式提供的API。
- wxs 函式不能作為元件的事件回撥。
- 由於執行環境的差異,在 iOS 裝置上小程式內的 wxs 會比 javascript 程式碼快 2 ~ 20 倍。在 android 裝置上二者執行效率無差異。
- 和js差不多,一般開發過程中都是使用.js寫邏輯
- 在開發微信小程式的時候,應該根據情況,選擇使用js或wxs。
- wxs是專門用於wxml頁面的。
- wxs和js不能互相直接呼叫。
- 有的事情,用wxs和js都能實現,但是你會發現用wxs更方便、直接。
- 案例連結:https://www.jianshu.com/p/097d47a83d5e
3.5 常用API
- 框架提供豐富的微信原生API,可以方便的調起微信提供的能力,如獲取使用者資訊,本地儲存,支付功能等。
- 說明:
- wx.on 開頭的 API 是監聽某個事件發生的API介面,接受一個 CALLBACK 函式作為引數。當該事件觸發時,會呼叫 CALLBACK 函式。
- 如未特殊約定,其他 API 介面都接受一個OBJECT作為引數。
- OBJECT中可以指定success
介面呼叫成功的回撥函式
, fail介面呼叫失敗的回撥函式
, complete介面呼叫結束的回撥函式(呼叫成功、失敗都會執行)
來接收介面呼叫結果。
3.5.0 小程式的生命週期-頁面載入順序
小程式的生命週期——App.js
- App() 必須在 app.js 中註冊,且不能註冊多個。所以App()方法在一個小程式中有且僅有一個。
App() 函式用來註冊一個小程式。接受一個 object 引數,其指定小程式的生命週期函式等。先上程式碼:
App({ onLaunch: function () { console.log('App onLaunch'); //當小程式初始化完成時,會觸發 onLaunch(全域性只觸發一次)。 }, onShow:function (){ console.log('App onShow'); //當小程式啟動,或從後臺進入前臺顯示,會觸發 onShow }, onHide:function(){ console.log('App onHide'); //當小程式從前臺進入後臺,會觸發 onHide }, onError:function(){ console.log('App onError'); 小程式發生指令碼錯誤,或者 api 呼叫失敗時,會觸發 onError 並帶上錯誤資訊 } });
總結:將原有的app.js中替換為上面的程式碼,首次開啟小程式,可以在Log資訊中看到以下Log資訊,會看到onShow()方法會執行兩次
App onLaunch App onShow() App onShow()
頁面的生命週期
- Page() 函式用來註冊一個頁面。接受一個 object 引數,其指定頁面的初始資料、生命週期函式、事件處理函式等。
- 生命週期函式
onLoad: 頁面載入 * 一個頁面只會呼叫一次。 * 接收頁面引數 可以獲取wx.navigateTo和wx.redirectTo及<navigator/>中的 query。 onShow: 頁面顯示 * 每次開啟頁面都會呼叫一次。 onReady: 頁面初次渲染完成 * 一個頁面只會呼叫一次,代表頁面已經準備妥當,可以和檢視層進行互動。 onHide: 頁面隱藏 當navigateTo或底部tab切換時呼叫。 onUnload: 頁面解除安裝 當redirectTo或navigateBack的時候呼叫。
- 總結
在app.js裡面的 onLaunch 寫整個專案都會呼叫到的邏輯以及一些初始化操作,例如,小程式背景音樂的播放控制等;
在頁面的.js檔案 呼叫 onLoad 接收引數,呼叫介面,獲取資料,更新渲染頁面;
每次開啟頁面,都會觸發 onShow ,所以做購物車的時候,購物車資訊要經常更新,就可以在頁面的.js檔案 呼叫 onShow 查詢購物車,並顯示;
3.5.1 wx.request 發起網路請求
-相當於AJAX、相當於介面開發。
- 例:
wx.request({
url: 'https://api.001php.com/api?url=page_class',//開發者伺服器介面地址
method: 'POST',//預設:GET,(需大寫)有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
dataType: 'json',//json, 如果設為json,會嘗試對返回的資料做一次 JSON.parse
data: {id:1},//請求的引數
header: {
"Content-Type": "application/x-www-form-urlencoded" //設定請求的 header,header 中不能設定 Referer。
},
//成功後的回撥
success: function (res) {
// console.log(res.data) //列印返回資料
//把返回資料存為 data 變數,直接可以在頁面上顯示輸出
that.setData({
list: res.data
})
}
})
//注:header使用什麼"Content-Type"?
//application/x-www-form-urlencoded : 通過頁面表單方式提交
//application/json : json(要反序列化成字串),php不能直接解析json字串
//所以我們做小程式介面,都有重新設定 header Content-Type 為: application/x-www-form-urlencoded
3.5.2 介面-互動反饋-彈出提示框
顯示訊息提示框:wx.showToast(OBJECT)
- 示例程式碼:
wx.showToast({ title: '登陸成功',//提示的內容 icon: 'success',//圖示,有效值 "success", "loading", "none" duration: 2000,//提示的延遲時間,單位毫秒,預設:1500 mask:true,// 是否顯示透明蒙層,防止觸控穿透,預設:false success:function(res){ //介面呼叫成功的回撥函式 wx.hideToast()//隱藏訊息提示框 } })
- 示例程式碼:
- 隱藏訊息提示框:wx.hideToast()
- 一般是顯示提示框介面呼叫成功的時候隱藏
顯示 loading 提示框:wx.showLoading(OBJECT),需主動呼叫 wx.hideLoading 才能關閉提示框
- 示例程式碼:
wx.showLoading({ title: '請選擇地址',//提示的內容 mask:true,// 是否顯示透明蒙層,防止觸控穿透,預設:false success:function(res){ //介面呼叫成功的回撥函式 } })
- 示例程式碼:
- 隱藏 loading 提示框 - wx.hideLoading()
- 一般是發起網路請求介面的時候呼叫
顯示 loading 提示框
,再在網路請求完成後,呼叫,wx.hideLoading()
,隱藏loading
- 一般是發起網路請求介面的時候呼叫
顯示模態彈窗:wx.showModal(OBJECT)
- 示例程式碼:
wx.showModal({ title: '刪除圖片', content: '確定要刪除該圖片?', showCancel: true,//是否顯示取消按鈕 cancelText:"否",//預設是“取消” cancelColor:'skyblue',//取消文字的顏色 confirmText:"是",//預設是“確定” confirmColor: 'skyblue',//確定文字的顏色 success: function (res) { if (res.cancel) { //點選取消,預設隱藏彈框 } else { //點選確定 temp.splice(index, 1), that.setData({ tempFilePaths: temp, }) } }, fail: function (res) { },//介面呼叫失敗的回撥函式 complete: function (res) { },//介面呼叫結束的回撥函式(呼叫成功、失敗都會執行) })
- 示例程式碼:
3.5.3 導航-跳轉頁面
- wx.navigateTo(OBJECT)
- 保留當前頁面,跳轉到應用內的某個頁面,使用wx.navigateBack可以返回到原頁面。
- 示例程式碼:
wx.navigateTo({
url: 'test?id=1'
})
wx.redirectTo(OBJECT)
關閉當前頁面,跳轉到應用內的某個頁面。
示例程式碼:
wx.redirectTo({ url: 'test?id=1' })
wx.reLaunch(OBJECT)
- 關閉所有頁面,開啟到應用內的某個頁面。
- 示例程式碼:
wx.reLaunch({ url: 'test?id=1' }) wx.switchTab(OBJECT) 跳轉到 tabBar 頁面,並關閉其他所有非 tabBar 頁面 wx.switchTab({ url: '/index' })
wx.navigateBack(OBJECT)
- 關閉當前頁面,返回上一頁面或多級頁面。可通過 getCurrentPages()) 獲取當前的頁面棧,決定需要返回幾層。
- 示例程式碼:
// 注意:呼叫 navigateTo 跳轉時,呼叫該方法的頁面會被加入堆疊,而 redirectTo 方法則不會。見下方示例程式碼 // 此處是A頁面 wx.navigateTo({ url: 'B?id=1' }) // 此處是B頁面 wx.navigateTo({ url: 'C?id=1' }) // 在C頁面內 navigateBack,將返回A頁面 wx.navigateBack({ delta: 2 }) // 如果是在C頁面內 navigateBack,將返回B頁面 wx.navigateBack()
Tip
- tip: wx.navigateTo 和 wx.redirectTo 不允許跳轉到 tabbar 頁面,只能用 wx.switchTab 跳轉到 tabbar 頁面
3.5.4 快取
- 關於本地快取
1.wx.setStorage(wx.setStorageSync)、wx.getStorage(wx.getStorageSync)、wx.clearStorage(wx.clearStorageSync)可以對本地快取進行設定、獲取和清理。本地快取最大為10MB
2.localStorage 是永久儲存 一、非同步快取
設定非同步快取:wx.setStorage(OBJECT)
- 將資料儲存在本地快取中指定的 key 中,會覆蓋掉原來該 key 對應的內容
wx.setStorage({ key:"key", data:"value" })
獲取非同步快取:wx.getStorage(OBJECT)
- 從本地快取中非同步獲取指定 key 對應的內容。
wx.getStorage({ key: 'key', success: function(res) { console.log(res.data) } })
wx.getStorageInfo(OBJECT)
- 非同步獲取當前storage的相關資訊
wx.getStorageInfo({ success: function(res) { console.log(res.keys) console.log(res.currentSize) console.log(res.limitSize) } })
wx.removeStorage(OBJECT)
- 從本地快取中非同步移除指定 key 。
wx.removeStorage({ key: 'key', success: function(res) { console.log(res.data) } })
- 二、同步快取
- 設定同步快取:wx.setStorageSync(KEY,DATA)
- 將 data 儲存在本地快取中指定的 key 中,會覆蓋掉原來該 key 對應的內容,這是一個同步介面。
- 獲取同步快取:wx.getStorageSync(KEY)
- 從本地快取中同步獲取指定 key 對應的內容。
- wx.getStorageInfoSync
- 同步獲取當前storage的相關資訊
- wx.removeStorageSync(KEY)
- 從本地快取中同步移除指定 key 。
- 設定同步快取:wx.setStorageSync(KEY,DATA)
- 三、清理快取
- wx.clearStorage():清理本地資料快取。
- wx.clearStorageSync():同步清理本地資料快取
- 四、關於同步快取和非同步快取的區別
- 以Sync(同步,同時)結尾的都是都是同步快取,二者的區別是,非同步不會阻塞當前任務,同步快取直到同步方法處理完才能繼續往下執行。
- 但是一般情況下不要用清除所有的快取,如果想要清除相應的快取,設定對應的快取內容為空陣列就好