小程序自定義組件

微信小程序不支持自定義組件笼痹,只提供了一個(gè)非常受限制的模板功能,尤其缺乏了開發(fā)產(chǎn)品中最重要的幾個(gè)功能:
  • 模板內(nèi)的數(shù)據(jù)只能由當(dāng)前頁面?zhèn)鬟f识补,無法預(yù)先設(shè)置一些初始化數(shù)據(jù)以達(dá)到復(fù)用的目的冈钦;
  • 模板內(nèi)的數(shù)據(jù)變化無法通知到當(dāng)前頁面,也就是說模板不知道誰在使用它李请,只能在當(dāng)前頁面定義方法綁定在模板內(nèi)部的組件事件上來處理交互邏輯
  • 模板內(nèi)部無法預(yù)先設(shè)置一些內(nèi)部邏輯代碼。
這些局限性分分鐘叫人抓狂厉熟,這個(gè)模板功能只是實(shí)現(xiàn)了UI層復(fù)用的功能导盅,所有的邏輯代碼都需要在頁面上重新寫一遍。開發(fā)和維護(hù)的效率一下子回到了解放前揍瑟,再也沒法愉快地思考業(yè)務(wù)需求了白翻,先把這個(gè)坑補(bǔ)補(bǔ)。 大路貌似走不通,只能另辟彎道滤馍,曲線救國了岛琼。 解決思路:所有的頁面都通過全局Page函數(shù)來定義,它提供了一個(gè)onLaunch的觸發(fā)事件巢株,看來能在這里想想辦法槐瑞。我們大致需要這樣的自定義組件或者說是模板:
 /*這是一個(gè)組件基類*/
module.exports = class BaseComp {        
    constructor({ key, page, data = {} }) { 
               this.key = key      
              this.page = page      
              this.data = data      ...    }    
/*當(dāng)組件內(nèi)部數(shù)據(jù)變化后,能在這里更新頁面*/    
update(){}    
/*當(dāng)頁面觸發(fā)事件時(shí)阁苞,組件也應(yīng)該能捕捉到*/ 
onLoad() {} onReady() {} onShow() {} onHide() {} onUnload() {}}

/*這是一個(gè)文本框組件*/
module.exports = class FormInput extends BaseComp { 
            constructor( { key, page, data }) {  
                 /*這里可以定義一些默認(rèn)數(shù)據(jù)*/               
                 data = Object.assign({               
                         type: 'text',                        
                         label: '',                        
                         placeholder: '',                        
                         value:'', 
                         ...                        
                         focus: false                
              }, data)                
             super( { key, page, data })    
    }        
      onfocus(e){...}       
      onblur(e){...}          
      onchange(e){...}
}
小程序的視圖(wxml)和js無法像webpack那樣打包在一起困檩,所以只能利用現(xiàn)有的模板功能,把小程序原生組件組合成一個(gè)自定義組件那槽。
<template name="formInput">    
        <view>        
              <label>{{label}}</label>       
              <input type="{{type}}" class="{{focus?' active':''}}"
                      placeholder-class="{{placeholderClass}}"            
                      placeholder="{{placeholder}}"            
                      value="{{value}}"            
                      data-key="{{key}}"            
                      data-index=""            
                      bindfocus="_EventProxy"            
                      bindblur="_EventProxy" />        
              <text>{{message}}</text>                
        </view>
