******************邏輯層******************
1:app.json文件用來對微信小程序進(jìn)行全局配置,決定頁面文件的路徑、窗口表現(xiàn)、設(shè)置網(wǎng)絡(luò)超時時間、設(shè)置多 tab 等,大致配置如下圖所示:


效果圖如下

2:每一個小程序頁面也可以使用.json文件來對本頁面的窗口表現(xiàn)進(jìn)行配置。 頁面的配置比app.json全局配置簡單得多,只是設(shè)置 app.json 中的 window 配置項(xiàng)的內(nèi)容,頁面中配置項(xiàng)會覆蓋 app.json 的 window 中相同的配置項(xiàng)。頁面的.json只能設(shè)置 window 相關(guān)的配置項(xiàng),以決定本頁面的窗口表現(xiàn),所以無需寫 window 這個鍵。大致配置如下圖所示:

效果圖如下所示:

3:App() 函數(shù)用來注冊一個小程序。接受一個 object 參數(shù),其指定小程序的生命周期函數(shù)等。大致函數(shù)如下圖所示:

測試結(jié)果如下所示:

注意:
1:可以在其它.js文件(非app.js文件)中通過getApp()可以用來獲取到小程序?qū)嵗?/h4>
2:App() 必須在 app.js 中注冊,且不能注冊多個;
3:不要在定義于 App() 內(nèi)的函數(shù)中調(diào)用 getApp() ,使用 this 就可以拿到 app 實(shí)例;
4:不要在 onLaunch 的時候調(diào)用 getCurrentPages(),此時 page 還沒有生成;
5:通過 getApp() 獲取實(shí)例之后,不要私自調(diào)用生命周期函數(shù);
測試如下:
運(yùn)行之后截圖為
4:Page() 函數(shù)用來注冊一個頁面。接受一個 object 參數(shù),其指定頁面的初始數(shù)據(jù)、生命周期函數(shù)、事件處理函數(shù)等。
日志輸入如下所示:
另外page中的data 將會以 JSON 的形式由邏輯層傳至渲染層,所以其數(shù)據(jù)必須是可以轉(zhuǎn)成 JSON 的格式:字符串,數(shù)字,布爾值,對象,數(shù)組。
另外page中的route字段可以獲取到當(dāng)前頁面的路徑,測試如下:
另外page中的setData函數(shù)用于將數(shù)據(jù)從邏輯層發(fā)送到視圖層(異步),同時改變對應(yīng)的 this.data 的值(同步)。具體說明如下所示:
注意:
1:直接修改 this.data 而不調(diào)用 this.setData 是無法改變頁面的狀態(tài)的,還會造成數(shù)據(jù)不一致。
2:僅支持設(shè)置可 JSON 化的數(shù)據(jù)。
3:單次設(shè)置的數(shù)據(jù)不能超過1024kB,請盡量避免一次設(shè)置過多的數(shù)據(jù)。
4:請不要把 data 中任何一項(xiàng)的 value 設(shè)為 undefined ,否則這一項(xiàng)將不被設(shè)置并可能遺留一些潛在問題。
測試如下:
小心得:只要是在生命周期中的數(shù)據(jù)(不論是app()還是page()),定義數(shù)據(jù)都是用:并且不用關(guān)鍵字來修飾,因?yàn)閍pp()以及page()中的object參數(shù)中的數(shù)據(jù)必須是json格式才行,所以不論是數(shù)據(jù)還是函數(shù)還是函數(shù)的參數(shù)都是用:來賦值的,另外在自己定義的js文件中調(diào)用wx自帶的api時,其方法的參數(shù)也是以json格式來書寫的,但是如果在生命周期以外的數(shù)據(jù)定義及函數(shù)中的數(shù)據(jù)定義是要用=并且需要const或者是var來修飾。
5:路由
5.1:getCurrentPages() 函數(shù)用于獲取當(dāng)前頁面棧的實(shí)例,以數(shù)組形式按棧的順序給出,第一個元素為首頁,最后一個元素為當(dāng)前頁面。測試如下:
5.2:路由方式
注意:
1:navigateTo, redirectTo 只能打開非 tabBar 頁面。
2:switchTab 只能打開 tabBar 頁面。
3:reLaunch 可以打開任意頁面。
4:頁面底部的 tabBar 由頁面決定,即只要是定義為 tabBar 的頁面,底部都有 tabBar。
5:調(diào)用頁面路由帶的參數(shù)可以在目標(biāo)頁面的onLoad中獲取。
實(shí)現(xiàn)頁面跳轉(zhuǎn)的四個方法
6:模塊化
6.1:文件作用域
在 JavaScript 文件中聲明的變量和函數(shù)只在該文件中有效;不同的文件中可以聲明相同名字的變量和函數(shù),不會互相影響。通過全局函數(shù) getApp()可以獲取全局的應(yīng)用實(shí)例,如果需要全局的數(shù)據(jù)可以在 App()中設(shè)置。
6.2:模塊化
可以將一些公共的代碼抽離成為一個單獨(dú)的 js 文件,作為一個模塊。模塊只有通過 module.exports 或者 exports 才能對外暴露接口。
需要注意的是:
exports 是 module.exports 的一個引用,因此在模塊里邊隨意更改 exports 的指向會造成未知的錯誤。所以更推薦開發(fā)者采用 module.exports 來暴露模塊接口,除非你已經(jīng)清晰知道這兩者的關(guān)系。
小程序目前不支持直接引入 node_modules , 開發(fā)者需要使用到 node_modules 時候建議拷貝出相關(guān)的代碼到小程序的目錄中。
在需要使用這些模塊的文件中,使用 require(path) 將公共代碼引入。
測試截圖如下:
注意:module中的函數(shù)的寫法和app以及page中函數(shù)的寫法是不同的
在頁面文件中調(diào)用module
log的輸出結(jié)果
******************視圖層******************
1:數(shù)據(jù)綁定(WXML 中的動態(tài)數(shù)據(jù)均來自對應(yīng) Page 的 data)
1.1:簡單綁定(使用雙大括號{{}}將變量包起來),
可以作用于內(nèi)容,eg:
<view> {{ message }} </view>
可以作用于組件屬性(需要在雙引號之內(nèi)),eg:
<view id="item-{{id}}"> </view>
可以作用于控制屬性(需要在雙引號之內(nèi)),eg:
<view wx:if="{{condition}}"> </view>
可以作用于關(guān)鍵字(需要在雙引號之內(nèi)),eg:
<checkbox checked="{{false}}"> </checkbox>
//特別注意:不要直接寫 checked="false",不然上面的checkbox的狀態(tài)還是選中狀態(tài),因?yàn)槠溆?jì)算結(jié)果是一個字符串,轉(zhuǎn)成 boolean 類型后代表真值。
1.2:運(yùn)算,可以在 {{}} 內(nèi)進(jìn)行簡單的運(yùn)算,支持的有如下幾種方式:
三元運(yùn)算,eg:
<view hidden="{{flag ? true : false}}"> Hidden </view>
算數(shù)運(yùn)算,eg:
<view> {{a + b}} + {{c}} + d </view>
邏輯判斷,eg:
<view wx:if="{{length > 5}}"> </view>
字符串運(yùn)算,eg:
<view>{{"hello" + name}}</view>
數(shù)據(jù)路徑運(yùn)算,eg:
<view>{{object.key}} {{array[0]}}</view>
Page({
data: {
object: {
key: 'Hello '
},
array: ['MINA']
}
})
1.3:組合,也可以在{{}}內(nèi)直接進(jìn)行組合,構(gòu)成新的數(shù)組或者對象
數(shù)組,eg:
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page({
data: {
zero: 0
}
})
最終組合成數(shù)組[0, 1, 2, 3, 4]
注意:花括號和引號之間如果有空格,將最終被解析成為字符串,eg:
<view wx:for="{{[1,2,3]}} ">
{{item}}
</view>
等同于
<view wx:for="{{[1,2,3] + ' '}}">
{{item}}
</view>
測試截圖如下
2:列表渲染
2.1:wx:for(在組件上使用 wx:for 控制屬性綁定一個數(shù)組,即可使用數(shù)組中各項(xiàng)的數(shù)據(jù)重復(fù)渲染該組件。默認(rèn)數(shù)組的當(dāng)前項(xiàng)的下標(biāo)變量名默認(rèn)為 index,數(shù)組當(dāng)前項(xiàng)的變量名默認(rèn)為 item),測試如下圖:
使用 wx:for-item 可以指定數(shù)組當(dāng)前元素的變量名,使用 wx:for-index 可以指定數(shù)組當(dāng)前下標(biāo)的變量名,當(dāng)出現(xiàn)循環(huán)嵌套時就可以指定變量名達(dá)到區(qū)分的目的,測試如下:
2.2:block wx:for(類似 block wx:if,也可以將 wx:for 用在<block/>標(biāo)簽上,以渲染一個包含多節(jié)點(diǎn)的結(jié)構(gòu)塊),測試如下:
2.3:wx:key(如果列表中項(xiàng)目的位置會動態(tài)改變或者有新的項(xiàng)目添加到列表中,并且希望列表中的項(xiàng)目保持自己的特征和狀態(tài)(如 <input/> 中的輸入內(nèi)容,<switch/> 的選中狀態(tài)),需要使用 wx:key 來指定列表中項(xiàng)目的唯一的標(biāo)識符)
wx:key 的值以兩種形式提供:
1:字符串,代表在 for 循環(huán)的 array 中 item 的某個 property,該 property 的值需要是列表中唯一的字符串或數(shù)字,且不能動態(tài)改變。
2:保留關(guān)鍵字 *this 代表在 for 循環(huán)中的 item 本身,這種表示需要 item 本身是一個唯一的字符串或者數(shù)字。
當(dāng)數(shù)據(jù)改變觸發(fā)渲染層重新渲染的時候,會校正帶有 key 的組件,框架會確保他們被重新排序,而不是重新創(chuàng)建,以確保使組件保持自身的狀態(tài),并且提高列表渲染時的效率。
如不提供 wx:key,會報(bào)一個 warning, 如果明確知道該列表是靜態(tài),或者不必關(guān)注其順序,可以選擇忽略。測試如下:
注意:
當(dāng) wx:for 的值為字符串時,會將字符串解析成字符串?dāng)?shù)組
<view wx:for="array">
{{item}}
</view>
等同于
<view wx:for="{{['a','r','r','a','y']}}">
{{item}}
</view>
3:條件渲染
3.1:wx:if(使用 wx:if="{{condition}}" 來判斷是否需要渲染該代碼塊,也可以用 wx:elif 和 wx:else 來添加一個 else 塊),測試如下:
3.2:block wx:if(因?yàn)?wx:if 是一個控制屬性,需要將它添加到一個標(biāo)簽上。如果要一次性判斷多個組件標(biāo)簽,可以使用一個 <block/> 標(biāo)簽將多個組件包裝起來,并在上邊使用 wx:if 控制屬性),測試如下:
注意: <block/> 并不是一個組件,它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性
3.3:wx:if vs hidden
因?yàn)?wx:if 之中的模板也可能包含數(shù)據(jù)綁定,所以當(dāng) wx:if 的條件值切換時,框架有一個局部渲染的過程,因?yàn)樗鼤_保條件塊在切換時銷毀或重新渲染。同時 wx:if 也是惰性的,如果在初始渲染條件為 false,框架什么也不做,在條件第一次變成真的時候才開始局部渲染。相比之下,hidden 就簡單的多,組件始終會被渲染,只是簡單的控制顯示與隱藏。
一般來說,wx:if 有更高的切換消耗而 hidden 有更高的初始渲染消耗。因此,如果需要頻繁切換的情景下,用 hidden 更好,如果在運(yùn)行時條件不大可能改變則 wx:if 較好。hidden的用法如下:
4:模板(WXML提供模板(template),可以在模板中定義代碼片段,然后在不同的地方調(diào)用)
4.1:定義模板(使用 name 屬性,作為模板的名字。然后在<template/>內(nèi)定義代碼片段),測試如下:
4.2:使用模板(使用import先導(dǎo)入模板文件,然后使用 is 屬性聲明需要的使用的模板,最后將模板所需要的 data 傳入,另外is 屬性可以使用{{}}語法,來動態(tài)決定具體需要渲染哪個模板)
使用模板
數(shù)據(jù)
最后效果為:
5:事件(事件是視圖層到邏輯層的通訊方式)
5.1:事件分類
事件分為冒泡事件和非冒泡事件:
冒泡事件:當(dāng)一個組件上的事件被觸發(fā)后,該事件會向父節(jié)點(diǎn)傳遞。
非冒泡事件:當(dāng)一個組件上的事件被觸發(fā)后,該事件不會向父節(jié)點(diǎn)傳遞。
冒泡事件
冒泡事件
注:除上表之外的其他組件自定義事件如無特殊聲明都是非冒泡事件,如<form/>的submit事件,<input/>的input事件,<scroll-view/>的scroll事件
5.2:事件綁定和冒泡

















實(shí)現(xiàn)頁面跳轉(zhuǎn)的四個方法

注意:module中的函數(shù)的寫法和app以及page中函數(shù)的寫法是不同的

在頁面文件中調(diào)用module

log的輸出結(jié)果
<view> {{ message }} </view>
<view id="item-{{id}}"> </view>
<view wx:if="{{condition}}"> </view>
<checkbox checked="{{false}}"> </checkbox>
//特別注意:不要直接寫 checked="false",不然上面的checkbox的狀態(tài)還是選中狀態(tài),因?yàn)槠溆?jì)算結(jié)果是一個字符串,轉(zhuǎn)成 boolean 類型后代表真值。
<view hidden="{{flag ? true : false}}"> Hidden </view>
<view> {{a + b}} + {{c}} + d </view>
<view wx:if="{{length > 5}}"> </view>
<view>{{"hello" + name}}</view>
<view>{{object.key}} {{array[0]}}</view>
Page({
data: {
object: {
key: 'Hello '
},
array: ['MINA']
}
})
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page({
data: {
zero: 0
}
})
<view wx:for="{{[1,2,3]}} ">
{{item}}
</view>
<view wx:for="{{[1,2,3] + ' '}}">
{{item}}
</view>













<view wx:for="array">
{{item}}
</view>
<view wx:for="{{['a','r','r','a','y']}}">
{{item}}
</view>










