小程序怎炊,七千多字知識點總結(jié)

1. 什么是小程序?

小程序是一種"不需要下載安裝"即可使用的應(yīng)用廓译,它實現(xiàn)了"觸手可及"的夢想评肆。使用起來方便快捷、用完即走

1.1 目前常見的小程序

  • 微信小程序
  • 支付寶小程序
  • 淘寶小程序
  • 抖音小程序
  • 頭條小程序
  • QQ小程序
  • 美團小程序
  • 等等
1.1.2 為什么各個平臺都需要支持小程序责循?

你有糟港,我也得有 大廠競爭格局中一個重要的一環(huán)。
小程序作為介于頁面和App之間的一項技術(shù)院仿,它有自身很大的優(yōu)勢 體驗比傳統(tǒng)H5頁面要好很多秸抚,相當于傳統(tǒng)的App,使用起來更加方便歹垫,不需要在應(yīng)用商店中下載安裝剥汤,甚至注冊登錄等麻煩操作。
小程序可以間接的動態(tài)為App添加新動態(tài) 傳統(tǒng)的App更新需要打包排惨,上架到應(yīng)用商店后需要通過審核用戶才能進行下載(App Store)吭敢,但是小程序可以在App不更新的情況下,動態(tài)為自己的應(yīng)用添加新的功能要求暮芭。

1.2 小程序由誰開發(fā)鹿驼?

  • 小程序的定位
    介于原生App和手機H5頁面之間的一個產(chǎn)品定位
  • 由此有一個疑問?小程序是由誰來開發(fā)呢辕宏?
    小程序開發(fā)工程師畜晰?
    由小程序的技術(shù)特點所決定的,比如微信小程序WXML瑞筐、WXSS凄鼻、JavaScript
    它更接近于前端的開發(fā)技術(shù)棧,所以小程序是由前端開發(fā)工程師來開發(fā)的

1.3 小程序的技術(shù)選型

1.3.1 原生小程序開發(fā)
  • 微信小程序
    WXML聚假、WXSS块蚌、JavaScript
  • 支付寶小程序
    AXML、ACSS膘格、JavaScript
1.3.2 選擇框架開發(fā)小程序
1.3.2.1 較少使用
  • mpvue

    mpvue是一個支持vue開發(fā)小程序的前端框架峭范,支持微信小程序、百度小程序瘪贱、頭條小程序虎敦、支付寶小程序游岳,框架在2018年之后就不再維護和更新了,目前已經(jīng)被放棄

  • wepy

    wepy是由騰訊開源的其徙,一款讓小程序支持組件化開發(fā)的框架,通過預編譯的手段讓開發(fā)者可以選擇自己喜歡的開發(fā)風格去開發(fā)小程序喷户,該框架目前維護的也較少唾那,不推薦使用

1.3.2.2 較常使用
  • uni-app

    由DCloud團隊開發(fā)和維護,uni-app是一個使用vue開發(fā)所有前端應(yīng)用的框架褪尝,開發(fā)者編寫一套代碼闹获,可以發(fā)布到Ios、Android河哑、Web(響應(yīng)式)避诽、以及各種小程序(微信/支付寶/百度/頭條/飛書/QQ/快手/釘釘/淘寶)、快應(yīng)用等多個平臺璃谨,uni-app目前是很多公司的技術(shù)選型沙庐,特別是希望適配移動端App的公司

  • taro

    由京東團隊開發(fā)和維護,taro是一個開放式 跨端 跨框架解決方案佳吞,支持使用React/Vue/Nerv等框架來開發(fā) (微信/京東/百度/支付寶/字節(jié)跳動/QQ/飛書)小程序 /H5/RN 等應(yīng)用拱雏,taro因為本身支持React、Vue的選擇底扳,給了我們更加靈活的選擇空間铸抑,特別是Taro3.x之后,支持Vue3衷模、React Hook 等寫法

  • uni- app和taro開發(fā)原生App
    • 無論是適配原生小程序還是原生App鹊汛,都有較多的適配問題,所以還是需要多了解原生的一些開發(fā)知識
    • 產(chǎn)品使用體驗整體相較于原生App差很多
    • 也有其他的技術(shù)選項來開發(fā)原生App
      • ReactNative
      • Flutter