</template> 
1. 寫個(gè)Page函數(shù)悼沿,在App初始化之前中引入,把小程序的全局Page替換掉骚灸。在這個(gè)Page函數(shù)內(nèi)根據(jù)配置參數(shù)實(shí)例化自定義組件糟趾,把當(dāng)前頁面賦給組件的page屬性,并向組件傳入當(dāng)前頁面的'onLoad','onReady'等事件甚牲;
const Page = this.Page 
this.Page = function( config ) {
     if( config.components ) {        
          let onLoad = config.onLoad         
          config.onLoad = function() {            
                for( let key in config.components ) {                
                      let opts = config.components[ key ]                
                      opts.key = key                
                      opts.page = this                 
                      config.components[ key ] = new comp[ opts.is ]( opts ) 
                      config.components[ key ].onLoad( arguments ) 
                 }            
                if( onLoad ) { 
                       onLoad.call( this, arguments )           
                }       
         }
...... 
2. Page函數(shù)在當(dāng)前頁面上添加一個(gè)統(tǒng)一的事件代理(Proxy)义郑,自定義組件內(nèi)部的小程序原生組件上的事件全部指向這個(gè)代理方法,由這個(gè)事件代理根據(jù)事件對象判斷是由哪個(gè)自定義組件鳖藕、自定義組件內(nèi)的哪個(gè)原生組件觸發(fā)的魔慷,觸發(fā)的是哪個(gè)事件,然后再調(diào)用自定義組件的處理方法去執(zhí)行內(nèi)部邏輯著恩。
config._EventProxy = function( e ) {    
      let dset = e.currentTarget.dataset    
      let comp = config.components[ dset.key ]     
      /*        組件上定義的事件名必須為 on + event.type 
       data-index用來區(qū)分多個(gè)同名事件    */    
      let event = 'on' + e.type + dset.index   
      if( comp && comp[ event ] ) {        
          comp[ event ].call( comp, e )   
       }
}
最后再執(zhí)行小程序的Page函數(shù)
Page( config ) 
3. 自定義組件基類中實(shí)現(xiàn)了更新頁面數(shù)據(jù)的公共方法
update() {    
      let origin = this.page.data[this.key] || {}    
      let data = Object.assign({}, origin, this.data)     
      this.page.setData({       
           [this.key]: data    
      })
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末院尔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子喉誊,更是在濱河造成了極大的恐慌邀摆,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伍茄,死亡現(xiàn)場離奇詭異栋盹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)敷矫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門例获,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人曹仗,你說我怎么就攤上這事榨汤。” “怎么了怎茫?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵收壕,是天一觀的道長。 經(jīng)常有香客問我,道長蜜宪,這世上最難降的妖魔是什么虫埂? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮圃验,結(jié)果婚禮上掉伏,老公的妹妹穿的比我還像新娘。我一直安慰自己损谦,他們只是感情好岖免,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著照捡,像睡著了一般颅湘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上栗精,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天闯参,我揣著相機(jī)與錄音,去河邊找鬼悲立。 笑死鹿寨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的薪夕。 我是一名探鬼主播脚草,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼原献!你這毒婦竟也來了馏慨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤姑隅,失蹤者是張志新(化名)和其女友劉穎写隶,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讲仰,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慕趴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鄙陡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冕房。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖趁矾,靈堂內(nèi)的尸體忽然破棺而出毒费,到底是詐尸還是另有隱情,我是刑警寧澤愈魏,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響培漏,放射性物質(zhì)發(fā)生泄漏溪厘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一牌柄、第九天 我趴在偏房一處隱蔽的房頂上張望畸悬。 院中可真熱鬧,春花似錦珊佣、人聲如沸蹋宦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冷冗。三九已至,卻和暖如春惑艇,著一層夾襖步出監(jiān)牢的瞬間蒿辙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工滨巴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留思灌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓恭取,卻偏偏與公主長得像泰偿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子蜈垮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

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

  • 前言 微信小程序自1月19號發(fā)布后,可謂是有人歡喜有人憂啊.曾經(jīng)對它一度抱有各種期待的前端工作者們在張總的一句句:...
    LinDaiDai_霖呆呆閱讀 6,198評論 6 11
  • 注意:目前自定義組件相關(guān)特性處于公測階段耗跛。如果需要使用相關(guān)特性,請確認(rèn)在項(xiàng)目選項(xiàng)中已勾選“預(yù)覽/上傳時(shí)使用新特性”...
    YU_YU_閱讀 3,147評論 0 5
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,163評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理窃款,服務(wù)發(fā)現(xiàn)课兄,斷路器,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 原本就想能找個(gè)一個(gè)無人的地方寫一些不會有人看的文字晨继。算是在忙碌迷茫的人生中對自己的一次救贖吧烟阐。 原...
    怎么都存在啊閱讀 132評論 0 0