微信小程序自定義組件原理探究

組件化是web共郭、移動(dòng)開發(fā)的大趨勢(shì),一次開發(fā)多次使用糠馆,調(diào)用方便嘶伟,解耦性好。當(dāng)然在小程序開發(fā)是一個(gè)趨勢(shì)又碌。

官網(wǎng):https://mp.weixin.qq.com/debug/wxadoc/dev/component/

雖然說從自定義組件化有其官網(wǎng)介紹九昧,但是在開發(fā)過程中總是不盡如人意绊袋,踩過 幾次坑后還是決定自己基于基礎(chǔ)的原理按照極簡(jiǎn)的思想搞一下吧。

0x00 原理

本篇文章傾向于對(duì)于小程序或組件化原理有一定了解的群體铸鹰。說來很簡(jiǎn)單癌别,所謂的組件化包括幾個(gè)部分,類html,css,和js掉奄,這幾個(gè)部分分別控制元素规个,樣式,和代碼邏輯姓建,這幾個(gè)部分是要在被加載的地方分別把這三樣加入到容器里面去诞仓,可以說是重新為這個(gè)組件開辟了一塊內(nèi)存空間,重新在加載的地方渲染了樣式和元素速兔。簡(jiǎn)單點(diǎn)說是墅拭,在page中把模板里面的東西塞進(jìn)去,在一定的條件下顯示出來涣狗〉瘢或者說是把本來屬于本頁(yè)面的東西獨(dú)立開了放在了另外的文件里面。拆分出去的元素樣式和邏輯只是跟自己相關(guān)镀钓,加上一些數(shù)據(jù)傳遞和接收穗熬,就變成了組件。

0x01 插槽/模板加載

小程序里面有個(gè)template的東西丁溅,就是一個(gè)插槽唤蔗,在一次申明中

<template name="ShareData">
this is a template
</template>

即完成了包裝。里面的樣式寫法就是普通的方式窟赏,這就是模板的寫法
在需要用的時(shí)候,在wxml中引用它

<import src="ShareData"/>

0x01 CSS加載

樣式是在wxss里面設(shè)定的妓柜,在容器中添加

@import "../../componts/section/index";
@import "ShareData";

即可把樣式添加到對(duì)應(yīng)的page或其他組件中去。

0x02 JS加載與轉(zhuǎn)移

這個(gè)是重點(diǎn)涯穷,很多人并不知道組件化的根本原因是不知道組件的js屬性和方法是要添加到page里面去的棍掐。基于此其實(shí)也是兩句話的問題就可以完成導(dǎo)入方法和組件拷况。

做一個(gè)簡(jiǎn)單的例子作煌,實(shí)現(xiàn)sectioncontrol

let __outcomp__ = "__SegmentedControl__"
let SegmentedControl = {
  data: {
    radioValues: [
      {'value': '男','selected': false},
      {'value': '女','selected': true},
      {'value': '保密','selected': false},
    ],
clazz: ['selected','last']
  },
methods:{
indexChanged: function (e) {
// 點(diǎn)中的是組中第個(gè)元素
var index = e.target.dataset.index;
// 讀取原始的數(shù)組
var radioValues = this.data[__outcomp__].radioValues;
for (var i = 0; i < radioValues.length; i++) {
// 全部改為非選中
radioValues[i].selected = false;
// 當(dāng)前那個(gè)改為選中
radioValues[index].selected = true;
}
// 寫回?cái)?shù)據(jù)
this.setData({
[__outcomp__]: this.data[__outcomp__]
});
// clazz狀態(tài)
this.clazzStatus();
},
onLoad: function () {
// onLoad 比 onReady 更早調(diào)用,后者為選中時(shí)屏幕閃動(dòng)一下
this.clazzStatus();
},
clazzStatus: function () {
/* 此方法分別被加載時(shí)調(diào)用赚瘦,點(diǎn)擊某段時(shí)調(diào)用 */
// class樣式表如"selected last","selected"
var clazz = [];
// 參照數(shù)據(jù)源
var radioValues = this.data[__outcomp__].radioValues;
for (var i = 0; i < radioValues.length; i++) {
// 默認(rèn)為空串最疆,即普通按鈕
var cls = '';
// 高亮,追回selected
if (radioValues[i].selected) {
cls += 'selected ';
}
// 最后個(gè)元素, 追加last
if (i == radioValues.length - 1) {
cls += 'last ';
}
//去掉尾部空格
cls = cls.replace(/(\s*$)/g, '');
clazz[i] = cls;
}
// 寫回?cái)?shù)據(jù)
this.data[__outcomp__].clazz = clazz;
this.setData({
[__outcomp__]: this.data[__outcomp__]
});
}
},
};