1.3.3 需要掌握的預備知識
1.3.3.1 核心技術(shù)

頁面布局: WXML阱冶,類似于HTML
頁面樣式: WXSS刁憋,幾乎就是CSS(某些樣式屬性不支持,某些進行了增強熙揍,但是基本是一致的)
頁面腳本: JavaScript+WXS(WeixinScript)


如果之前已經(jīng)掌握了Vue或者React等框架開發(fā)职祷,那么學習小程序是更簡單的
因為里面的核心思想都是一致的 組件化開發(fā)、數(shù)據(jù)響應(yīng)式届囚、mustache語法有梆、事件綁定、等

2. 小程序架構(gòu)和配置

2.1 小程序的架構(gòu)模型

2.1.1 MVVM架構(gòu)
2.1.1.1 Vue的MVVM和小程序MVVM對比
vue
小程序
2.1.1.2 MVVM為什么好用呢意系?
  • DOM Listeners
    ViewModel層可以將DOM的監(jiān)聽綁定到Model層
  • Data Bindings
    ViewModel層可以將數(shù)據(jù)的變量泥耀,響應(yīng)式的反應(yīng)到View層

MVVM框架將我們從'命令式編程'轉(zhuǎn)移到'聲明式編程'

2.1.2 誰是小程序的宿主環(huán)境呢?

微信客戶端
宿主環(huán)境為了執(zhí)行小程序的各種文件WXML蛔添、WXSS痰催、JS

小程序基于WebView環(huán)境下時兜辞,WebView的 JS邏輯、DOM樹構(gòu)建夸溶、CSS解析逸吵、樣式計算、Layout缝裁、Paint(Composite) 都發(fā)生在同一線程扫皱,在 WebView 上執(zhí)行過多的Js邏輯可能會阻塞渲染,導致頁面卡頓捷绑,以此為前提下韩脑,小程序同時考慮了性能與安全,來用了目前稱為雙線程模型的架構(gòu)粹污。

2.1.3 雙線程模型
  • WXML模塊和WXSS樣式運行于渲染層段多,渲染層使用WebView線程渲染(一個程序有多個頁面,會使用多個WebView的線程)
  • JS腳本(app.js/home.js等) 運行于邏輯層壮吩,邏輯層使用JsCore運行JS腳本
  • 這兩個線程都會經(jīng)由微信客戶端(Native)進行中轉(zhuǎn)交互

2.2 小程序的配置文件

小程序很多開發(fā)需求被規(guī)定在了配置文件中
為什么這樣做进苍?
更利于開發(fā)效率
保證開發(fā)出來的小程序某些開發(fā)風格是一致的
比如導航欄-頂部TabBar 頁面路由等

2.2.1 常見的配置文件

project.config.json 項目配置文件,如項目名稱粥航、appid等
sitemap.json 小程序搜索相關(guān)的
app.json 全局配置

常用

  • pages 頁面路徑列表
    用于指定小程序由哪些頁面組成琅捏,每一項都對應(yīng)一個頁面的路徑(含文件名)信息
    小程序中所有的頁面都必須在pages中進行注冊
  • window 全局的默認窗口展示
    用戶指定窗口如何展示,其中還包含了很多其他的屬性
  • tabBar 頂部tab欄的展示

page.json 頁面配置

每個小程序頁面也可以使用.json文件來對本頁面的窗口表現(xiàn)進行配置
頁面中配置項在當前頁面會覆蓋app.json(全局配置)的window中相同的配置項

2.3 注冊小程序(App函數(shù))

每個小程序都需要在app.js中調(diào)用 App函數(shù) 注冊
在注冊時可以綁定對應(yīng)的生命周期函數(shù)递雀,在生命周期函數(shù)中執(zhí)行對應(yīng)的代碼

