微信專(zhuān)門(mén)為小程序開(kāi)發(fā)了一個(gè)ide叫做微信開(kāi)發(fā)者工具
最新一版的微信開(kāi)發(fā)者工具,把微信公眾號(hào)的調(diào)試開(kāi)發(fā)工作也集成了進(jìn)去,可以更換開(kāi)發(fā)模式。

https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html
選擇無(wú)appid,即可在沒(méi)有appid情況下進(jìn)行開(kāi)發(fā),但是無(wú)法預(yù)覽;

二 基本架構(gòu)和配置文件
1.小程序架構(gòu)
小程序主要由兩個(gè)部分構(gòu)成,主體部分 (app)和各個(gè)頁(yè)面(page)。
類(lèi)似于許多框架,主體部分主要用于核心的配置,各個(gè)頁(yè)面主要用于不同業(yè)務(wù)場(chǎng)景。
app,就是小程序的框架。支撐pages,邏輯層的調(diào)用,對(duì)數(shù)據(jù),wxss,wxml的解析;
page,主要是業(yè)務(wù)層,用于實(shí)現(xiàn)界面化操作功能,是程序員使用頻率最高的部分。
1.1,主體部分主要由3個(gè)文件構(gòu)成
三個(gè)app文件分別是app.js,app.json,app.wxss。
app.js文件是腳本文件處理一些公共的或者全局的邏輯。比如在這里定義全局變量處理登錄邏輯指定首頁(yè)等。
app.json文件是小程序的整體配置文件。我們必須要在這個(gè)文件中配置小程序是由哪些頁(yè)面組成的,我們還可以在這個(gè)文件中配置整個(gè)小程序的統(tǒng)一的窗口 背景色,導(dǎo)航條 樣式,默認(rèn)標(biāo)題。但是必須注意該文件不可添加任何注釋。
app.wxss文件是整個(gè)小程序的公共樣式表。我們可以在小程序子頁(yè)面組件的 class 屬性上直接使用 app.wxss 中聲明的樣式規(guī)則。也就是說(shuō)在這個(gè)文件里定義的樣式在其他任何的子頁(yè)面中都可以使用。這個(gè)也是為了代碼的簡(jiǎn)潔和整體風(fēng)格的統(tǒng)一。
1.2,頁(yè)面由4個(gè)文件構(gòu)成
小程序的所有顯示的頁(yè)面都必須以子文件夾的形式存放在pages文件夾里面,包括首頁(yè)。項(xiàng)目展示多少個(gè)頁(yè)面,在pages文件夾下就要新建多少個(gè)子文件夾。每個(gè)頁(yè)面的子文件夾,必須包括這四個(gè)文件:*.js , *.wxml , *.wxss 和 *.json(* 表示文件名)。這四個(gè)文件的文件名必須和子文件夾的名字一樣。
*.js文件是當(dāng)前頁(yè)面腳本文件,也是業(yè)務(wù)邏輯的處理文件,當(dāng)前頁(yè)面的所有和后端服務(wù)器接口的交互,請(qǐng)求數(shù)據(jù)的邏輯都在這個(gè)文件完成,是核心文件,必須創(chuàng)建。
*.wxml文件是搭建當(dāng)前頁(yè)面元素的文件。負(fù)責(zé)搭建當(dāng)前頁(yè)面的結(jié)構(gòu)和布局,相當(dāng)于網(wǎng)頁(yè)開(kāi)發(fā)中的*.html文件,這個(gè)文件中存放一些類(lèi)似于div span form input sectiond等布局代碼,必須創(chuàng)建。
*.wxss文件是當(dāng)前頁(yè)面的樣式文件。負(fù)責(zé)調(diào)整當(dāng)前頁(yè)面的樣式,元素之間的間距,字體的大小,字體顏色,背景圖等,相當(dāng)于網(wǎng)頁(yè)開(kāi)發(fā)中的css文件,需要時(shí)創(chuàng)建。
*.json文件是當(dāng)前頁(yè)面的配置文件。配置當(dāng)前頁(yè)面的窗口背景色,導(dǎo)航條樣式,默認(rèn)標(biāo)題等。
1)app.js:小程序邏輯,初始化APP
2)app.json :小程序配置,比如導(dǎo)航、窗口、頁(yè)面http請(qǐng)求跳轉(zhuǎn)等
3)app.wxss:公共樣式配置
主體配置完成之后,就是對(duì)應(yīng)的業(yè)務(wù)開(kāi)發(fā)了,也就是開(kāi)發(fā)者最常操作的頁(yè)面。小程序頁(yè)面設(shè)計(jì)基本上也是遵循 MVC 結(jié)構(gòu)進(jìn)行構(gòu)建。
1)js:頁(yè)面邏輯,相當(dāng)于控制層(C);也包括部分的數(shù)據(jù)(M)
2)wxml:頁(yè)面結(jié)構(gòu)展示,相當(dāng)于視圖層(V)
3)wxss:頁(yè)面樣式表,純前端,用于輔助wxml展示
4)json:頁(yè)面配置,配置一些頁(yè)面展示的數(shù)據(jù),充當(dāng)部分的模型(M)

