微信小程序開發(fā)概述
由于微信的使用人數(shù)眾多拍埠,因此微信小程序也受到許多企業(yè)公司的推崇秸抚。除此之外小程序還有開發(fā)簡單容易豌蟋,用戶流量較大的優(yōu)點(diǎn)廊散,因此學(xué)習(xí)小程序還是很有意義的。
開發(fā)入門
瀏覽器環(huán)境的前端html梧疲、css允睹、js分別對應(yīng)于微信中的wxml、wxss幌氮、js文件缭受。與瀏覽器環(huán)境不同的是每個頁面(Page)和整個應(yīng)用(App)都有對應(yīng)名稱的json文件用于配置,project.config.json文件用于開發(fā)環(huán)境的配置该互。
WXML
wxml(WeiXin Markup Language)是框架設(shè)計(jì)的一套標(biāo)簽語言米者,結(jié)合基礎(chǔ)組件、事件系統(tǒng)宇智,可以構(gòu)建出頁面的結(jié)構(gòu)蔓搞。
數(shù)據(jù)綁定
wxml頁面數(shù)據(jù)綁定使用雙括號的形式
<view data-ml="{{a}}"> {{a + b}} + {{c}} + d </view>
數(shù)據(jù)是單向綁定的,只有通過setData方法改變Page的data對象中的屬性才能改變頁面中對應(yīng)表達(dá)式中的值
條件渲染與列表渲染
條件渲染與列表渲染相當(dāng)于随橘,vue中的組件
條件渲染
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
wx:if是惰性的喂分,如果在初始渲染條件為 false,框架什么也不做机蔗,在條件第一次變成真的時候才開始局部渲染蒲祈。
相比之下,hidden 就簡單的多蜒车,組件始終會被渲染讳嘱,只是簡單的控制顯示與隱藏。
列表渲染
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName" wx:key="message">
{{idx}}: {{itemName.message}}
</view>
如果列表中項(xiàng)目的位置會動態(tài)改變或者有新的項(xiàng)目添加到列表中酿愧,并且希望列表中的項(xiàng)目保持自己的特征和狀態(tài)(如 <input/>
中的輸入內(nèi)容沥潭,<switch/>
的選中狀態(tài)),需要使用 wx:key 來指定列表中項(xiàng)目的唯一的標(biāo)識符嬉挡。
wx:key的兩種值:字符串代表item中的某個熟悉;*this代表循環(huán)中的item本身
template
template定義的模板可以在任意地方引用
<!-- template.wxml -->
<template name="odd">
<view> odd </view>
</template>
<template name="even">
<view> even </view>
</template>
<!-- index.wxml -->
<block wx:for="{{[1, 2, 3, 4, 5]}}">
<template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
</block>
include可以將目標(biāo)文件除了<template/>
的整個代碼引入钝鸽,相當(dāng)于是拷貝到include位置
<!-- index.wxml -->
<include src="header.wxml"/>
<!-- header.wxml -->
<view> header </view>
import可以在該文件中使用目標(biāo)文件定義的template
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
相比于include使用import可以設(shè)置數(shù)據(jù)
import具有作用域的概念,C導(dǎo)入B庞钢,B導(dǎo)入A拔恰。C中只能獲取B中的模板,而不能獲取B中導(dǎo)入的A中的基括。
WXSS
wxss是小程序用于描述頁面的樣式語言颜懊,該語言與css基本相同。
新增加了rpx(responsive pixel)響應(yīng)式單位,該單位可以根據(jù)屏幕寬度進(jìn)行自適應(yīng)河爹。
樣式導(dǎo)入@import "common.wxss";
模塊化
導(dǎo)出模塊可以使用CommonJS機(jī)制和ES6的模塊機(jī)制
CommonJS
每個js模塊都在自己的作用域中匠璧,導(dǎo)出模塊需要使用exports或module.exports
導(dǎo)入使用require,但是不支持絕對路徑。
ES6
使用ES6的模塊機(jī)制導(dǎo)出模塊咸这,導(dǎo)入使用import...from等關(guān)鍵字夷恍,導(dǎo)出使用export default關(guān)鍵字
路由分類
路由是指導(dǎo)航到頁面的方式,路由的種類有:navigateTo媳维、redirectTo酿雪、switchTab、reLaunch侄刽、navigateBack
除了navigateTo指黎、switchTab的方式是隱藏當(dāng)前頁面其他的方式都會卸載當(dāng)前頁面。
navigateTo, redirectTo 只能打開非 tabBar 頁面唠梨。
switchTab 只能打開 tabBar 頁面袋励。
reLaunch 可以打開任意頁面。
具體見表路由
事件分類
小程序中事件分為冒泡和非冒泡兩種類型当叭。
事件的生命周期階段與瀏覽器中相同都是先捕獲后冒泡茬故。
綁定事件的方式
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
inner view
</view>
</view>
</view>
- bind事件發(fā)生在冒泡階段,且不阻止事件向上冒泡
- capture-bind事件發(fā)生在捕獲階段蚁鳖,且不阻止事件捕獲
- catch事件發(fā)生在冒泡階段磺芭,阻止事件向上冒泡
- capture-catch事件發(fā)生在捕獲階段,阻止事件捕獲
組件
小程序提供了許多組件醉箕,常見的有:
- view相當(dāng)于div
- text相當(dāng)于span
- navigator相當(dāng)于a
- image相當(dāng)于img
- canvas相當(dāng)于canvas
- contact-button客戶會話钾腺,從此處發(fā)送的消息,會在微信小程序后臺接收到
小程序中表單form組件不同于瀏覽器的地方是讥裤,無法像瀏覽器一樣通過給表單配置action讓頁面直接跳轉(zhuǎn)放棒。需要對表單設(shè)置submit事件,在submit中獲取數(shù)據(jù)處理跳轉(zhuǎn)邏輯己英,要獲取數(shù)據(jù)表單項(xiàng)必須要有name屬性间螟,這點(diǎn)與瀏覽器中一致。
小程序中的button除了像瀏覽器中一樣可以通過form-type屬性設(shè)置為submit损肛、reset與表單相關(guān)的按鈕之外厢破。
還可以通過設(shè)置open-type屬性設(shè)置為特別的按鈕:
- contact(打開客服會話)
- share(觸發(fā)用戶轉(zhuǎn)發(fā))
- getUserInfo(獲取用戶信息,可以在bindgetuserinfo回調(diào)中取到用戶信息)
- getPhoneNumber(獲取用戶手機(jī)號治拿,可以從bindgetphonenumber中取得)
一些細(xì)節(jié)
小程序中阻止事件冒泡摩泪,使用的是catchXX方法(事件還分為冒泡和非冒泡兩種)
沒有阻止默認(rèn)行為的方法
使用wx.canvasToTempFilePath方法生成圖片,如果canvas使用圖片進(jìn)行了繪制劫谅,那圖片必須是本地圖片见坑。而且在微信基礎(chǔ)庫版本1.5.4下嚷掠,使用本地圖片需要導(dǎo)出兩次才能在開發(fā)者工具上的canvas看到圖片
wx.downloadFile({
url: url,
success: function (res) {
// console.log('下載圖片文件')
// console.log(res)
ctx.drawImage(res.tempFilePath, left, top, width, height);
ctx.draw();
wx.canvasToTempFilePath({
canvasId: 'photoid',
success(res) {
wx.canvasToTempFilePath({
canvasId: 'photoid',
success(res) {
//...
}
});
}
})
}
})