在Amaple單頁應用中,一個頁面其實存在兩種模塊化單位,分別是
模塊 (am.Module類),它是以web單頁應用跳轉更新為最小單位所拆分的獨立塊;
組件 (am.Component類),它的定位是擁有特定功能的封裝塊,就像由一堆代碼封裝成的具有特定功能的函數一樣,一個組件也有獨立的視圖、狀態數據對象、組件行為以及生命周期。常用的組件有Dialog、Bubble、Navigator和Menubar等。
在模塊中定義并使用一個簡單的組件衍生類使用am.class類構造器繼承am.Component類定義一個組件,而繼承am.Component創建的類被稱為 組件衍生類 ,你可以這樣定義一個組件衍生類:
// 在am.class函數的參數中指定該組件衍生類的類名,它返回指定名稱的組件衍生類
// 類名須遵循首字母大寫的駝峰式命名規范,如"BubbleDemo",否則將會報錯。但接收變量名沒有限制
var BubbleDemo = am.class ( "BubbleDemo" ).extends ( am.Component ) ( {
// 在init函數返回該組件的狀態數據對象
init : function () {
return {
bubbleText: "this is a component bubble"
};
},
// 組件中必須定義render函數,在該函數中指定組件的template模板和樣式
render : function () {
this.template ( "{{ bubbleText }}" )
.style ( {
span: { background: "red", fontSize: 20, padding: "10px 16px" }
// !注意:當元素選擇器為符合變量命名規則時可不用引號,如上面選擇span元素時。當選擇器不符合變量名規則時需使用引號,如:
// ".class-name": { fontSize: 15 }
// "span #id": { margin-top: 24 }
} );
// this.template ( templateHTML )函數中傳入html字符串來定義該組件的視圖
// this.style ( styleObj )函數為該組件的視圖定義樣式,這些樣式也只作用于組件視圖
// 需注意的是該函數傳入一個對象,對象屬性名為css選擇器語法,值為css樣式對象,樣式名也是使用駝峰式表示,樣式值為量值時可直接寫為數字
}
} );
在一個模塊中使用 組件衍生類 渲染組件視圖也是非常簡單的,首先在am.startRouter函數中配置組件加載的baseURL:
am.startRouter ( { baseURL : { // ... // 為組件文件設置base路徑,所有的組件文件請求路徑都將基于“/component”目錄,不設置時默認“/” component: "/component" }, // ... } );
然后在需要使用的模塊或組件中通過import函數引入,并在中通過自動以標簽名來使用組件
組件生命周期
與模塊生命周期階段數一樣,一個組件從創建到卸載也分為5個階段的生命周期,具體如下:
init:組件初始化時觸發,它返回組件模板解析與掛載所使用的狀態數據。init函數內可調用this.propsType函數進行props參數驗證。
props相關知識將在本章節的后面部分介紹
render:渲染組件視圖時觸發,該生命周期函數內可分別調用this.template函數定義視圖標簽的字符串,和this.style函數為組件視圖添加樣式
mounted:解析并掛載狀態數據到組件視圖后觸發,你可以在此函數中處理一些視圖解析完成后的操作,如為此組件請求網絡數據并更新到模板等
updated:當組件在頁面中的位置改變時觸發,在組件上使用:for指令時將會渲染多個組件,此時改變:for指令所綁定的狀態數組時將可能改變組件的位置
unmount:組件卸載時觸發,有兩種情況將會卸載組件:
①. 通過:for指令渲染多個組件視圖后,調用綁定的狀態數組的變異函數都可能在頁面上卸載一個或多個組件;
②. 當一個模塊或組件被卸載時,該模塊或組件中的組件也將會卸載。
我們已經知道組件是一個擁有特定功能的封裝塊,所以它會有自己特定的 組件行為 ,如Dialog組件有打開和關閉行為,輪播圖組件有翻頁行為等。你可以這樣定義 組件行為 :
var Dialog = am.class ( "Dialog" ).extends ( am.Component ) ( { init : function () { return { open: false, text: "" }; }, render : function () { this.template ( [ "# 組件行為的兩種使用方法", "{{ text }}", "" ].join ( "" ) ); }, // 添加action成員函數,該函數返回組件行為的函數集合對象,該對象被稱為組件行為對象 // action函數的this指針也是指向該組件對象本身 action : function () { var _this = this; return { // 組件行為函數的this指針不會指向任何值 // 通過state.open來控制Dialog視圖的隱藏與顯示 open: function ( text ) { _this.state.text = text; _this.state.open = true; }, close: function () { _this.state.open = false; } }; } } );
[1]在組件的生命周期函數mounted、update和unmount中可通過this.action使用組件行為對象;
[2]在組件元素上使用:ref指令,調用module.refs函數獲取組件引用時將返回該組件的組件行為對象。
嵌套組件組件與組件之間配合使用可以發揮更強大的組件能力,在一個組件的模板中可以嵌套其他組件,你可以這樣寫:
// ComponentB組件依賴ComponentA組件 // ComponentA組件的編寫與普通組件編寫相同,這里省略 var CompoenntB = am.class ( "CompoenntB" ).extends ( am.Component ) ( { // 在構造函數中通過this.depComponents來指定該組件的依賴組件數組 constructor : function () { // 和ES6的class關鍵字定義類一樣,在構造函數中需首先調用super()函數,否則將會拋出錯誤 this.__super (); this.depComponents = [ ComponentA ]; }, init : function () { ... }, render : function () { this.template ( "" ); } } );
當ComponentA和ComponentB組件都編寫在多帶帶的文件中時,你需要在模塊中同時引入 組件 及 嵌套組件 ,像這樣:
...組件與組件、組件與模塊之間的通信
組件作為一個多帶帶的封裝塊,它必須與其他組件或模塊進行通信,你可以在模塊中分發數據到不同組件,也可以在組件中分發數據到嵌套組件中。在組件中可以使用props進行數據的通信,使用subElements進行html模板塊分發。
# 使用props傳遞靜態值# 使用props傳遞動態值
props還支持使用插值表達式的方式傳遞狀態數據,這被稱為 動態props 。動態props將創建一個對外部狀態數據的代理屬性,當在組件內更改了此代理屬性時,外部對應的狀態數據也將同步更新。如下:
在使用Dialog組件的視圖中,將狀態屬性text傳入組件后,組件的this.props.text即為該狀態屬性的代理屬性。
在Dialog組件的代碼中,可通過this.props.text獲取外部傳遞的text狀態屬性。
am.class ( "Dialog" ).extends ( am.Component ) ( { init : function () { return { // 使用text1接收并使用this.props.text的值 text1: this.props.text, // 如果你希望更新外部的text屬性后,組件視圖中掛載了this.props.text數據的地方也同步更新, // 你可以在組件中創建一個計算屬性作為this.props.text的代理,如下創建的text2計算屬性: computed: { var _this = this; text2: { get: function () { return _this.props.text; }, set: function ( newVal ) { _this.props.text = newVal; } } // 因為組件內對this.props.text的值更新后,外部的text狀態屬性也會同步更新,反之也成立 // 這樣在組件視圖中掛載text2就等于掛載props.text // 此時需注意的是,更改text2的值也將同步更改外部text屬性的值 } }; }, // ... } );# props驗證
當你希望開放你所編寫的組件給其他開發者使用時,你不確定其他開發者傳入的props參數是否符合組件內的處理要求,此時你可以為你的組件設置props數據驗證,你可以在組件的init函數內調用this.propsType函數進行驗證:
am.class ( "Dialog" ).extends ( am.Component ) ( { init : function () { // 每項值的驗證都可以設置validate、require和default屬性 this.propsType ( { text: { validate: String, // 表示當傳入text值時它必須為字符串 require: true, // 表示text參數為必須傳入的參數,默認為false default: "Have no message" // 表示不傳入text參數時的默認值,默認值不會參與props驗證,不指定default時無默認值 // validate的值可以有四種類型的參數,分別為: // ①. 基礎數據構造函數,分別有String、Number、Boolean三種基本數據類型構造函數,Function、Object、Array三種引用類型構造函數, // 以及undefined和null,它表示允許傳入的數據類型 // ②. 正則表達式,如/^1d{10}$/表示只允許傳入一個手機號碼 // ③. 函數,它接收此props參數值,必須返回true或false表示是否通過驗證,如: // function ( text ) { return text.length > 5 } // ④. 數組,數組內是以上三種值的組合,通過數組內任意一項驗證都可以通過,相當于“||”運算符 } // 當text屬性驗證只要設置validate屬性時,可直接如下縮寫: // text: String } ); return { text: this.props.text }; }, // ... } );使用subElements分發html片段
如果你想開發一個更加通用的Dialog組件,你應該不希望Dialog的視圖布局是固定不變的,而是可以根據不同的需求自定義Dialog視圖,因為這樣才顯得更加靈活多變,組件的subElements就是用來解決這個問題的,它可以使你從組件外部傳入html片段與組件視圖混合:
然后在組件內通過subElements屬性獲取外部傳遞的視圖,并插入到組件視圖中的任意位置。subElement接收的視圖可分為 默認subElements 、 subElements的單數分塊 和 subElements的不定數分塊 三種形式。
# 默認subElements在組件元素中傳入html片段時,組件內將會創建一個默認的subElements局部變量,你可以在組件內的模板中通過{{ subElements.default }}插入此html片段:
am.class ( "Dialog" ).extends ( am.Component ) ( { init : function () { ... }, render : function () { // {{ subElements.default }}將會輸出外部傳入的“this is external HTML template” this.template ( "{{ subElements.default }}" ); } // ... } );
Dialog組件將會被渲染成:
this is external HTML template
【注意】分發的html片段也可以使用模板指令與組件,此html片段解析時掛載的數據來源是組件外部的狀態數據,如下:
# subElements的單數分塊
如果你希望開發的Dialog分為頭部和內容兩部分視圖,再混合到組件模板的不同位置,subElements也允許你這樣編寫html片段:
am.class ( "Dialog" ).extends ( am.Component ) ( { init : function () { ... }, render : function () { // 指定分塊的組件子元素名 // 組件子元素名也需遵循首字母大寫的駝峰式規則,在組件元素內使用時也是全部小寫的中劃線式規范 this.subElements ( "Header", "Content" ) .template ( [ "", "" ].join ( "" ) ); //{{ subElements.Header }}", "{{ subElements.Content }}", "、 兩個子元素只能作為
此時Dialog組件將會被渲染成:
this is a titlethis is external HTML template
【注意】①. 如沒有在this.subElements函數中定義相應的組件子元素時,Amaple只會將它們作為普通dom元素對待。# subElements的不定數分塊
②. 除、 外的其他html片段會自動包含在subElements.default中。
subElements的分塊分發可能會讓你想到很多原生的元素,如 在組件中這樣定義不定數分塊的subElements: 繼續學習下一節:【AmapleJS教程】5. 插件 文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。 轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92717.html 摘要:體驗優先的單頁框架點此查看倉庫是專為單頁應用而設計的基于頁面模塊化的框架,它可使開發者快速開發單頁應用。使用前置要求此框架的使用者可不需了解構建工具,但必須掌握和的基礎知識。
showImg(https://segmentfault.com/img/bV2wO3?w=792&h=303);
Amaple · 體驗優先的JavaScript單頁框架
Amaple (點此查看Github倉... 摘要:體驗優先的單頁框架點此查看倉庫是專為單頁應用而設計的基于頁面模塊化的框架,它可使開發者快速開發單頁應用。使用前置要求此框架的使用者可不需了解構建工具,但必須掌握和的基礎知識。
showImg(https://segmentfault.com/img/bV2wO3?w=792&h=303);
Amaple · 體驗優先的JavaScript單頁框架
Amaple (點此查看Github倉... 摘要:體驗優先的單頁框架點此查看倉庫是專為單頁應用而設計的基于頁面模塊化的框架,它可使開發者快速開發單頁應用。使用前置要求此框架的使用者可不需了解構建工具,但必須掌握和的基礎知識。
showImg(https://segmentfault.com/img/bV2wO3?w=792&h=303);
Amaple · 體驗優先的JavaScript單頁框架
Amaple (點此查看Github倉... 摘要:參數為循環遍歷時的回調函數,它分別接收遍歷項的值遍歷下表遍歷變量本身三個參數,當回調函數返回時將結束本次循環,而且此時執行結束后也將會返回一個,這在結束多層循環遍歷時很有用,開發者可以通過再次推出上層循環。
Amaple 擁有非常強大插件功能,這也是它的突出功能之一,Amaple插件一般表現為功能塊(函數)或功能塊(包含一系列函數和屬性的Object對象),它除了支持Amaple規范... 閱讀 1411·2021-10-08 10:04 閱讀 733·2021-09-07 09:58 閱讀 2912·2019-08-30 15:55 閱讀 2424·2019-08-29 17:21 閱讀 2126·2019-08-28 18:04 閱讀 3075·2019-08-28 17:57 閱讀 715·2019-08-26 11:46 閱讀 2228·2019-08-23 17:20和、和、
和
等,他們都屬于包含與被包含的關系,但你會發現其實 中可以定義一個或多個,在subElements中你也可以定義一個 組件子元素 的不定數分塊,如Grid組件(網格)可包含不定個數的GridItem:
am.class ( "Grid" ).extends ( am.Component ) ( {
init : function () { ... },
render : function () {
this.subElements ( { elem: "GridItem", multiple: true } )
.template ( [
"
",
"
"
].join ( "" ) )
.style ( ... );
// 此時局部變量subElements.GridItem為一個包含所有GridItem分塊片段的數組,在組件內使用:for指令循環輸出,
// 也可以使用數組索引如subElements.GridItem [ 0 ]
// 其實上面定義單數分塊的Header的全寫是{ elem: "Header", multiple: false },但它可縮寫為"Header"
}
// ...
} );
也可回顧上一節:【AmapleJS教程】3. 模板指令與狀態數據(state)相關文章
Amaple.js框架詳細介紹
Amaple.js框架詳細介紹
Amaple.js框架詳細介紹
【Amaple教程】5. 插件
發表評論
0條評論
flyer_dev
男|高級講師
TA的文章
閱讀更多
FaceBook 遭遇有史以來全球最大宕機
git倉庫合并分支指南-簡單易懂
web移動端與Hybird開發知識整理
從零開始學習vue
CSS編碼規范
詳述css中的百分比值
NPM酷庫047:ini,解析INI配置文件
「讀懂源碼系列3」lodash 是如何實現深拷貝的(上)