function LoadSegmentedControl(fromData) {
let pages = getCurrentPages()
let curPage = pages[pages.length - 1]
Object.assign(curPage, SegmentedControl.methods);

curPage.setData({ [__outcomp__]: SegmentedControl.data });

console.log(curPage.data[__outcomp__])
return this;
}

module.exports = {
LoadSegmentedControl
};

重點(diǎn)看model.exports={LoadSegmentedControl},這其實(shí)是導(dǎo)出一個(gè)加載的方法的蚤告,這個(gè)方法用來把該組件中的data和method復(fù)制到當(dāng)前頁(yè)面中去。是的服爷,使用的是object.assign,另外data里面的數(shù)據(jù)是放到頁(yè)面data中的[outcomp]屬性值中杜恰。

0x03 數(shù)據(jù)傳遞

有幾種數(shù)據(jù)需要傳遞获诈,在wxml中如何傳遞,組件中的js如何更改里面的屬性心褐,組件間的數(shù)據(jù)如何傳遞舔涎。

還是基于模板的思想,從原理得知逗爹,組件中的標(biāo)簽和方法其實(shí)已經(jīng)加入到page中去了亡嫌,所以只需要去page樹中取值和方法即可。

如在加載模板的過程中如下傳遞數(shù)據(jù)
<template is="SegmentedControl" data='{{...SegmentedControl}}' />
這里有個(gè)技巧掘而,用...擴(kuò)展運(yùn)算符挟冠,把組件中的數(shù)據(jù)都一次性傳遞過來,并且傳遞之后的key和value都是同一個(gè)袍睡,這是es6的語法知染。

然而在js中的method需要改變屬性的方式則可以用

FSHeaderItemTap:function(e){
var index = e.currentTarget.dataset.idx;
console.log(e.currentTarget.dataset.idx);
this.data[outcomp].fsSelectIdx = e.currentTarget.dataset.idx;
this.setData({ [outcomp]: this.data[outcomp]})
if(index == 1){
LoadShareData();
}
},

可以看到,更改本組件中的屬性用的是this.data[outcomp]取值和賦值

0x04 應(yīng)用

組件與組件的嵌套斑胜,或者Page直接的使用都是用的這個(gè)原理控淡,在使用的過程中需要注意幾個(gè)規(guī)范,組件名要有前綴止潘,這樣方便查找方法和屬性掺炭。其他方式使用的命名空間就是這個(gè)作用吧。下面再來看看下面的界面凭戴,這高仿“阿拉丁小程序統(tǒng)計(jì)”的界面涧狮,有興趣的可以去看看如何實(shí)現(xiàn),結(jié)合本例原理簡(jiǎn)要分析一下簇宽。

image.png
極限水果勋篓,專注高端程序員技術(shù)與理財(cái)人生
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市魏割,隨后出現(xiàn)的幾起案子譬嚣,更是在濱河造成了極大的恐慌,老刑警劉巖钞它,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拜银,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡遭垛,警方通過查閱死者的電腦和手機(jī)尼桶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事启盛〈媾冢” “怎么了福澡?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵埋虹,是天一觀的道長(zhǎng)忿檩。 經(jīng)常有香客問我东抹,道長(zhǎng)秩冈,這世上最難降的妖魔是什么本缠? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮入问,結(jié)果婚禮上丹锹,老公的妹妹穿的比我還像新娘。我一直安慰自己芬失,他們只是感情好楣黍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著麸折,像睡著了一般锡凝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垢啼,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天窜锯,我揣著相機(jī)與錄音,去河邊找鬼芭析。 笑死锚扎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的馁启。 我是一名探鬼主播驾孔,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼惯疙!你這毒婦竟也來了翠勉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤霉颠,失蹤者是張志新(化名)和其女友劉穎对碌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒿偎,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡朽们,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诉位。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骑脱。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖苍糠,靈堂內(nèi)的尸體忽然破棺而出叁丧,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布歹袁,位于F島的核電站坷衍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏条舔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一乏矾、第九天 我趴在偏房一處隱蔽的房頂上張望孟抗。 院中可真熱鬧,春花似錦钻心、人聲如沸凄硼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)摊沉。三九已至,卻和暖如春痒给,著一層夾襖步出監(jiān)牢的瞬間说墨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工苍柏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尼斧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓试吁,卻偏偏與公主長(zhǎng)得像棺棵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子熄捍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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