App.js
用來(lái)注冊(cè)一個(gè)小程序。在小程序啟動(dòng)的時(shí)候調(diào)用,并創(chuàng)建小程序,直到銷(xiāo)毀。在整個(gè)小程序的生命周期過(guò)程中,它都是存在的。很顯然它是單例的,全局的。所以,
1)只能在app.js中注冊(cè)一次。
2)在代碼的任何地方都可以通過(guò) getApp() 獲取這個(gè)唯一的小程序單例,
比如 var app = getApp();
App()的參數(shù)是 object 類(lèi)型 {} ,指定了小程序的生命周期函數(shù)。
onLaunch 函數(shù)
監(jiān)聽(tīng)小程序初始化。
當(dāng)小程序初始化完成時(shí),會(huì)觸發(fā) onLaunch(全局只觸發(fā)一次)。
onShow 函數(shù)
監(jiān)聽(tīng)小程序顯示。
當(dāng)小程序啟動(dòng),或從后臺(tái)進(jìn)入前臺(tái)顯示,會(huì)觸發(fā)。
onHide 函數(shù)
監(jiān)聽(tīng)小程序隱藏。
當(dāng)小程序從前臺(tái)進(jìn)入后臺(tái),會(huì)觸發(fā)。
所謂前后臺(tái)的定義,類(lèi)似于手機(jī)上的app,比如當(dāng)不在使用微信時(shí),就進(jìn)入了后臺(tái)。
App.json
接受一個(gè)數(shù)組,每一項(xiàng)都是字符串,來(lái)指定小程序由哪些頁(yè)面組成
"pages":[
"pages/index/index",
"pages/result/result",
"pages/history/history"
],
window
用于設(shè)置小程序的狀態(tài)欄、導(dǎo)航條、標(biāo)題、窗口背景色。

"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#d13f49",
"navigationBarTitleText": "姓名測(cè)算",
"navigationBarTextStyle":"#7f8389"
},
tabBar

通過(guò) tabBar 配置項(xiàng)指定 tab 欄的表現(xiàn),以及 tab 切換時(shí)顯示的對(duì)應(yīng)頁(yè)面。
tabBar 配置數(shù)組,只能配置最少2個(gè)、最多5個(gè) tab,tab 按數(shù)組的順序排序。
"tabBar": {
"color": "#7f8389",
"selectedColor": "#d13d3d",
"borderStyle": "white",
"backgroundColor": "#fff",
"list": [
{
"pagePath": "pages/index/index",
"text": "姓名測(cè)算",
"iconPath": "image/ico1.png",
"selectedIconPath": "image/h_ico1.png"
},
{
"pagePath": "pages/history/history",
"text": "測(cè)算歷史",
"iconPath": "image/ico2.png",
"selectedIconPath": "image/h_ico2.png"
}
]
},
networkTimeout
可以設(shè)置各種網(wǎng)絡(luò)請(qǐng)求的超時(shí)時(shí)間。
"networkTimeout": {
"request": 180000
}
}
三 視圖預(yù)渲染
組件,小程序開(kāi)發(fā)者文檔
https://mp.weixin.qq.com/debug/wxadoc/dev/component/view.html
<view class="section">
<view class="section__title">flex-direction: row</view>
<view class="flex-wrp" style="flex-direction:row;">
<view class="flex-item bc_green">1</view>
<view class="flex-item bc_red">2</view>
<view class="flex-item bc_blue">3</view>
</view>
</view>