2.3.1 注冊App時柄延,一般會做些什么?
  • 判斷小程序的進入場景
    • 常見的打開場景
      • 群聊會話中打開
      • 小程序列表打開
      • 微信掃一掃打開
      • 另一個小程序打開等
    • 如何確定場景缀程?
      • 在onLaunch和onShow生命周期回調(diào)函數(shù)中搜吧,會有options參數(shù),其中有scene值 鏈接
  • 監(jiān)聽生命周期函數(shù)杨凑,在生命周期中執(zhí)行對應(yīng)的業(yè)務(wù)邏輯滤奈,比如在某個生命周期函數(shù)中進行登錄操作或者請求網(wǎng)絡(luò)數(shù)據(jù)
  • 因為App()實例只有一個,并且是全局共享的(單例對象)撩满,所以可以將一些共享的數(shù)據(jù)放在這里
    • 在App中定義全局的數(shù)據(jù)
    globalData: {
      userInfo: {name:"藍"}
    }
    
    • 在其他頁面中訪問
    onLoad(options) {
      const app = getApp()
      console.log(app.globalData)
    }
    

2.3 注冊頁面(Page函數(shù))

小程序中的每個頁面都有一個對應(yīng)的js文件蜒程,其中調(diào)用Page函數(shù)注冊頁面示例
在注冊時,可以綁定初始化數(shù)據(jù)伺帘,生命周期回調(diào)昭躺,事件處理函數(shù)等

2.3.1 注冊一個page頁面時,一般需要做些什么伪嫁?
  • 在生命周期函數(shù)中發(fā)送網(wǎng)絡(luò)請求领炫,從服務(wù)器獲取數(shù)據(jù)
  • 初始化一些數(shù)據(jù),以方便被wxml引用展示
  • 監(jiān)聽wxml中的事件张咳,綁定對應(yīng)的事件函數(shù)
  • 其他的一些監(jiān)聽
    • 頁面滾動
    • 上拉刷新
      • 配置當前監(jiān)聽頁面的json文件
        "enablePullDownRefresh": true (開啟上拉刷新)
      • 在代碼中進行監(jiān)聽
        onPullDownRefresh() {}
    • 下拉加載
      • 配置當前監(jiān)聽頁面的json文件
        "onReachBottomDistance": 0 (距離底部欄多少距離時開啟下拉加載)
      • 在代碼中進行監(jiān)聽
        onReachBottom() {}

2.4 page頁面的生命周期函數(shù)

3. WXSS-WXML-WXS語法

3.1 WXSS

是一套樣式語言,用于描述wxml的組件樣式,wxss用來決定wxml的組件應(yīng)該怎么顯示

3.1.1 小程序樣式的寫法
  • 行內(nèi)樣式
  • 頁面樣式
  • 全局樣式

三種樣式都可以作用于頁面的組件衰腌,如果有相同的樣式,優(yōu)先級的順序是:行內(nèi)樣式>頁面樣式>全局樣式

目前支持的選擇器

wxss優(yōu)先級與css類似

3.1.2 WXSS的擴展

wxss具有css大部分特性砚哗,同時為了更適合開發(fā)微信小程序,wxss對css進行了擴充及修改

3.1.2.1 尺寸單位

rpx(responsive pixel) 可以根據(jù)屏幕寬度進行自適應(yīng)族沃,規(guī)定屏幕寬度為750px
如在iPhone6上频祝,屏幕寬度為375px,共有375個物理像素脆淹,則750rpx = 375px = 750物理像素, 1rpx = 0.5px = 1物理像素沽一。

  • 建議
    開發(fā)微信小程序時設(shè)計師可以使用iPhone6作為視覺稿的標準
  • 注意
    在較小的屏幕上不可避免的會有一些毛刺


3.1.2.2 樣式導入

使用@import語句可以導入外聯(lián)樣式表盖溺,@import后跟需要導入的外聯(lián)樣式表的相對路徑,用;表示語句結(jié)束

