以下內(nèi)容基于BUI 1.6.2版本.
路由初始化以后就會去找 main
入口頁, 假設(shè)main
由3個組件組成, 會依次,從上到下加載組件, 加載以后再遞歸查找子組件, 如此反復. (雖然默認組件允許嵌套組件, 但我們依然不建議把頁面拆得太散. 組件應(yīng)該是一個可以被自由加載,獨立運行的個體. )
一進頁面的時候就會編譯, 這種組件應(yīng)該是能夠獨立運行的.
<component id="list" name="pages/components/list/index" type="news"></component>
組件需要通過請求以后才知道有哪些參數(shù), 靜態(tài)參數(shù)改變不會實時變更.
<component id="list" name="pages/components/list/index" delay="true"></component>
// 點擊或者請求以后才加載
$("#id").click(function(){
// 動態(tài)加載組件
loader.delay({
id: "#list",
param: {"type":"news"}
})
})
list組件 pages/components/list/index.js
loader.define(function(require,export,module){
// 接收父級的傳參
var param = bui.history.getParams(module.id)
// param.type = news
})
list組件 pages/components/list/index.js
loader.define(function(require,export,module){
// 1.6.1 的方式
var params = bui.history.getParams(module.id);
var parentComp = bui.history.getComponent(params.parentId);
// 1.6.2 的方式
var parentComp = bui.history.getParentComponent();
// 拿到父組件return 出來的方法, 就可以操作父組件.
})
如果列表組件沒有被嵌套加載, 拿到的父組件為
頁面組件
, 嵌套則是拿到上一級組件.
list組件 pages/components/list/index.js
loader.define(function(require,export,module){
// 無論被嵌套多少層都可以直接獲取到頁面組件
var pageComp = bui.history.getLast("exports");
})
比方頁面由
搜索組件
,列表組件
組成, 點擊搜索, 要操作列表的方法重新帶上關(guān)鍵字請求;
頁面組件 pages/main/main.html
<div class="bui-page bui-box-vertical">
<header></header>
<main>
<!-- 搜索組件 -->
<component id="search" name="pages/components/searchbar/index"></component>
<!-- 列表組件 -->
<component id="list" name="pages/components/list/index"></component>
</main>
</div>
search組件 pages/components/search/index.js
loader.define(function(require,export,module){
var pageview = {
init: function(){
// 這樣是獲取不到list組件的 refresh 方法, 因為list比search晚加載.
// var list = bui.history.getComponent("list");
router.$("#btnSearch").click(function(){
// 在點擊的時候可以獲取到兄弟list組件.
var list = bui.history.getComponent("list");
// 獲取搜索的關(guān)鍵字
var keyword = router.$(".search-input").val();
// 調(diào)用列表組件的局部屬性方法, 把關(guān)鍵字傳過去.
list.refresh(keyword);
})
}
}
// 初始化
pageview.init();
return pageview
})
list組件 pages/components/list/index.js
loader.define(function(require,export,module){
var pageview = {
init: function(){
},
refresh: function(keyword){
// 接收到搜索傳來的關(guān)鍵字進行請求操作
console.log(keyword)
}
}
// 初始化
pageview.init();
return pageview
})
注意, 搜索組件在初始化直接獲取list組件, 會獲取不到, 因為list比search晚加載.
父組件獲取子組件由于加載順序, 如果組件被重復加載,那就會重復觸發(fā)
one
里面的回調(diào). 應(yīng)該盡量避免這種操作.
main頁面組件: pages/main/main.html
<component id="searchbar" name="pages/components/searchbar/index"></component>
<component id="list" name="pages/components/list/index"></component>
pages/main/main.js
loader.define(function(){
// 監(jiān)聽 多個子組件加載完成就會觸發(fā)一次
loader.wait(["searchbar","list"],function(searchbar,list){
// 拿到子組件實例操作
console.log(searchbar.exports)
console.log(list.exports)
})
})
main頁面組件: pages/main/main.html
<component id="list" name="pages/components/list/index"></component>
pages/main/main.js
loader.define(function(require,export,module){
// 監(jiān)聽頁面點擊了搜索以后的操作
loader.on("click-search",function(mod){
// 拿到子組件操作
mod.refresh();
})
})
pages/components/list/index.js
loader.define(function(require,export,module){
var pageview = {
init: function(){
// 綁定點擊事件
router.$(".btn-search").click(function(){
// 組件加載完成以后觸發(fā)自定義事件, 把對象傳給父組件操作.
loader.trigger("click-search","傳過去的參數(shù)");
})
},
refresh: function(){
console.log("list refresh")
}
}
// 初始化
pageview.init();
return pageview;
})
搜索跟列表組件跟頁面組件相互操作的案例.
例如: 待辦頁面, 頁面上有
搜索組件
,有list組件
,還有tab組件
. 點擊搜索如果在待辦列表,則搜索待辦數(shù)據(jù), 在已辦列表則搜索已辦數(shù)據(jù).
預(yù)覽效果. 點擊里面的源碼可以看到代碼, 但看不到效果.
主入口, 待辦已辦
我們在這里來分析下. 模板里面跟我們前面講的一個TAB的初始化是一樣的. 模板header有搜索組件,main有tab組件(容器組件不用做成component), tab組件又嵌套了list組件. 根據(jù)組件的名稱, 我們知道了組件的所在目錄, 新建了
components
目錄進行集中管理, 并且組件的命名里面都是叫index
,通過文件夾名稱區(qū)分組件名.
pages/main/main.html
<div class="bui-page bui-box-vertical">
<header>
<div class="bui-bar">
<div class="bui-bar-left">
<a class="bui-btn" onclick="bui.back();"><i class="icon-back"></i></a>
</div>
<div class="bui-bar-main">待辦已辦</div>
<div class="bui-bar-right">
</div>
</div>
<component name="pages/components/searchbar/index"></component>
</header>
<main class="bui-scroll-hide">
<div id="uiTab" class="bui-tab bui-box-vertical">
<div class="bui-tab-head">
<ul class="bui-nav">
<li class="bui-btn">待辦</li>
<li class="bui-btn">已辦</li>
</ul>
</div>
<div class="bui-tab-main">
<ul>
<li>
<component id="list0" name="pages/components/list/index" type="todo"></component>
</li>
<li style="display: none;">
<component id="list1" name="pages/components/list/index" type="done" delay="true"></component>
</li>
</ul>
</div>
</div>
</main>
</div>
pages/main/main.js
在模塊的內(nèi)部組織里面,我們也新建了一個 pageview對象,并把 tab的實例接口拋出去. tab在切換的時候, 把之前延遲加載的組件編譯執(zhí)行了一遍, 下次點擊切換不會再繼續(xù)執(zhí)行.
loader.define(function(){
var pageview = {
init: function() {
// 拋出tab的實例,搜索控件需要用到
this.tab = this.tabInit();
},
tabInit: function() {
var uiTab = bui.tab({
id: "#uiTab",
scroll: false
});
// component 自動編譯延遲加載的component, 所以無需 to(0)
uiTab.on("to", function() {
// 索引從0開始
var index = this.index();
// 延遲加載有delay屬性的列表,跳到對應(yīng)的tab才加載
loader.delay({
id: "#list" + index
})
})
return uiTab;
}
};
// 執(zhí)行初始化
pageview.init();
// 拋出接口
return pageview;
})
列表刷新滾動加載組件
pages/components/list/index.html
<div class="bui-scroll">
<div class="bui-scroll-head"></div>
<div class="bui-scroll-main">
<ul class="bui-list">
</ul>
</div>
<div class="bui-scroll-foot"></div>
</div>
pages/components/list/index.js
list被同一個頁面加載, 因此初始化時, 需要通過父層id來區(qū)分不同控件, 并且通過不同參數(shù)來請求不同的接口. 剩下的交由控件自己處理分頁跟刷新. 把list實例拋出, 因為搜索的時候, 需要操作對應(yīng)的list實例.
loader.define(function(require,exports,module){
var pageview = {
init: function(){
// 獲取參數(shù)
var params = bui.history.getParams(module.id)
// 拋出list的實例
this.list = this.listInit(params);
},
listInit: function(opt){
if( this.list ){
return this.list;
}
// 列表控件 js 初始化:
var uiList = bui.list({
id: `#${module.id} .bui-scroll`,
url: "http://rap2api.taobao.org/app/mock/84605/example/getNews",
pageSize:5,
data: {
type: opt.type
},
//如果分頁的字段名不一樣,通過field重新定義
field: {
page: "page",
size: "pageSize",
data: "data"
},
callback: function (e) {},
template: function (data) {
var html = "";
data.forEach(function(el, index) {
html +=`<li class="bui-btn bui-box">
<div class="bui-thumbnail"><img src="${el.image}" alt=""></div>
<div class="span1">
<h3 class="item-title">${el.name}</h3>
<p class="item-text">${el.address}</p>
<p class="item-text">${el.distance}公里</p>
</div>
<span class="price"><i>¥</i>${el.price}</span>
</li>`
});
return html;
}
});
return uiList;
}
}
pageview.init();
return pageview;
})
搜索組件
pages/components/searchbar/index.html
<div id="searchbar" class="bui-searchbar bui-box">
<div class="span1">
<div class="bui-input">
<i class="icon-search"></i>
<input type="search" value="" placeholder="請輸入出差人或同行人" />
</div>
</div>
<div class="btn-search">搜索</div>
</div>
pages/components/searchbar/index.js
一個頁面只有一個搜索欄, 這里并不需要通過外部id去進行區(qū)分. 點擊搜索的時候, 通過
bui.history.getLast("exports")
獲取父級TAB實例,bui.history.getComponent("list0")
通過id來獲取對應(yīng)的list實例. 調(diào)用實例的方法, 把參數(shù)傳過去.
loader.define(function(require,exports,module){
var pageview = {
init: function(){
this.searchbar = this.searchbarInit();
},
searchbarInit: function(opt){
//搜索條的初始化
var uiSearchbar = bui.searchbar({
id: `#searchbar`,
callback: function (e, keyword) {
// 獲取父級實例
var lastDistance = bui.history.getLast("exports");
var currentIndex = lastDistance.tab.index();
// 根據(jù)索引獲取對應(yīng)的list實例,重新請求關(guān)鍵字
var components = bui.history.getComponent("list"+currentIndex);
components.list.empty();
components.list.init({
data: {
keyword: keyword
}
});
},
onInput: function (e, keyword) {
//實時搜索
// console.log(++n)
},
onRemove: function (e, keyword) {
//刪除關(guān)鍵詞需要做什么其它處理
// console.log(keyword);
}
});
return uiSearchbar;
}
}
pageview.init();
return pageview;
})
通過上面幾個文件的代碼, 就可以輕松實現(xiàn)下拉刷新
,滾動加載下一頁
,tab切換
,自動根據(jù)選項卡觸發(fā)列表搜索
,刪除關(guān)鍵字
等功能.
更多建議: