微信小程序开发02-小程序基本介绍
前言
前面我們研究了下微信小程序的執(zhí)行流程,因?yàn)槟貌坏皆创a,只能算我們的猜想,我們需要更加了解小程序還需要做具體的項(xiàng)目,于是我們將原來那套還算復(fù)雜的業(yè)務(wù)拿出來:
【組件化開發(fā)】前端進(jìn)階篇之如何編寫可維護(hù)可升級(jí)的代碼(有些晦澀有些亂,但是對(duì)于整體了解小程序結(jié)構(gòu)有幫助)
我們用小程序?qū)崿F(xiàn)這里的代碼,看看是個(gè)什么樣的體驗(yàn),另外我這里想保證代碼最大程度重用,為后續(xù)一端代碼四端運(yùn)行做前驅(qū)探索。
頁面復(fù)雜度還是比較高的,包括了:
① 彈出層
② 頁面跳轉(zhuǎn)
③ 緩存
④ 數(shù)據(jù)請(qǐng)求
⑤ 列表頁、滾動(dòng)分頁
⑥ ......
我相信完成了這個(gè)例子,我們對(duì)小程序業(yè)務(wù)代碼怎么寫會(huì)有比較好的了解,于是讓我們開始今天的代碼吧。
小程序的布局
為什么不使用HTML&CSS
微信小程序這種平臺(tái)型的超越Hybrid系統(tǒng)誕生還是有一些客觀條件的,其中一個(gè)就是移動(dòng)端的應(yīng)用相對(duì)來說簡(jiǎn)單的多,想想PC負(fù)責(zé)的布局,如果要使用小程序?qū)崿F(xiàn),那么復(fù)雜度會(huì)提高很多。
小程序代碼編寫邏輯層依舊使用JS完成,但是結(jié)構(gòu)層以及樣式層推出了:
① WXML,Weixin Markup Language,是微信設(shè)計(jì)的一套標(biāo)簽語言,與HTML類似,做過React&Vue的同學(xué)會(huì)非常熟悉
② WXSS,WeiXin Style Sheets,是一套樣式語言,用于定義樣式,與CSS類似,一般認(rèn)為是CSS的子集
因?yàn)樾〕绦蛑蠻I組件都是Native實(shí)現(xiàn),所以小程序直接手起刀落壓根放棄讓我們使用HTML容器,這樣做我覺得有個(gè)好處是:
為了更好的限制,我之前也在做Hybrid乃至前端框架,一般來說我會(huì)限制到View級(jí)別的實(shí)習(xí),要求必須按照我的規(guī)則做,但是因?yàn)槿肟跒閕ndex.html文件,我甚至將全局控制器App的實(shí)例化放到了main.js里面,只提供了建議的做法,事實(shí)上HTML還是太過靈活,有些同事逐漸根本不按照我們的規(guī)則玩,他覺得他的做法更好,但是這樣一來便會(huì)破壞了項(xiàng)目的總體性,后續(xù)的工程性的優(yōu)化或者監(jiān)控可能就不能幫助他了,從某個(gè)角度來說,我是認(rèn)可小程序的做法的。
我們之前在這里研究過自定義標(biāo)簽的做法:從DOM操作看Vue&React的前端組件化,順帶補(bǔ)齊React的demo
1 <article class="cm-page page-list" id="main"> 2 <div class="js_sort_wrapper sort-bar-wrapper"> 3 <mySortBar :entity="sortEntity"></mySortBar> 4 </div> 5 <myList :entity="listEntity" :sort="sort"></myList> 6 </article>從這個(gè)文章以及小程序的實(shí)現(xiàn)可以看出基本的概念:
① 標(biāo)簽的出現(xiàn)根本不是做標(biāo)簽用,而是為了讓JS捕捉執(zhí)行相關(guān)邏輯,最后生成真正的標(biāo)簽
② 為了做更好的限制,小程序根本不提供入口index.html文件了,所以這里的標(biāo)簽是用作JS做模板解析后生成Native能識(shí)別的代碼,更具體點(diǎn)說是,Native實(shí)現(xiàn)了一個(gè)組件,組件有很多規(guī)則,可以使用JS去調(diào)用,正如我們這里的header組件調(diào)用邏輯(JS會(huì)設(shè)置Native的Header組件展示),這里如果不太清晰可以參考下這個(gè)文章:淺談Hybrid技術(shù)的設(shè)計(jì)與實(shí)現(xiàn)第二彈
當(dāng)然,小程序底層具體是不是這么做,我們不得而知,如果有小程序的同事,可以指導(dǎo)下:),至此,我覺得可以從技術(shù)層面說明為什么不直接使用HTML&CSS了:更好的業(yè)務(wù)限制 + 方便JS解析模板被Native執(zhí)行。
小程序組件
我們之前做Hybrid應(yīng)用的時(shí)候,事實(shí)上只提供了一個(gè)真正具有結(jié)構(gòu)的組件Header,其他loading類的提示組件都比較簡(jiǎn)單,而我們看看小程序提供了哪些組件呢:
容器類組件
view&scroll-view&swiper等作為容器組件存在,這里官方有基本介紹,我們這里看看其中一個(gè)即可:
這里官方給了一個(gè)demo進(jìn)行說明:
1 <view class="section"> 2 <view class="section__title">flex-direction: row</view> 3 <view class="flex-wrp" style="flex-direction:row;"> 4 <view class="flex-item bc_green">1</view> 5 <view class="flex-item bc_red">2</view> 6 <view class="flex-item bc_blue">3</view> 7 </view> 8 </view> 9 <view class="section"> 10 <view class="section__title">flex-direction: column</view> 11 <view class="flex-wrp" style="height: 300px;flex-direction:column;"> 12 <view class="flex-item bc_green">1</view> 13 <view class="flex-item bc_red">2</view> 14 <view class="flex-item bc_blue">3</view> 15 </view> 16 </view> 1 @import "../lib/weui.wxss"; 2 3 .page-section{ 4 margin-bottom: 20rpx; 5 } 6 .flex-wrp {display: flex;} 7 .bc_green {background: green;width:100px; height: 100px;} 8 .bc_red {background: red;width:100px; height: 100px;} 9 .bc_blue {background: blue;width:100px; height: 100px;}可以將這個(gè)標(biāo)簽理解為div類組件。
swipe
一般來說,Native提供的輪播圖體驗(yàn)要好得多,所以這里也提供了一個(gè)Native的組件:
1 <view class="container"> 2 <view class="page-body"> 3 <view class="page-section page-section-spacing swiper"> 4 <swiper 5 indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" circular="{{circular}}" vertical="{{vertical}}" 6 interval="{{interval}}" duration="{{duration}}" previous-margin="{{previousMargin}}px" next-margin="{{nextMargin}}px"> 7 <block wx:for="{{background}}" wx:key="*this"> 8 <swiper-item> 9 <view class="swiper-item {{item}}"></view> 10 </swiper-item> 11 </block> 12 </swiper> 13 </view> 14 <view class="page-section" style="margin-top: 40rpx;margin-bottom: 0;"> 15 <view class="weui-cells weui-cells_after-title"> 16 <view class="weui-cell weui-cell_switch"> 17 <view class="weui-cell__bd">指示點(diǎn)</view> 18 <view class="weui-cell__ft"> 19 <switch checked="{{indicatorDots}}" bindchange="changeProperty" data-property-name="indicatorDots" /> 20 </view> 21 </view> 22 <view class="weui-cell weui-cell_switch"> 23 <view class="weui-cell__bd">自動(dòng)播放</view> 24 <view class="weui-cell__ft"> 25 <switch checked="{{autoplay}}" bindchange="changeProperty" data-property-name="autoplay" /> 26 </view> 27 </view> 28 <view class="weui-cell weui-cell_switch"> 29 <view class="weui-cell__bd">銜接滑動(dòng)</view> 30 <view class="weui-cell__ft"> 31 <switch checked="{{circular}}" bindchange="changeProperty" data-property-name="circular" /> 32 </view> 33 </view> 34 <view class="weui-cell weui-cell_switch"> 35 <view class="weui-cell__bd">豎向</view> 36 <view class="weui-cell__ft"> 37 <switch checked="{{vertical}}" bindchange="changeProperty" data-property-name="vertical" /> 38 </view> 39 </view> 40 </view> 41 </view> 42 43 <view class="page-section page-section-spacing"> 44 <view class="page-section-title"> 45 <text>幻燈片切換時(shí)長(zhǎng)(ms)</text> 46 <text class="info">{{duration}}</text> 47 </view> 48 <slider value="{{duration}}" min="500" max="2000" bindchange="changeProperty" data-property-name="duration" /> 49 <view class="page-section-title"> 50 <text>自動(dòng)播放間隔時(shí)長(zhǎng)(ms)</text> 51 <text class="info">{{interval}}</text> 52 </view> 53 <slider value="{{interval}}" min="2000" max="10000" bindchange="changeProperty" data-property-name="interval" /> 54 <view class="page-section-title"> 55 <text>前邊距(px)</text> 56 <text class="info">{{previousMargin}}</text> 57 </view> 58 <slider value="{{previousMargin}}" min="0" max="50" bindchange="changeProperty" data-property-name="previousMargin" /> 59 <view class="page-section-title"> 60 <text>后邊距(px)</text> 61 <text class="info">{{nextMargin}}</text> 62 </view> 63 <slider value="{{nextMargin}}" min="0" max="50" bindchange="changeProperty" data-property-name="nextMargin" /> 64 </view> 65 </view> 66 </view> View Code 1 Page({ 2 data: { 3 background: ['demo-text-1', 'demo-text-2', 'demo-text-3'], 4 indicatorDots: true, 5 vertical: false, 6 autoplay: false, 7 circular: false, 8 interval: 2000, 9 duration: 500, 10 previousMargin: 0, 11 nextMargin: 0 12 }, 13 changeProperty: function (e) { 14 var propertyName = e.currentTarget.dataset.propertyName 15 var newData = {} 16 newData[propertyName] = e.detail.value 17 this.setData(newData) 18 }, 19 changeIndicatorDots: function (e) { 20 this.setData({ 21 indicatorDots: !this.data.indicatorDots 22 }) 23 }, 24 changeAutoplay: function (e) { 25 this.setData({ 26 autoplay: !this.data.autoplay 27 }) 28 }, 29 intervalChange: function (e) { 30 this.setData({ 31 interval: e.detail.value 32 }) 33 }, 34 durationChange: function (e) { 35 this.setData({ 36 duration: e.detail.value 37 }) 38 } 39 }) View Code有demo有代碼,還是比較清晰。
movable-area
提供一個(gè)可以移動(dòng)的區(qū)域,暫時(shí)沒想到應(yīng)用場(chǎng)景......
icon
圖標(biāo),小程序這邊還擴(kuò)展了一下,給了很多默認(rèn)的圖標(biāo)樣式,能滿足基本需求
text
文本
rich-text
富文本,用于展示文章,支持HTML,這里的nodes屬性建議使用數(shù)組,類型,還不如系統(tǒng)自己解析js算了,因?yàn)椴粫?huì)有人像這樣寫代碼(nodes看上去很蠢):
1 Page({ 2 data: { 3 html: '<div class="div_class" style="line-height: 60px; color: red;">Hello World!</div><script>console.log(1)</script>', 4 nodes: [{ 5 name: 'div', 6 attrs: { 7 class: 'div_class', 8 style: 'line-height: 60px; color: red;' 9 }, 10 children: [{ 11 type: 'text', 12 text: 'Hello World!' 13 }] 14 }] 15 }, 16 tap() { 17 console.log('tap') 18 } 19 })progress
進(jìn)度條
button
按鈕
checkbox
選擇框
form
表單相關(guān)
input
輸入框,小程序的數(shù)據(jù)流動(dòng)是單向的,每次數(shù)據(jù)更新,動(dòng)態(tài)調(diào)用setData改變數(shù)據(jù)便會(huì)觸發(fā)view更新,底層實(shí)現(xiàn)便不知道了;文本框值改變js需要自己去獲取
label
與html一致,用以點(diǎn)擊文字操作控件,主要用于文本框
picker&picker-view
用于級(jí)聯(lián)操作
navigator&function-page-navigator
頁面鏈接,這個(gè)組件感覺不利于跳轉(zhuǎn)收口,建議少用
其他組件請(qǐng)大家直接到這里來看demo,非常清晰:
https://developers.weixin.qq.com/miniprogram/dev/component/map.html#map
總結(jié)
可以看出,小程序Native層是將常用的HTML標(biāo)簽分別都實(shí)現(xiàn)了一次,使用這些組件可以拼接處任何復(fù)雜的組件。至于樣式方面,WXSS與CSS大同小異,其中主要區(qū)別是小程序沒有使用px而是使用的rpx,這個(gè)類似于rem的實(shí)現(xiàn),為了解決移動(dòng)端的適配問題而存在,總而言之,你在iPhone6設(shè)計(jì)搞上是多少px就寫成多少rpx就行,其余系統(tǒng)會(huì)幫你完成適配工作,這塊透明做的很好,后續(xù)樣式我們直接上實(shí)例即可。
小程序的生命周期
我們這里上一張圖:
這張圖不但真實(shí)反映了Page的生命周期,也將我們之前的猜想做了一個(gè)證明,解讀這張圖大概是這個(gè)意思(未必正確,如有錯(cuò)誤請(qǐng)指出):
Native層在載入小程序時(shí)候,起了兩個(gè)線程一個(gè)的view Thread一個(gè)是AppService Thread,我這邊理解下來應(yīng)該就是程序邏輯執(zhí)行與頁面渲染分離,也許是想優(yōu)化性能,這里更具體一點(diǎn)的解釋是(帶有猜測(cè)了):微信會(huì)開一個(gè)webview來執(zhí)行我們的JS邏輯,然后會(huì)開一個(gè)Native View UI執(zhí)行頁面渲染;兩個(gè)部分是彼此獨(dú)立的,頁面點(diǎn)擊時(shí)候觸發(fā)事件,View線程會(huì)獲取APPService服務(wù)線程(其實(shí)就是獲取webview),執(zhí)行其中的js邏輯;APPService執(zhí)行js邏輯改變數(shù)據(jù)通過setData調(diào)用,觸發(fā)一個(gè)JSCore通信,通知view線程執(zhí)行UI更新,這里結(jié)合這張圖做下理解:
① 微信打開一個(gè)小程序時(shí),主UI線程繼續(xù)運(yùn)行,開啟一個(gè)webview(我認(rèn)為這里的主線程就是view Thread,webview就是APPService線程,這里可能有誤)
② 主View等待構(gòu)建頁面命令,邏輯層開始載入js邏輯(編譯過),微信底層應(yīng)該會(huì)將WXML以及WXSS翻譯為JS代碼,邏輯層執(zhí)行JS代碼做一些初始化工作APP結(jié)束后,開始Page邏輯,而他這個(gè)圖只有Page的邏輯,沒有將app囊括進(jìn)去,這里也引發(fā)了我一個(gè)疑惑:我在onLoad的時(shí)候打了個(gè)斷點(diǎn),而頁面這個(gè)時(shí)候事實(shí)上已經(jīng)進(jìn)行了結(jié)構(gòu)層的渲染,也就是說頁面的WXML邏輯已經(jīng)執(zhí)行了:
如果要按照我現(xiàn)有的邏輯下做解釋的話,我認(rèn)為實(shí)例化Page的時(shí)候,執(zhí)行了一個(gè)create事件,但是小程序并沒有釋放onCreate事件讓我們做注冊(cè),所以我這里知識(shí)體系的基礎(chǔ)依舊是:
JS邏輯先于Native UI 執(zhí)行,頁面渲染是由實(shí)例化Page時(shí)候發(fā)出所以我覺得,這里的圖好像少了一部分(或者說我理解是有問題的):
③ 業(yè)務(wù)線程執(zhí)行實(shí)例化Page邏輯,引發(fā)onLoad、onShow事件,onShow的時(shí)候頁面初步渲染已經(jīng)結(jié)束,如果系統(tǒng)有異步數(shù)據(jù)或者其他再次數(shù)據(jù)渲染會(huì)執(zhí)行setData,引發(fā)Native UI更新,邏輯結(jié)束
但是微信給出的圖不可能是錯(cuò)的,而從圖上看,首次異步通知是由View Thread發(fā)起的,我這里就很是困惑了?,因?yàn)槲艺J(rèn)為邏輯發(fā)起者一定是邏輯層的js發(fā)出通知
總結(jié)
今天我們對(duì)小程序進(jìn)行了基本的了解學(xué)習(xí),明天我們持續(xù)完成我們的demo吧
轉(zhuǎn)載于:https://www.cnblogs.com/yexiaochai/p/9374374.html
總結(jié)
以上是生活随笔為你收集整理的微信小程序开发02-小程序基本介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 获取的输入内容,没有被P标签包裹的文本和
- 下一篇: 17-比赛1 A - Weak in t