/** 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語法

開發(fā)中烘嘱,界面上展示的數(shù)據(jù)并不是寫死的,而是會根據(jù)服務(wù)器返回的數(shù)據(jù)蝗蛙,或者用戶的操作來進行改變蝇庭,如果使用原生JS或者Jquery的話,我們需要通過操作DOM來進行頁面的更新捡硅,小程序和Vue一樣哮内,提供了插值語法,Mustache語法(雙大括號)

3.2.3 block標簽

某些情況下壮韭,我們需要使用 wx:if 或 wx:for 時北发,可能需要包裹一組或者多組組件標簽,我們希望對這一組或者多組標簽進行整體操作喷屋,這時就可以使用block標簽琳拨。

  • 注意
    <block/>并不是一個組件,它僅僅是一個包裝元素屯曹,不會在頁面中做任何渲染狱庇,只接受控制屬性
  • 好處
    將需要進行遍歷或者判斷的內(nèi)容進行包裹,將遍歷和判斷的屬性放在block標簽中恶耽,不影響普通屬性的閱讀密任,提高代碼的可讀性
3.2.4 邏輯判斷 wx:if - wx:elif - wx:else

有些時候,我們需要根據(jù)條件來決定一些內(nèi)容是否渲染驳棱,當條件為true時批什,view組件會渲染出來,當條件為false時社搅,view組件不會渲染出來

<view>
  <block wx:if="{{score>=90}}">
    <view>優(yōu)秀</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的區(qū)別
  • hidden 控制組件的隱藏和顯示暮的,無論條件組件始終都會被渲染
  • wx:if 控制組件是否渲染,wx:if 是惰性的淌实,如果在初始渲染條件為false是冻辩,該組件不會進行任何處理
  • 一般來說 wx:if 有更高的切換消耗 而 hidden 有更高的初始渲染消耗,如果需要頻繁切換拆祈,使用hidden恨闪。如果在運行時條件不大可能改變則使用wx:if
3.2.7 列表渲染
3.2.7.1 wx:for

為什么使用wx:for?
在實際開發(fā)中放坏,服務(wù)器經(jīng)常返回各種列表數(shù)據(jù)咙咽,我們不可能一一從列表中取出數(shù)據(jù)進行展示,需要通過for循環(huán)的方式來遍歷所有的數(shù)據(jù)淤年,一次性的進行展示

在組件中钧敞,我們可以使用wx:for來遍歷數(shù)組(字符串、數(shù)字)麸粮,默認情況下遍歷后wxml中可以使用一個變量index溉苛,保存的是當前遍歷數(shù)據(jù)的下標值,數(shù)據(jù)中對應(yīng)的某項的數(shù)據(jù)弄诲,使用變量名item獲取

<block>
  <!-- 遍歷一個數(shù)組 -->
  <view wx:for="{{['abc','aaa','ccc']}}">{{item}}</view>
  <!-- 遍歷一個字符串 -->
  <view wx:for="{{'hello 你好'}}">{{item}}</view>
  <!-- 遍歷一個數(shù)字 -->
  <view wx:for="{{5}}">{{item}}</view>
</block>
3.2.7.2 item/index名稱

默認情況下愚战,item/index的名字是固定的但是某些情況下我們可能想使用其他名稱,或者當出現(xiàn)多層變量時威根,名字會重復
使用wx:for-itemwx:for-index修改數(shù)組當前元素和下標的變量名

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.message}}
</view>
3.2.7.3 wx:key的值以兩種形式提供
  • 字符串凤巨,代表在for循環(huán)的array中item的某個property,該property的值需要是列表中唯一的字符串或者數(shù)字洛搀,且不能動態(tài)改變
  • 保留關(guān)鍵字*this敢茁,代表在for循環(huán)中的item本身,這種表示需要item本身是一個唯一的字符串或者數(shù)字

3.2 WXS

3.2.1 什么是WXS留美?
3.2.1.1 WXS(WeiXin Script) 是小程序的一套腳本語言彰檬,結(jié)合 WXML,可以構(gòu)建出頁面的結(jié)構(gòu)谎砾。

官方:WXS 與 JavaScript 是不同的語言逢倍,有自己的語言,并不和 JavaScript 一致景图。(不過基本一致)
WXS中目前只能使用ES5较雕,ES6的使用會報錯

3.2.2 為什么要設(shè)計WXS語言?
3.2.2.1 在WXML中是不能直接調(diào)用Page/Component中定義函數(shù)的; (雙線程模式)
<!-- 在vue中可以直接調(diào)用函數(shù) 但是在小程序中這樣調(diào)用是沒用的(以前這樣調(diào)用會報錯,現(xiàn)在不會報錯但是沒有任何結(jié)果顯示) -->
<view>結(jié)果:{{formatCount(value)}}</view>

但是某些情況下亮蒋,我們希望使用函數(shù)來處理WXML中WXML中的數(shù)據(jù)(類似于Vue中的過濾器)扣典,這個時候就可以使用WXS了

3.2.3 WXS使用的限制和特點:
  • WXS 不依賴于運行時的基礎(chǔ)庫版本,可以在所有版本的小程序中運行慎玖;
  • WXS 的運行環(huán)境和其他 JavaScript 代碼是隔離的贮尖,WXS中不能調(diào)用其他JavaScript文件中定義的函數(shù),也不能調(diào)用小程序提供的API趁怔;
  • 由于運行環(huán)境的差異湿硝,在IOS設(shè)備上小程序內(nèi)的WXS會比JavaScript代碼快 2~20 倍,在android設(shè)備上二者運行效率無差異润努;
3.2.4 WXS的寫法
3.2.4.1 WXS有兩種寫法:
  • 寫在<wxs>標簽中
  • 寫在以.wxs結(jié)尾的文件中
3.2.4.2 <wxs>標簽的屬性:
屬性名 類型 說明
module String 當前<wxs>標簽的模塊名关斜。必填字段。
src String 引用.wxs文件的相對路徑铺浇。僅當本標簽為單閉合標簽標簽內(nèi)容為空時有效蚤吹。
3.2.5 每一個.wxs文件和 <wxs> 標簽都是一個單獨的模塊。(一個wxml文件中可以引入多個wxs"module不能重復")
  • 每個模塊都有自己獨立的作用域随抠。即在一個模塊里面定義的變量與函數(shù),默認為私有的繁涂,對其他模塊不可見拱她;
  • 一個模塊想要對外暴露起內(nèi)部的私有變量,只能通過 module.exports實現(xiàn)扔罪;
3.2.6 WXS簡單案例
  • 傳入一個數(shù)字(整數(shù)或小數(shù))秉沼,格式化后進行展示(例如36456,展示結(jié)果3.6萬)

  • 傳入一個時間(秒)矿酵,格式化后進行展示(例如100秒唬复,展示結(jié)果為01:40)


  • wxml

<wxs module="format" src="/utils/format.wxs"></wxs>
<block>
  <view>傳入一個數(shù)字(整數(shù)或小數(shù)),格式化后進行展示(例如36456全肮,展示結(jié)果3.6萬)</view>
  <view>結(jié)果:{{format.formatCount(value)}}</view>
  <input type="number" model:value="{{value}}" class="my-input" />
</block>
<block>
  <view>傳入一個時間(秒)敞咧,格式化后進行展示(例如100秒,展示結(jié)果為01:40)</view>
  <view>結(jié)果:{{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函數(shù)
var patrn = getRegExp('(^[0-9]*$)');

  • 注意 使用getRegExp時里面不要帶/9枷佟P萁ā!评疗!
  • 錯誤 getRegExp('/(^[0-9]*$)/');
  • 正確 getRegExp('(^[0-9]*$)');

4. 事件處理

4.1 什么時候會產(chǎn)生事件测砂?

小程序需要經(jīng)常和用戶進行某種交互,比如點擊界面上的某個按鈕或者區(qū)域百匆,比如滑動了某個區(qū)域 等

4.2 什么是事件砌些?

事件是視圖層到邏輯層的通訊方式
事件可以將用戶的行為反饋到邏輯層進行處理
事件可以綁定在組件上,當觸發(fā)事件時加匈,就會執(zhí)行邏輯層中對應(yīng)的事件處理函數(shù)
事件對象可以攜帶額外信息存璃,如id仑荐、dataset、touches等

4.3 事件是如何處理的有巧?

  • 事件通過bind/catch這個屬性綁定在組建上的(和普通的屬性寫法很相似释漆,以key="value"形式)
  • key以bind或catch開頭,從1.5.0版本開始篮迎,可以在bind和catch后加一個冒號
  • 同時在當前頁面的Page構(gòu)造器中定義對應(yīng)的事件處理函數(shù)男图,如果沒有對應(yīng)的函數(shù),觸發(fā)事件時會報錯
    • 比如當用戶點擊該button區(qū)域時甜橱,達到觸發(fā)條件生成事件tap逊笆,該事件處理函數(shù)會被執(zhí)行,同時還會收到一個事件對象event

4.4 事件對象event

當某個事件觸發(fā)時岂傲,會產(chǎn)生一個事件對象难裆,并且這個對象被傳入到回調(diào)函數(shù)中

4.4.1 BaseEvent基礎(chǔ)事件對象屬性列表

4.5 current Target和target的區(qū)別

  • currentTarget 事件處理程序注冊的元素
  • target 事件觸發(fā)實際目標元素

4.6 touches和changedTouches的區(qū)別

  • 在touched中不同
  • 多手指觸摸時不同

4.7 事件參數(shù)傳遞

4.7.1 dataset

當視圖層發(fā)生事件時,某些情況需要事件攜帶一些參數(shù)到執(zhí)行的函數(shù)中镊掖,這個時候就可以通過data-屬性來完成

  • 格式 data-屬性的名稱
  • 獲取 e.currentTarget.dataset.屬性的名稱
4.7.2 mark

版本2.7.1以上才可以使用

使用mark來識別具體觸發(fā)事件的target節(jié)點乃戈,還可以用于承載一些自定義數(shù)據(jù)
當事件觸發(fā)時,事件冒泡路徑上所有的mark會被合并亩进,并返回給事件回調(diào)函數(shù)
即使事件不是冒泡事件症虑,也會mark
如何存在同名的mark,父節(jié)點的mark會被子節(jié)點的覆蓋
在自定義組件中接收事件時归薛,mark不包含自定義組件外的節(jié)點的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的區(qū)別
  • mark會包含從觸發(fā)事件的節(jié)點到根節(jié)點上的所有的mark屬性值
  • dataset僅包含一個節(jié)點的data-屬性值
  • dataset的值會做大小寫的轉(zhuǎn)換谍憔,mark不會做大小寫的轉(zhuǎn)換

4.8 事件冒泡和事件捕獲

當界面產(chǎn)生了一個事件時,事件分為了捕獲階段和冒泡階段


5. 組件化開發(fā)

1.6.3版本后小程序才開始支持自定義組件的開發(fā)

5.1 組件化思想的應(yīng)用

  • 盡可能的將頁面拆分成一個個小的主籍、可復用的組件
  • 讓代碼更加方便組織和管理习贫,并且擴展性也更強

5.2 創(chuàng)建一個組件

類似于頁面,自定義組件由json wxml wxss js四個文件組成
首先先在根目錄下創(chuàng)建一個文件夾components千元,在里面存放后續(xù)新建的自定義組件

  • 自定義組件的步驟

    • 首先需要先在創(chuàng)建的自定義組件的json文件中進行自定義組件的聲明(將component字段設(shè)置為true)
    • 在wxml中編寫組件自己的模版
    • 在wxss中編寫組件自己的相關(guān)樣式
    • 在js文件中可以定義數(shù)據(jù)或組件內(nèi)部的相關(guān)邏輯

5.3 使用自定義組件和細節(jié)注意事項

自定義組件也是可以引用自定義組件的苫昌,引用方法類似于頁面引用自定義組件的方法(使用usingComponents字段)
自定義組件和頁面所在項目根目錄名不能以"wx-"為前綴,否則會報錯
如果在app.json和usingComponents聲明某個組件诅炉,那么所有頁面和組件都可以直接使用該組件

5.4 組件的樣式細節(jié)

5.4.1 組件內(nèi)的樣式 對 外部樣式 的影響
  • 組件內(nèi)的class樣式蜡歹,只對組件wxml內(nèi)的節(jié)點生效,對引用組件的Page頁面不生效
  • 組件內(nèi)不能使用id選擇器涕烧、屬性選擇器月而、標簽選擇器
5.4.2 外部樣式 對 組件內(nèi)的樣式 的影響
  • 外部使用class的樣式,只對外部wxml的class生效议纯,對組件內(nèi)是不生效的
  • 外部使用了id選擇器父款、屬性選擇器不會對組件內(nèi)產(chǎn)生影響
  • 外部使用了標簽選擇器,會對組件內(nèi)產(chǎn)生影響
5.4.3 如何讓class可以相互影響
  • 在Component中,可以傳入一個options屬性憨攒,其中options屬性中有一個styleIsolation(隔離)屬性
  • styleIsolation常用的三個值
    • isolated 表示啟動樣式隔離世杀,在自定義組件內(nèi)外,使用class指定的樣式將不會互相影響
    • apply-shared 表示頁面wxss樣式將影響到自定義組件肝集,但自定義組件wxss中指定的樣式不會影響頁面
    • shared 表示頁面wxss樣式將影響到自定義組件瞻坝,自定義組件wxss中指定的樣式也會影響頁面和其他設(shè)置

5.5 組件的通訊

很多情況下,組件內(nèi)展示的內(nèi)容(數(shù)據(jù)杏瞻、樣式所刀、標簽)并不是在組件內(nèi)寫死的,而是可以由使用者來決定的

5.5.1 向組件傳遞數(shù)據(jù) - properties

給組件傳遞數(shù)據(jù)

大部分情況下捞挥,組件只負責布局和樣式浮创,內(nèi)容是由使用組件的對象決定的,所以經(jīng)常需要從外部傳遞數(shù)據(jù)給我們的組件砌函,讓我們的組件來進行展示

5.5.1.1 如何傳遞斩披?

使用properties屬性

  • 支持的類型 String、Number讹俊、Boolean垦沉、Object、Array仍劈、null(不限制類型)
  • 默認值 可以通過value設(shè)置默認值
5.5.2 向組件傳遞樣式 - externalClasses

有時候我們不希望將樣式在組件內(nèi)固定不變乡话,而是外部可以決定樣式
使用externalClasses屬性

  • 在Component對象中定義externalClasses屬性
  • 在組件那的wxml中使用externalClasses屬性中的class
  • 在頁面中傳入對應(yīng)的class,并且給這個class設(shè)置樣式
5.5.3 組件向外傳遞事件 - 自定義事件

有時候自定義組件內(nèi)部發(fā)生了事件耳奕,需要告知使用者,這個時候就可以使用自定義事件

5.5.4 頁面直接調(diào)用組件方法

在父組件里調(diào)用 this.selectComponent诬像,獲取子組件的實例對象
調(diào)用時需要傳入一個匹配選擇器selector 如:this.selectComponent(".tabs")

5.6 插槽slot

5.6.1 現(xiàn)實生活中什么是插槽屋群?
  • 在生活中很多地方都有插槽,電腦的USB插槽坏挠,插板當中的電源插槽
  • 插槽的目的是讓我們原來的設(shè)備具備更多的擴展性
  • 比如電腦的USB我們可以插入U盤芍躏、硬盤、手機降狠、音箱对竣、鍵盤、鼠標等
5.6.2 組件的插槽

組件的插槽是為了讓我們封裝的組件更加具有擴展性榜配,讓使用者可以決定組件內(nèi)部的一些內(nèi)容到底展示什么

例子
移動開發(fā)中否纬,幾乎每個頁面都有導航欄
導航欄必然會封裝成一個插槽,比如nav-bar組件
一旦有了這個組件蛋褥,我們就可以在多個頁面中進行復用了
但是我們并不能確保每個頁面中的導航欄是一模一樣的临燃,整體樣式架構(gòu)是一樣的可能里面的內(nèi)容不一樣,這個時候就可以使用插槽

5.6.3 單個插槽的使用

除了內(nèi)容和樣式可能由外界決定之外,也可能外界想決定顯示的方式膜廊,比如我們有一個組件定義了頭部和尾部乏沸,但是中間的內(nèi)容可能是一段文字、圖片或者進度條爪瓜,在不確定外界想插入什么其他組件的前提下蹬跃,我們可以在組件內(nèi)預留插槽


5.6.4 多個插槽的使用

有時候為了讓組件更加靈活,我們需要定義多個插槽


5.6.5 slot插槽使用默認值方案

前提:
在很多場景下我們希望自定義組件有較好的擴展性铆铆,在不傳入slot的情況下默認展示默認的結(jié)構(gòu)與樣式蝶缀,但小程序中的slot沒有像vue中的slot一樣提供默認值,這時候我們可以通過偽類選擇器:empty相鄰選擇器+控制元素的display來實現(xiàn)

  • 使用自定義組件
<view>
  <slot-item>
    <button>我是一個按鈕</button>
  </slot-item>
  <slot-item></slot-item>
  <slot-item>
    <text style="color: red;">我是一個文本</text>
  </slot-item>
</view>
  • 實現(xiàn)自定義組件

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;
}

/* 當插槽內(nèi)為空時 通過相鄰選擇器將默認值顯示 */
.content:empty+.default {
  display: block;
}