使用模板

數(shù)據(jù)


冒泡事件

冒泡事件
事件綁定的寫法同組件的屬性,以 key、value 的形式。
key 以bind或catch開頭,然后跟上事件的類型,如bindtap,catchtouchstart。自基礎(chǔ)庫版本1.5.0起,bind和catch后可以緊跟一個冒號,其含義不變,如bind:tap、、catch:touchstart。
value 是一個字符串,需要在對應(yīng)的 Page 中定義同名的函數(shù)。不然當(dāng)觸發(fā)事件的時候會報(bào)錯。
bind事件綁定不會阻止冒泡事件向上冒泡,catch事件綁定可以阻止冒泡事件向上冒泡。
如在下邊這個例子中,點(diǎn)擊 inner view 會先后調(diào)用handleTap3和handleTap2(因?yàn)閠ap事件會冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父節(jié)點(diǎn)傳遞),點(diǎn)擊 middle view 會觸發(fā)handleTap2,點(diǎn)擊 outer view 會觸發(fā)handleTap1。
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>
5.3:事件對象(如無特殊說明,當(dāng)組件觸發(fā)事件時,邏輯層綁定該事件的處理函數(shù)會收到一個事件對象),測試如下:



另外,還有個dataset屬性(在組件中可以定義數(shù)據(jù),這些數(shù)據(jù)將會通過事件傳遞給 SERVICE。 書寫方式: 以data-開頭,多個單詞由連字符-鏈接,不能有大寫(大寫會自動轉(zhuǎn)成小寫)如data-element-type,最終在 event.currentTarget.dataset 中會將連字符轉(zhuǎn)成駝峰elementType),測試如下:



