1. 什么是小程序?
小程序是一種"不需要下載安裝"即可使用的應用,它實現了"觸手可及"的夢想。使用起來方便快捷、用完即走
1.1 目前常見的小程序
- 微信小程序
- 支付寶小程序
- 淘寶小程序
- 抖音小程序
- 頭條小程序
- QQ小程序
- 美團小程序
- 等等
1.1.2 為什么各個平臺都需要支持小程序?
你有,我也得有
大廠競爭格局中一個重要的一環。
小程序作為介于頁面和App之間的一項技術,它有自身很大的優勢
體驗比傳統H5頁面要好很多,相當于傳統的App,使用起來更加方便,不需要在應用商店中下載安裝,甚至注冊登錄等麻煩操作。
小程序可以間接的動態為App添加新動態
傳統的App更新需要打包,上架到應用商店后需要通過審核用戶才能進行下載(App Store),但是小程序可以在App不更新的情況下,動態為自己的應用添加新的功能要求。
1.2 小程序由誰開發?
-
小程序的定位
介于原生App和手機H5頁面之間的一個產品定位 -
由此有一個疑問?小程序是由誰來開發呢?
小程序開發工程師?
由小程序的技術特點所決定的,比如微信小程序WXML、WXSS、JavaScript
它更接近于前端的開發技術棧,所以小程序是由前端開發工程師
來開發的
1.3 小程序的技術選型
1.3.1 原生小程序開發
- 微信小程序
WXML、WXSS、JavaScript - 支付寶小程序
AXML、ACSS、JavaScript
1.3.2 選擇框架開發小程序
1.3.2.1 較少使用
- mpvue
mpvue是一個支持vue開發小程序的前端框架,支持微信小程序、百度小程序、頭條小程序、支付寶小程序,框架在2018年之后就不再維護和更新了,目前已經被放棄
- wepy
wepy是由騰訊開源的,一款讓小程序支持組件化開發的框架,通過預編譯的手段讓開發者可以選擇自己喜歡的開發風格去開發小程序,該框架目前維護的也較少,不推薦使用
1.3.2.2 較常使用
- uni-app
由DCloud團隊開發和維護,uni-app是一個使用vue開發所有前端應用的框架,開發者編寫一套代碼,可以發布到Ios、Android、Web(響應式)、以及各種小程序(微信/支付寶/百度/頭條/飛書/QQ/快手/釘釘/淘寶)、快應用等多個平臺,uni-app目前是很多公司的技術選型,特別是希望適配移動端App的公司
- taro
由京東團隊開發和維護,taro是一個
開放式 跨端 跨框架
解決方案,支持使用React/Vue/Nerv等框架來開發 (微信/京東/百度/支付寶/字節跳動/QQ/飛書)小程序 /H5/RN 等應用,taro因為本身支持React、Vue的選擇,給了我們更加靈活的選擇空間,特別是Taro3.x之后,支持Vue3、React Hook 等寫法 - uni- app和taro開發原生App
- 無論是適配原生小程序還是原生App,都有較多的適配問題,所以還是需要多了解原生的一些開發知識
- 產品使用體驗整體相較于原生App差很多
- 也有其他的技術選項來開發原生App
- ReactNative
- Flutter
1.3.3 需要掌握的預備知識
1.3.3.1 核心技術
頁面布局
: WXML,類似于HTML
頁面樣式
: WXSS,幾乎就是CSS(某些樣式屬性不支持,某些進行了增強,但是基本是一致的)
頁面腳本
: JavaScript+WXS(WeixinScript)
如果之前已經掌握了Vue或者React等框架開發,那么學習小程序是更簡單的
因為里面的核心思想都是一致的 組件化開發、數據響應式、mustache語法、事件綁定、等
2. 小程序架構和配置
2.1 小程序的架構模型
2.1.1 MVVM架構
2.1.1.1 Vue的MVVM和小程序MVVM對比
2.1.1.2 MVVM為什么好用呢?
- DOM Listeners
ViewModel層可以將DOM的監聽綁定到Model層 - Data Bindings
ViewModel層可以將數據的變量,響應式的反應到View層
MVVM框架將我們從'命令式編程'轉移到'聲明式編程'
2.1.2 誰是小程序的宿主環境呢?
微信客戶端
宿主環境為了執行小程序的各種文件WXML、WXSS、JS
小程序基于WebView
環境下時,WebView的 JS邏輯、DOM樹構建、CSS解析、樣式計算、Layout、Paint(Composite) 都發生在同一線程,在 WebView 上執行過多的Js邏輯可能會阻塞渲染,導致頁面卡頓,以此為前提下,小程序同時考慮了性能與安全,來用了目前稱為雙線程模型
的架構。
2.1.3 雙線程模型
- WXML模塊和WXSS樣式運行于渲染層,渲染層使用WebView線程渲染(一個程序有多個頁面,會使用多個WebView的線程)
- JS腳本(app.js/home.js等) 運行于邏輯層,邏輯層使用JsCore運行JS腳本
- 這兩個線程都會經由微信客戶端(Native)進行中轉交互
2.2 小程序的配置文件
小程序很多開發需求被規定在了配置文件中
為什么這樣做?
更利于開發效率
保證開發出來的小程序某些開發風格是一致的
比如導航欄-頂部TabBar 頁面路由等
2.2.1 常見的配置文件
project.config.json 項目配置文件,如項目名稱、appid等
sitemap.json 小程序搜索相關的
app.json 全局配置
常用
- pages 頁面路徑列表
用于指定小程序由哪些頁面組成,每一項都對應一個頁面的路徑(含文件名)信息
小程序中所有的頁面都必須在pages中進行注冊- window 全局的默認窗口展示
用戶指定窗口如何展示,其中還包含了很多其他的屬性- tabBar 頂部tab欄的展示
page.json 頁面配置
每個小程序頁面也可以使用
.json
文件來對本頁面的窗口表現進行配置
頁面中配置項在當前頁面會覆蓋app.json
(全局配置)的window中相同的配置項
2.3 注冊小程序(App函數)
每個小程序都需要在app.js中調用 App函數 注冊
在注冊時可以綁定對應的生命周期函數,在生命周期函數中執行對應的代碼
2.3.1 注冊App時,一般會做些什么?
- 判斷小程序的進入場景
- 常見的打開場景
- 群聊會話中打開
- 小程序列表打開
- 微信掃一掃打開
- 另一個小程序打開等
- 如何確定場景?
- 在onLaunch和onShow生命周期回調函數中,會有options參數,其中有scene值 鏈接
- 常見的打開場景
- 監聽生命周期函數,在生命周期中執行對應的業務邏輯,比如在某個生命周期函數中進行登錄操作或者請求網絡數據
- 因為App()實例只有一個,并且是全局共享的(單例對象),所以可以將一些共享的數據放在這里
- 在App中定義全局的數據
globalData: { userInfo: {name:"藍"} }
- 在其他頁面中訪問
onLoad(options) { const app = getApp() console.log(app.globalData) }
2.3 注冊頁面(Page函數)
小程序中的每個頁面都有一個對應的js文件,其中調用Page函數注冊頁面示例
在注冊時,可以綁定初始化數據,生命周期回調,事件處理函數等
2.3.1 注冊一個page頁面時,一般需要做些什么?
- 在生命周期函數中發送網絡請求,從服務器獲取數據
- 初始化一些數據,以方便被wxml引用展示
- 監聽wxml中的事件,綁定對應的事件函數
- 其他的一些監聽
- 頁面滾動
- 上拉刷新
- 配置當前監聽頁面的json文件
"enablePullDownRefresh": true (開啟上拉刷新)
- 在代碼中進行監聽
onPullDownRefresh() {}
- 配置當前監聽頁面的json文件
- 下拉加載
- 配置當前監聽頁面的json文件
"onReachBottomDistance": 0 (距離底部欄多少距離時開啟下拉加載)
- 在代碼中進行監聽
onReachBottom() {}
- 配置當前監聽頁面的json文件
- 等
2.4 page頁面的生命周期函數
3. WXSS-WXML-WXS語法
3.1 WXSS
是一套樣式語言,用于描述wxml的組件樣式,wxss用來決定wxml的組件應該怎么顯示
3.1.1 小程序樣式的寫法
- 行內樣式
- 頁面樣式
- 全局樣式
三種樣式都可以作用于頁面的組件,如果有相同的樣式,優先級的順序是:行內樣式>頁面樣式>全局樣式
目前支持的選擇器
wxss優先級與css類似
3.1.2 WXSS的擴展
wxss具有css大部分特性,同時為了更適合開發微信小程序,wxss對css進行了擴充及修改
3.1.2.1 尺寸單位
rpx(responsive pixel)
可以根據屏幕寬度進行自適應,規定屏幕寬度為750px
如在iPhone6上,屏幕寬度為375px,共有375個物理像素,則750rpx = 375px = 750物理像素, 1rpx = 0.5px = 1物理像素。
- 建議
開發微信小程序時設計師可以使用iPhone6作為視覺稿的標準 -
注意
在較小的屏幕上不可避免的會有一些毛刺
3.1.2.2 樣式導入
使用@import
語句可以導入外聯樣式表,@import
后跟需要導入的外聯樣式表的相對路徑,用;
表示語句結束
/** common.wxss **/
.small-p {
padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
3.2 WXML
3.2.1 WXML基本格式
類似于HTML代碼
比如可以寫成單標簽,也可以寫成雙標簽
必須有嚴格的閉合
沒有閉合會導致編譯錯誤
大小寫敏感
class和Class時不同的屬性
3.2.2 Mustache語法
開發中,界面上展示的數據并不是寫死的,而是會根據服務器返回的數據,或者用戶的操作來進行改變,如果使用原生JS或者Jquery的話,我們需要通過操作DOM來進行頁面的更新,小程序和Vue一樣,提供了插值語法,Mustache語法(雙大括號)
3.2.3 block標簽
某些情況下,我們需要使用 wx:if 或 wx:for 時,可能需要包裹一組或者多組組件標簽,我們希望對這一組或者多組標簽進行整體操作,這時就可以使用block標簽。
- 注意
<block/>并不是一個組件,它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性 - 好處
將需要進行遍歷或者判斷的內容進行包裹,將遍歷和判斷的屬性放在block標簽中,不影響普通屬性的閱讀,提高代碼的可讀性
3.2.4 邏輯判斷 wx:if - wx:elif - wx:else
有些時候,我們需要根據條件來決定一些內容是否渲染,當條件為true時,view組件會渲染出來,當條件為false時,view組件不會渲染出來
<view>
<block wx:if="{{score>=90}}">
<view>優秀</view>
</block>
<block wx:elif="{{score>80}}">
<view>良好</view>
</block>
<block wx:elif="{{score>=60}}">
<view>及格</view>
</block>
<block wx:else>
<view>不及格</view>
</block>
</view>
3.2.5 hidden屬性
hidden是所有組件都默認擁有的屬性
,當hidden屬性為true時,組件會被隱藏,當hidden屬性為false時,組件會顯示出來
<view hidden="{{false}}">hi hi</view>
3.2.6 hidden和wx:if的區別
- hidden 控制組件的隱藏和顯示,無論條件組件始終都會被渲染
- wx:if 控制組件是否渲染,wx:if 是惰性的,如果在初始渲染條件為false是,該組件不會進行任何處理
- 一般來說 wx:if 有更高的切換消耗 而 hidden 有更高的初始渲染消耗,
如果需要頻繁切換,使用hidden。如果在運行時條件不大可能改變則使用wx:if
3.2.7 列表渲染
3.2.7.1 wx:for
為什么使用wx:for?
在實際開發中,服務器經常返回各種列表數據,我們不可能一一從列表中取出數據進行展示,需要通過for循環的方式來遍歷所有的數據,一次性的進行展示
在組件中,我們可以使用wx:for來遍歷數組(字符串、數字),默認情況下遍歷后wxml中可以使用一個變量index
,保存的是當前遍歷數據的下標值,數據中對應的某項的數據,使用變量名item獲取
<block>
<!-- 遍歷一個數組 -->
<view wx:for="{{['abc','aaa','ccc']}}">{{item}}</view>
<!-- 遍歷一個字符串 -->
<view wx:for="{{'hello 你好'}}">{{item}}</view>
<!-- 遍歷一個數字 -->
<view wx:for="{{5}}">{{item}}</view>
</block>
3.2.7.2 item/index名稱
默認情況下,item/index的名字是固定的
但是某些情況下我們可能想使用其他名稱,或者當出現多層變量時,名字會重復
使用wx:for-item
和wx:for-index
修改數組當前元素和下標的變量名
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
3.2.7.3 wx:key的值以兩種形式提供
-
字符串
,代表在for循環的array中item的某個property,該property的值需要是列表中唯一的字符串或者數字,且不能動態改變 - 保留關鍵字
*this
,代表在for循環中的item本身,這種表示需要item本身是一個唯一的字符串或者數字
3.2 WXS
3.2.1 什么是WXS?
3.2.1.1 WXS(WeiXin Script) 是小程序的一套腳本語言,結合 WXML,可以構建出頁面的結構。
官方:WXS 與 JavaScript 是不同的語言,有自己的語言,并不和 JavaScript 一致。(不過基本一致)
WXS中目前只能使用ES5,ES6的使用會報錯
3.2.2 為什么要設計WXS語言?
3.2.2.1 在WXML中是不能直接調用Page
/Component
中定義函數的; (雙線程模式)
<!-- 在vue中可以直接調用函數 但是在小程序中這樣調用是沒用的(以前這樣調用會報錯,現在不會報錯但是沒有任何結果顯示) -->
<view>結果:{{formatCount(value)}}</view>
但是某些情況下,我們希望使用函數來處理WXML中WXML中的數據(類似于Vue中的過濾器),這個時候就可以使用WXS了
3.2.3 WXS使用的限制和特點:
- WXS 不依賴于運行時的基礎庫版本,可以在所有版本的小程序中運行;
- WXS 的運行環境和其他 JavaScript 代碼是隔離的,WXS中不能調用其他JavaScript文件中定義的函數,也不能調用小程序提供的API;
- 由于運行環境的差異,在IOS設備上小程序內的WXS會比JavaScript代碼快 2~20 倍,在android設備上二者運行效率無差異;
3.2.4 WXS的寫法
3.2.4.1 WXS有兩種寫法:
- 寫在<wxs>標簽中
- 寫在以.wxs結尾的文件中
3.2.4.2 <wxs>標簽的屬性:
屬性名 | 類型 | 說明 |
---|---|---|
module | String | 當前<wxs> 標簽的模塊名。必填字段。 |
src | String | 引用.wxs 文件的相對路徑。僅當本標簽為單閉合標簽或標簽內容為空時有效。 |
3.2.5 每一個.wxs文件和 <wxs> 標簽都是一個單獨的模塊。(一個wxml文件中可以引入多個wxs"module不能重復")
- 每個模塊都有自己獨立的作用域。即在一個模塊里面定義的變量與函數,默認為私有的,對其他模塊不可見;
- 一個模塊想要對外暴露起內部的私有變量,只能通過
module.exports
實現;
3.2.6 WXS簡單案例
傳入一個數字(整數或小數),格式化后進行展示(例如36456,展示結果3.6萬)
-
傳入一個時間(秒),格式化后進行展示(例如100秒,展示結果為01:40)
wxml
<wxs module="format" src="/utils/format.wxs"></wxs>
<block>
<view>傳入一個數字(整數或小數),格式化后進行展示(例如36456,展示結果3.6萬)</view>
<view>結果:{{format.formatCount(value)}}</view>
<input type="number" model:value="{{value}}" class="my-input" />
</block>
<block>
<view>傳入一個時間(秒),格式化后進行展示(例如100秒,展示結果為01:40)</view>
<view>結果:{{format.formatDuration(value1)}}</view>
<input type="number" model:value="{{value1}}" class="my-input" />
</block>
- wxs
function formatCount(count) {
var patrn = getRegExp('(^[0-9]*\.([0-9]{1}\d*)$)|(^[0-9]*$)')
if (!patrn.test(count)) return count ? "格式錯誤" : "";
var count = +count;
if (count > 100000000) {
return (count / 100000000).toFixed(1) + "億"
} else if (count > 10000) {
return (count / 10000).toFixed(1) + "萬"
}
return count
}
function disposeTime(time) {
return time < 10 ? "0" + time : time
}
function formatDuration(duration) {
var patrn = getRegExp('(^[0-9]*$)');
if (!patrn.test(duration)) return "格式錯誤";
var isHours = duration >= 3600;
if (isHours) {
var hours = disposeTime(Math.floor(duration / 3600));
duration = duration - hours * 3600;
}
var minutes = disposeTime(Math.floor(duration / 60));
var seconds = disposeTime(duration % 60);
return (isHours ? (hours + ":") : "") + minutes + ":" + seconds;
}
module.exports = {
formatCount: formatCount,
formatDuration: formatDuration
}
3.2.7 WXS中使用正則表達式
直接使用會報錯 var patrn = /'(^[0-9]*$)'/;
要使用getRegExp函數
var patrn = getRegExp('(^[0-9]*$)');
- 注意 使用getRegExp時里面不要帶
/
!!!! - 錯誤
getRegExp('/(^[0-9]*$)/');
- 正確
getRegExp('(^[0-9]*$)');
4. 事件處理
4.1 什么時候會產生事件?
小程序需要經常和用戶進行某種交互,比如點擊界面上的某個按鈕或者區域,比如滑動了某個區域 等
4.2 什么是事件?
事件是視圖層到邏輯層的通訊方式
事件可以將用戶的行為反饋到邏輯層進行處理
事件可以綁定在組件上,當觸發事件時,就會執行邏輯層中對應的事件處理函數
事件對象可以攜帶額外信息,如id、dataset、touches等
4.3 事件是如何處理的?
- 事件通過
bind
/catch
這個屬性綁定在組建上的(和普通的屬性寫法很相似,以key="value"形式) - key以bind或catch開頭,從
1.5.0
版本開始,可以在bind和catch后加一個冒號 - 同時在當前頁面的Page構造器中定義對應的事件處理函數,如果沒有對應的函數,觸發事件時會報錯
- 比如當用戶點擊該button區域時,達到觸發條件生成事件tap,該事件處理函數會被執行,同時還會收到一個事件對象
event
- 比如當用戶點擊該button區域時,達到觸發條件生成事件tap,該事件處理函數會被執行,同時還會收到一個事件對象
4.4 事件對象event
當某個事件觸發時,會產生一個事件對象,并且這個對象被傳入到回調函數中
4.4.1 BaseEvent基礎事件對象屬性列表
4.5 current Target和target的區別
-
currentTarget
事件處理程序注冊的元素 -
target
事件觸發實際目標元素
4.6 touches和changedTouches的區別
- 在touched中不同
- 多手指觸摸時不同
4.7 事件參數傳遞
4.7.1 dataset
當視圖層發生事件時,某些情況需要事件攜帶一些參數到執行的函數中,這個時候就可以通過data-屬性來完成
- 格式
data-屬性的名稱
- 獲取
e.currentTarget.dataset.屬性的名稱
4.7.2 mark
版本2.7.1以上才可以使用
使用mark來識別具體觸發事件的target節點,還可以用于承載一些自定義數據
當事件觸發時,事件冒泡路徑上所有的mark會被合并,并返回給事件回調函數
即使事件不是冒泡事件,也會mark
如何存在同名的mark,父節點的mark會被子節點的覆蓋
在自定義組件中接收事件時,mark不包含自定義組件外的節點的mark
<view mark:myMark="last" bindtap="bindViewTap">
<button mark:anotherMark="leaf" bindtap="bindButtonTap">按鈕</button>
</view>
Page({
bindViewTap: function(e) {
e.mark.myMark === "last" // true
e.mark.anotherMark === "leaf" // true
}
})
4.7.3 dataset和mark的區別
- mark會包含從觸發事件的節點到根節點上的所有的mark屬性值
- dataset僅包含一個節點的data-屬性值
- dataset的值會做大小寫的轉換,mark不會做大小寫的轉換
4.8 事件冒泡和事件捕獲
當界面產生了一個事件時,事件分為了捕獲階段和冒泡階段
5. 組件化開發
1.6.3版本后小程序才開始支持自定義組件的開發
5.1 組件化思想的應用
- 盡可能的將頁面拆分成一個個小的、可復用的組件
- 讓代碼更加方便組織和管理,并且擴展性也更強
5.2 創建一個組件
類似于頁面,自定義組件由
json wxml wxss js
四個文件組成
首先先在根目錄下創建一個文件夾components
,在里面存放后續新建的自定義組件
-
自定義組件的步驟
- 首先需要先在創建的自定義組件的json文件中進行自定義組件的聲明(將component字段設置為true)
- 在wxml中編寫組件自己的模版
- 在wxss中編寫組件自己的相關樣式
- 在js文件中可以定義數據或組件內部的相關邏輯
5.3 使用自定義組件和細節注意事項
自定義組件也是可以引用自定義組件的,引用方法類似于頁面引用自定義組件的方法(使用usingComponents字段)
自定義組件和頁面所在項目根目錄名不能以"wx-"為前綴,否則會報錯
如果在app.json和usingComponents聲明某個組件,那么所有頁面和組件都可以直接使用該組件
5.4 組件的樣式細節
5.4.1 組件內的樣式 對 外部樣式 的影響
- 組件內的class樣式,只對組件wxml內的節點生效,對引用組件的Page頁面不生效
- 組件內不能使用id選擇器、屬性選擇器、標簽選擇器
5.4.2 外部樣式 對 組件內的樣式 的影響
- 外部使用class的樣式,只對外部wxml的class生效,對組件內是不生效的
- 外部使用了id選擇器、屬性選擇器不會對組件內產生影響
- 外部使用了標簽選擇器,會對組件內產生影響
5.4.3 如何讓class可以相互影響
- 在Component中,可以傳入一個options屬性,其中options屬性中有一個styleIsolation(隔離)屬性
- styleIsolation常用的三個值
-
isolated
表示啟動樣式隔離,在自定義組件內外,使用class指定的樣式將不會互相影響 -
apply-shared
表示頁面wxss樣式將影響到自定義組件,但自定義組件wxss中指定的樣式不會影響頁面 -
shared
表示頁面wxss樣式將影響到自定義組件,自定義組件wxss中指定的樣式也會影響頁面和其他設置
-
5.5 組件的通訊
很多情況下,組件內展示的內容(數據、樣式、標簽)并不是在組件內寫死的,而是可以由使用者來決定的
5.5.1 向組件傳遞數據 - properties
給組件傳遞數據
大部分情況下,組件只負責布局和樣式,內容是由使用組件的對象決定的,所以經常需要從外部傳遞數據給我們的組件,讓我們的組件來進行展示
5.5.1.1 如何傳遞?
使用properties屬性
- 支持的類型
String、Number、Boolean、Object、Array、null(不限制類型)
- 默認值
可以通過value設置默認值
5.5.2 向組件傳遞樣式 - externalClasses
有時候我們不希望將樣式在組件內固定不變,而是外部可以決定樣式
使用externalClasses屬性
- 在Component對象中定義externalClasses屬性
- 在組件那的wxml中使用externalClasses屬性中的class
- 在頁面中傳入對應的class,并且給這個class設置樣式
5.5.3 組件向外傳遞事件 - 自定義事件
有時候自定義組件內部發生了事件,需要告知使用者,這個時候就可以使用自定義事件
5.5.4 頁面直接調用組件方法
在父組件里調用 this.selectComponent,獲取子組件的實例對象
調用時需要傳入一個匹配選擇器selector 如:this.selectComponent(".tabs")
5.6 插槽slot
5.6.1 現實生活中什么是插槽?
- 在生活中很多地方都有插槽,電腦的USB插槽,插板當中的電源插槽
- 插槽的目的是讓我們原來的設備具備更多的擴展性
- 比如電腦的USB我們可以插入U盤、硬盤、手機、音箱、鍵盤、鼠標等
5.6.2 組件的插槽
組件的插槽是為了讓我們封裝的組件更加具有擴展性,讓使用者可以決定組件內部的一些內容到底展示什么
例子
移動開發中,幾乎每個頁面都有導航欄
導航欄必然會封裝成一個插槽,比如nav-bar組件
一旦有了這個組件,我們就可以在多個頁面中進行復用了
但是我們并不能確保每個頁面中的導航欄是一模一樣的,整體樣式架構是一樣的可能里面的內容不一樣,這個時候就可以使用插槽
5.6.3 單個插槽的使用
除了內容和樣式可能由外界決定之外,也可能外界想決定顯示的方式,比如我們有一個組件定義了頭部和尾部,但是中間的內容可能是一段文字、圖片或者進度條,在不確定外界想插入什么其他組件的前提下,我們可以在組件內預留插槽
5.6.4 多個插槽的使用
有時候為了讓組件更加靈活,我們需要定義多個插槽
5.6.5 slot插槽使用默認值方案
前提:
在很多場景下我們希望自定義組件有較好的擴展性
,在不傳入slot的情況下默認展示默認的結構與樣式,但小程序中的slot沒有像vue中的slot一樣提供默認值,這時候我們可以通過偽類選擇器
:empty 和相鄰選擇器
+控制元素的display
來實現
- 使用自定義組件
<view>
<slot-item>
<button>我是一個按鈕</button>
</slot-item>
<slot-item></slot-item>
<slot-item>
<text style="color: red;">我是一個文本</text>
</slot-item>
</view>
- 實現自定義組件
wxml
<view class="container">
<view>我是header</view>
<view class="content">
<slot></slot>
</view>
<!-- 插槽默認值 -->
<view class="default">我是slot默認值</view>
<view>我是footer</view>
</view>
wxss
.default {
width: 200rpx;
height: 200rpx;
background-color: #f99;
text-align: center;
line-height: 200rpx;
margin: 0 auto;
/* 默認值默認不顯示 */
display: none;
}
/* 當插槽內為空時 通過相鄰選擇器將默認值顯示 */
.content:empty+.default {
display: block;
}
5.7 behaviors
behaviors用于組件間代碼共享的特性,類似于一些編輯語言中的"mixins"
- 每個behaviors可以包含一組屬性、數據、生命周期和方法
- 組件應用它時,它的屬性、數據和方法會被合并到組件中,生命周期也會在對應時機被調用
- 每個組件引用多個behavior,behavior也可以引用其它behavior
5.8 組件的生命周期
指的是組件自身的一些函數,這些函數在特殊的時間點或遇到一些特殊的框架事件時被觸發,最重要的生命周期是 created、attached、detached,包含了一個組件實例生命流程的最主要的時間點
2.2.3起,組件的生命周期也可以在lifetimes字段內進行聲明,推薦使用這個方式聲明,其優先級最高
Component({
lifetimes: {
attached: function() {
// 在組件實例進入頁面節點樹時執行
},
detached: function() {
// 在組件實例被從頁面節點樹移除時執行
},
},
// 以下是舊式的定義方式,可以保持對 <2.2.3 版本基礎庫的兼容
attached: function() {
// 在組件實例進入頁面節點樹時執行
},
detached: function() {
// 在組件實例被從頁面節點樹移除時執行
},
// ...
})
5.9 組件所在頁面的生命周期
還有一些特殊的生命周期,它們并非與組件有很強的關聯,但有時組件需要獲知,以便組件內部處理,這樣的生命周期稱為"組件所在頁面的生命周期",在pageLifetimes定義段中定義
Component({
pageLifetimes: {
show: function() {
// 頁面被展示
},
hide: function() {
// 頁面被隱藏
},
resize: function(size) {
// 頁面尺寸變化
}
}
})
5.10 Component構造器
-
properties
定義傳入的屬性
-
data
定義內部屬性
-
methods
定義方法
-
options
額外配置選項
-
externalClasses
引用外部樣式
-
observers
屬性和數據監聽
-
pageLifetimes
頁面生命周期
-
lifetimes
組件生命周期
6. 系統API調用
持續更新...