5.7 behaviors

behaviors用于組件間代碼共享的特性算灸,類似于一些編輯語言中的"mixins"

  • 每個behaviors可以包含一組屬性扼劈、數(shù)據(jù)、生命周期和方法
  • 組件應(yīng)用它時菲驴,它的屬性荐吵、數(shù)據(jù)和方法會被合并到組件中,生命周期也會在對應(yīng)時機被調(diào)用
  • 每個組件引用多個behavior赊瞬,behavior也可以引用其它behavior

5.8 組件的生命周期

指的是組件自身的一些函數(shù)先煎,這些函數(shù)在特殊的時間點或遇到一些特殊的框架事件時被觸發(fā),最重要的生命周期是 created巧涧、attached薯蝎、detached,包含了一個組件實例生命流程的最主要的時間點


2.2.3起谤绳,組件的生命周期也可以在lifetimes字段內(nèi)進行聲明占锯,推薦使用這個方式聲明,其優(yōu)先級最高

Component({
  lifetimes: {
    attached: function() {
      // 在組件實例進入頁面節(jié)點樹時執(zhí)行
    },
    detached: function() {
      // 在組件實例被從頁面節(jié)點樹移除時執(zhí)行
    },
  },
  // 以下是舊式的定義方式缩筛,可以保持對 <2.2.3 版本基礎(chǔ)庫的兼容
  attached: function() {
    // 在組件實例進入頁面節(jié)點樹時執(zhí)行
  },
  detached: function() {
    // 在組件實例被從頁面節(jié)點樹移除時執(zhí)行
  },
  // ...
})