6:引用(WXML 提供兩種文件引用方式import和include)
6.1:import(import可以在該文件中使用目標(biāo)文件定義的template),測試如下:

模板內(nèi)容

導(dǎo)入模板

數(shù)據(jù)內(nèi)容

展示效果
6.2:import 的作用域(只會 import 目標(biāo)文件中定義的 template,而不會 import 目標(biāo)文件 import 的 template)
6.3:include(include 可以將目標(biāo)文件除了 <template/> <wxs/> 外的整個代碼引入,相當(dāng)于是拷貝到 include 位置),測試如下:



7:WXS 模塊(每一個 .wxs 文件和 <wxs> 標(biāo)簽都是一個單獨(dú)的模塊。每個模塊都有自己獨(dú)立的作用域。即在一個模塊里面定義的變量與函數(shù),默認(rèn)為私有的,對其他模塊不可見。一個模塊要想對外暴露其內(nèi)部的私有變量與函數(shù),只能通過 module.exports 實(shí)現(xiàn))
7.1:.wxs 文件(在微信開發(fā)者工具里面,右鍵可以直接創(chuàng)建 .wxs 文件,在其中直接編寫 WXS 腳本),測試如下:



注意:
wxs文件中寫的公共代碼是用在.wxml文件中的,它通過<wxs>標(biāo)簽來導(dǎo)入,而.js文件中寫的公共代碼是用在其他.js文件中的,它通過require來導(dǎo)入。二者相同的地方就是都需要通過module.exports來將私有的數(shù)據(jù)變成公共的。另外template是用來存放公共的視圖的。另外wxs文件可以通過require函數(shù)來導(dǎo)入其他wxs文件。
8:變量(WXS 中的變量均為值的引用;沒有聲明的變量直接賦值使用,會被定義為全局變量;如果只聲明變量而不賦值,則默認(rèn)值為 undefined;var表現(xiàn)與javascript一致,會有變量提升。),示例如下:
var foo = 1;
var bar = "hello world";
var i; // i === undefined
//上面代碼,分別聲明了 foo、 bar、 i 三個變量。然后,foo 賦值為數(shù)值 1 ,bar 賦值為字符串 "hello world"。
注意:在js中"==" 只要求值相等; "===" 要求值和類型都相等
注意:function 也支持以下的語法(匿名函數(shù),閉包等):
var a = function (x) {
return function () { return x;}
}
var b = a(100);
console.log( 100 === b() );
9:WXSS(用于描述 WXML 的組件樣式)
9.1:尺寸單位(rpx: 可以根據(jù)屏幕寬度進(jìn)行自適應(yīng))
9.2:樣式導(dǎo)入(使用@import語句可以導(dǎo)入外聯(lián)樣式表,@import后跟需要導(dǎo)入的外聯(lián)樣式表的相對路徑,用;表示語句結(jié)束)
9.3:內(nèi)聯(lián)樣式(框架組件上支持使用 style、class 屬性來控制組件的樣式)
9.3.1:style:靜態(tài)的樣式統(tǒng)一寫到 class 中。style 接收動態(tài)的樣式,在運(yùn)行時會進(jìn)行解析,請盡量避免將靜態(tài)的樣式寫進(jìn) style 中,以免影響渲染速度。
<view style="color:{{color}};" />
9.3.2:class:用于指定樣式規(guī)則,其屬性值是樣式規(guī)則中類選擇器名(樣式類名)的集合,樣式類名不需要帶上.,樣式類名之間用空格分隔。
<view class="normal_view" />

所支持的選擇器的類型
9.4:全局樣式與局部樣式(定義在 app.wxss 中的樣式為全局樣式,作用于每一個頁面。在 page 的 wxss 文件中定義的樣式為局部樣式,只作用在對應(yīng)的頁面,并會覆蓋 app.wxss 中相同的選擇器),并且app.wxss不需要導(dǎo)入直接使用即可,測試如下:



用了樣式表后的view,內(nèi)容居中了