<view class="section">
<view class="section__title">flex-direction: column</view>
<view class="flex-wrp" style="height:300px;flex-direction:column;">
<view class="flex-item bc_green">1</view>
<view class="flex-item bc_red">2</view>
<view class="flex-item bc_blue">3</view>
</view>
</view>

Button
<button type="default" size="{{defaultSize}}" loading="{{loading}}" plain="{{plain}}"disabled="{{disabled}}" bindtap="default" hover-class="other-button-hover"> default </button>
四 數(shù)據(jù)綁定
2.1 數(shù)據(jù)的綁定
<view> {{ message }} </view>
data:{
message:'Hello,world!'
}
2.2 事件(小程序是不可以操作dom的)
<button type=“primary”bindtap=“btnClick”>{{btntext}}</button>
BtnClick:function(){
console.log(“按鈕被點(diǎn)擊了~”)
}
2.3動(dòng)態(tài)修改內(nèi)容(對(duì)于data的修改,只能使用 setData()
<button type=“primary”bindtap=“btnClick”>{{btntext}}</button>
<text>{{text}}</text>
data:{
text:“這里是文本”
}
BtnClick:function(){
console.log(“按鈕被點(diǎn)擊了~”)
this.setData({text:“這是新的內(nèi)容~”})
}
<view wx:if="{{condition}}"> </view>
2.4 渲染標(biāo)簽
<view wx:if=“{{false}}”>{{text}}</view>
或者
<button type=“primary”bindtap=“btnClick”>{{btntext}}</button>
<view wx:if=“{{show}}”>{{text}}</view>
data:{
show:false
}
動(dòng)態(tài)改變這個(gè)值
btnClick:function(){
var isShow = this.data.show;
console.log( “isShow:”+isShow)
this.setData({text:“這是改變后的內(nèi)容…”,show:!isShow})
}
<view wx:if=“{{show }}”>{{text}}1</view>
<view wx:else >{{text}}2</view>
2.4 循環(huán)
<view wx:for=“{{news}}”>{{index}}-{{item}}</view>
data:{
news: [‘a(chǎn)aa’,‘bbb’,‘ccc’]
}
自己定義
<view wx:for=“{{news}}”wx:for-item=“items”wx:for-index=“ix”>{{ix}}-{{items}}</view>
動(dòng)態(tài)修改數(shù)組的值
data:{
news: [‘a(chǎn)aa’,‘bbb’,‘ccc’]
}
btnClick:function(){
var newsdata = this.data.news;
newsdata.shift()
this.setData({news:newsdata})
}
模板template
1.例如頭部
header.html
<text>這里是頭部</text>
引入
<include src=”../template/header”/>相當(dāng)于把全部?jī)?nèi)容復(fù)制過(guò)來(lái)
2.例如foot
foot.html
<template name=“foot1”>
這里是底部1
</template>
<template name=“foot2”>
這里是底部2
</template>
引入
<import src="../template/footer"/>
<template is="foot1"/>
is就相當(dāng)于引入部分模塊內(nèi)容
五 生命周期
用戶首次打開(kāi)小程序,觸發(fā) onLaunch(全局只觸發(fā)一次)。
小程序初始化完成后,觸發(fā)onShow方法,監(jiān)聽(tīng)小程序顯示。
小程序從前臺(tái)進(jìn)入后臺(tái),觸發(fā) onHide方法。
小程序從后臺(tái)進(jìn)入前臺(tái)顯示,觸發(fā) onShow方法。
小程序后臺(tái)運(yùn)行一定時(shí)間,或系統(tǒng)資源占用過(guò)高,會(huì)被銷(xiāo)毀。
示例代碼:
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'
})