5.9 組件所在頁面的生命周期

還有一些特殊的生命周期消略,它們并非與組件有很強的關(guān)聯(lián),但有時組件需要獲知瞎抛,以便組件內(nèi)部處理艺演,這樣的生命周期稱為"組件所在頁面的生命周期",在pageLifetimes定義段中定義


Component({
  pageLifetimes: {
    show: function() {
      // 頁面被展示
    },
    hide: function() {
      // 頁面被隱藏
    },
    resize: function(size) {
      // 頁面尺寸變化
    }
  }
})

5.10 Component構(gòu)造器

  • properties 定義傳入的屬性
  • data 定義內(nèi)部屬性
  • methods 定義方法
  • options 額外配置選項
  • externalClasses 引用外部樣式
  • observers 屬性和數(shù)據(jù)監(jiān)聽
  • pageLifetimes 頁面生命周期
  • lifetimes 組件生命周期

6. 系統(tǒng)API調(diào)用

持續(xù)更新...


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桐臊,一起剝皮案震驚了整個濱河市胎撤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌断凶,老刑警劉巖伤提,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異认烁,居然都是意外死亡飘弧,警方通過查閱死者的電腦和手機识藤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來次伶,“玉大人痴昧,你說我怎么就攤上這事」谕酰” “怎么了赶撰?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長柱彻。 經(jīng)常有香客問我豪娜,道長,這世上最難降的妖魔是什么哟楷? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任瘤载,我火速辦了婚禮,結(jié)果婚禮上卖擅,老公的妹妹穿的比我還像新娘鸣奔。我一直安慰自己,他們只是感情好惩阶,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布挎狸。 她就那樣靜靜地躺著,像睡著了一般断楷。 火紅的嫁衣襯著肌膚如雪锨匆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天冬筒,我揣著相機與錄音恐锣,去河邊找鬼。 笑死舞痰,一個胖子當著我的面吹牛侥蒙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匀奏,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼学搜!你這毒婦竟也來了娃善?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤瑞佩,失蹤者是張志新(化名)和其女友劉穎聚磺,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炬丸,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡瘫寝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年蜒蕾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焕阿。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡咪啡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出暮屡,到底是詐尸還是另有隱情撤摸,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布褒纲,位于F島的核電站准夷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏莺掠。R本人自食惡果不足惜衫嵌,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望彻秆。 院中可真熱鬧楔绞,春花似錦、人聲如沸掖棉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幔亥。三九已至耻讽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帕棉,已是汗流浹背针肥。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留香伴,地道東北人慰枕。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像即纲,于是被迫代替她去往敵國和親具帮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容