小程序提供了全局的 getApp()函數(shù),可以獲取到小程序?qū)嵗?/span>
// other.js
varappInstance = getApp()
console.log(appInstance.globalData)// I am global data
總結(jié):
onLoad: 頁(yè)面加載。 1)一個(gè)頁(yè)面只會(huì)調(diào)用一次。 2)參數(shù)可以獲取wx.navigateTo和wx.redirectTo及<navigator/>中的 query。
onShow: 頁(yè)面顯示 1)每次打開(kāi)頁(yè)面都會(huì)調(diào)用一次。
onReady: 頁(yè)面初次渲染完成 1)一個(gè)頁(yè)面只會(huì)調(diào)用一次,代表頁(yè)面已經(jīng)準(zhǔn)備妥當(dāng),可以和視圖層進(jìn)行交互。 2)對(duì)界面的設(shè)置如wx.setNavigationBarTitle請(qǐng)?jiān)趏nReady之后設(shè)置。
onHide: 頁(yè)面隱藏 1)當(dāng)navigateTo或底部tab切換時(shí)調(diào)用。
onUnload: 頁(yè)面卸載
1)當(dāng)redirectTo或navigateBack的時(shí)候調(diào)用。
六 微信小程序頁(yè)面跳轉(zhuǎn)三種方式
為了不讓用戶在使用小程序時(shí)造成困擾,微信小程序規(guī)定頁(yè)面路徑只能是五層,請(qǐng)盡量避免多層級(jí)的交互方式。 頁(yè)面跳轉(zhuǎn)的話就涉及到了多個(gè)頁(yè)面層級(jí)
<navigator url="../index/index" pen-type="navigate" >跳轉(zhuǎn)到新頁(yè)面</navigator>
pen-type="navigate"等價(jià)于API的 wx.navigateTo 而wx.navigateTo的url是需要跳轉(zhuǎn)的應(yīng)用內(nèi)非 tabBar 的頁(yè)面的路徑
保留當(dāng)前頁(yè)面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個(gè)頁(yè)面,使用wx.navigateBack可以返回到原頁(yè)面。
<navigator url="../index/index" open-type="redirect">在當(dāng)前頁(yè)打開(kāi)</navigator>
open-type="redirect"等價(jià)于API的 wx.redirectTo 而wx.redirectTo的url是需要跳轉(zhuǎn)的應(yīng)用內(nèi)非 tabBar 的頁(yè)面的路徑
<navigator url="../index/index" open-type="switchTab">切換到首頁(yè)Tab</navigator>
open-type="switchTab"等價(jià)于API的 wx.switchTab而wx.switchTab的url是需要跳轉(zhuǎn)到 tabBar 頁(yè)面,并關(guān)閉其他所有非 tabBar 頁(yè)面
七 微信小程序傳遞數(shù)據(jù)
1.使用本地緩存的方法保存全局變量,本地緩存是有存儲(chǔ)限制的,所以建議手動(dòng)刪除不再需要的緩存數(shù)據(jù)。
假如在A頁(yè)面保存需要的信息,如下圖就可以直接保存鍵名為cargo的數(shù)據(jù)。
varcargo={
id:'12345',
count:2,
name:'xx書(shū)籍',
price:85,
picUrl:'http://image/kiwis.com/gfdscvbwerdcdgqd.jpg'
};
wx.setStorage({
key:"cargo",
data:cargo
})
在B頁(yè)面直接可以使用小程序的wx.getStorage并傳入要獲取到的鍵值名就可以獲取本地緩存的數(shù)據(jù)。
wx.getStorage({
key:'cargo',
success:function(res) {
console.log(res.data)
}
})
2.通過(guò)在跳轉(zhuǎn)、重定向等轉(zhuǎn)變頁(yè)面時(shí)候,可以直接通過(guò)url來(lái)傳送數(shù)據(jù)。
在A頁(yè)面?zhèn)鬟f數(shù)據(jù)到B頁(yè)面中使用的時(shí)候可以直接使用以下數(shù)據(jù)。
//page A
wx.navigateTo({
url:'test?id=1'
})
//or page A
wx.redirectTo({
url:'test?id=1&title=“標(biāo)題”'
})
//page B
Page({
onLoad:function(options){
console.log(options.id)
console.log(options.title)
}
})
八 微信小程序分享
在頁(yè)面的js文件中定義了 onShareAppMessage 函數(shù)時(shí),頁(yè)面可以表示改頁(yè)面可以轉(zhuǎn)發(fā)??梢栽诤瘮?shù)中設(shè)置頁(yè)面轉(zhuǎn)發(fā)的信息。
- 只有定義了該函數(shù),小程序右上角的菜單中才會(huì)有轉(zhuǎn)發(fā)按鈕
- 用戶點(diǎn)擊轉(zhuǎn)發(fā)按鈕的時(shí)候會(huì)調(diào)用該函數(shù)
- 該函數(shù)內(nèi)需要 return 一個(gè) Object,Object中包含轉(zhuǎn)發(fā)的信息(可自定義轉(zhuǎn)發(fā)的內(nèi)容)
onShareAppMessage: function( options ){ var that = this; // 設(shè)置菜單中的轉(zhuǎn)發(fā)按鈕觸發(fā)轉(zhuǎn)發(fā)事件時(shí)的轉(zhuǎn)發(fā)內(nèi)容 var shareObj = { title: "轉(zhuǎn)發(fā)的標(biāo)題", // 默認(rèn)是小程序的名稱(chēng)(可以寫(xiě)slogan等) path: '/pages/share/share', // 默認(rèn)是當(dāng)前頁(yè)面,必須是以‘/’開(kāi)頭的完整路徑 imgUrl: '', //自定義圖片路徑,可以是本地文件路徑、代碼包文件路徑或者網(wǎng)絡(luò)圖片路徑,支持PNG及JPG,不傳入 imageUrl 則使用默認(rèn)截圖。顯示圖片長(zhǎng)寬比是 5:4 success: function(res){ // 轉(zhuǎn)發(fā)成功之后的回調(diào) if(res.errMsg == 'shareAppMessage:ok'){ } }, fail: function(){ // 轉(zhuǎn)發(fā)失敗之后的回調(diào) if(res.errMsg == 'shareAppMessage:fail cancel'){ // 用戶取消轉(zhuǎn)發(fā) }else if(res.errMsg == 'shareAppMessage:fail'){ // 轉(zhuǎn)發(fā)失敗,其中 detail message 為詳細(xì)失敗信息 } }, complete: fucntion(){ // 轉(zhuǎn)發(fā)結(jié)束之后的回調(diào)(轉(zhuǎn)發(fā)成不成功都會(huì)執(zhí)行) } }; // 來(lái)自頁(yè)面內(nèi)的按鈕的轉(zhuǎn)發(fā) if( options.from == 'button' ){ var eData = options.target.dataset; console.log( eData.name ); // shareBtn }
通過(guò)給 button 組件設(shè)置屬性 open-type="share",可以在用戶點(diǎn)擊按鈕后觸發(fā) Page.onShareAppMessage() 事件,如果當(dāng)前頁(yè)面沒(méi)有定義此事件,則點(diǎn)擊后無(wú)效果。
兼容性寫(xiě)法: Page({
data: {
canIUse: wx.canIUse('button.open-type.share')
}
})
<button wx:if="{{canIUse}}" open-type="share"> 分享給好友</button>
<share-button wx:else></share-button>
data:{
canIUse: wx.canIUse('button.open-type.share'),
}
客服
<contact-button type="default-light" size="20" session-from="weapp"></contact-button>
<button wx:if="{{canIUse}}" open-type="contact">客服消息</button>
<contact -button wx:else></ contact-button>
data:{
canIUse: wx.canIUse('button.open-type. contact '),
本文轉(zhuǎn)載自:博客園
作者:徐念念