BUI 組件化

2020-08-12 10:59 更新

組件介紹

組件由模板+模塊組成. 模板使用.html結(jié)尾, 模塊使用.js結(jié)尾, 我們推薦默認(rèn)使用路徑名作為組件的名稱.

組件有3種表現(xiàn)形式:

  1. 通過bui.load跳轉(zhuǎn)的頁面組件;
  2. 通過component標(biāo)簽加載的局部組件;
  3. 通過bui.page彈窗加載組件;

BUI版本1.6.0以上的版本才有這些功能.

組件特點(diǎn)

  • 自執(zhí)行
  • 獨(dú)立作用域
  • 生命周期
  • 封閉或開放

BUI的組件加載后是一條線, 雖然組件允許相互嵌套, 我們并不建議把頁面拆的太過零散. 加載以后的組件依然在一條線上操作. 頁面可以看成是一個大的組件, 頁面組件可以加載 component 組件, 也可以加載 page 組件. 線的末端可以操控前面的頁面.

例如: 路由從A跳轉(zhuǎn)到B再到C, C除了可以操作當(dāng)前頁面的component1,component2,還可以操作B,跟A,以及A下面的component, 鏈接起來就是一條線. C的component也可以操控B的component1及component2 或C,A,B 等. 底下的組件交互案例會有詳細(xì)說明.

單頁路由跳轉(zhuǎn)路線
main--------->頁面A--------->頁面B------------>頁面C
               |              |                |
               |              |                |
        A的component1    B的component1   C的component1
               |              |                |
               |              |                |
        A的component2    B的component2   C的component2

組件標(biāo)簽

使用component作為組件的加載標(biāo)簽, 跟view標(biāo)簽的區(qū)別在于, view標(biāo)簽只加載了模板, component標(biāo)簽是加載了模板并執(zhí)行了相同文件名的js.

例如: 局部加載一個 pages/components/slide 組件. 默認(rèn)路徑名便是組件名, 另外 "/pages/xxx""pages/xxx" 是不同的, 為了確保在webapp,打包都能正確加載, 包括路由的路徑,圖片的路徑,script引入的路徑等, 都應(yīng)該使用 "pages/xxx" 之類的寫法.

<component name="pages/components/slide"></component>

組件屬性

component有3個內(nèi)置的屬性. 支持自定義屬性, 具體查看組件的傳參.

  • name="xxx" 模塊名.
  • render="true" 代表已經(jīng)渲染結(jié)束,不會再次渲染.
  • delay="true" 代表暫時不加載,直到調(diào)用 loader.delay方法. 查看組件的延遲加載

自定義組件

例如: pages目錄下有一個slide.html slide.js, 那么該組件的名稱為 pages/slide;

模板: pages/slide.html

<div id="uiSlide" class="bui-slide"></div>

模塊: pages/slide.js

// 定義一個模塊
loader.define(function(require,export,module){
// 輪播圖控件初始化
  var uiSlide = bui.slide({
        id: "#uiSlide",
        height: 380,
        autopage: true,
        data: [{
          image: "images/banner01.png",
          url: "pages/ui_controls/bui.slide_title.html",
        },{
          image: "images/banner02.png",
          url: "pages/ui_controls/bui.slide_title.html",
        }]
    })
})

自定義的組件如何被加載進(jìn)頁面呢? 我們把快速開始的例子改寫一下.

<div class="bui-page bui-box-vertical">
    <!-- 固定頂部區(qū) -->
    <header>
      <div class="bui-bar">
        <div class="bui-bar-left">
          <a class="bui-btn"><i class="icon-back"></i></a>
        </div>
        <div class="bui-bar-main">BUI標(biāo)準(zhǔn)頁面</div>
        <div class="bui-bar-right"></div>
      </div>
    </header>
    <main>
      <!-- name 默認(rèn)是路徑名 -->
      <component name="pages/slide"></component>


      <!-- 如果需要復(fù)用,內(nèi)部的初始化還需要改改 -->
      <component name="pages/slide"></component>
    </main>
    <footer>
      <!-- 固定底部區(qū) -->
    </footer>
  </div>

組件復(fù)用

如果當(dāng)前組件要被同一個頁面多次復(fù)用, 那組件的js還需要改改.

模塊: pages/slide.js

// 定義一個模塊
loader.define(function(require,export,module){
  // module.id 如果component沒有id則隨機(jī)生成, 通過外層component生成的id 來區(qū)分不同的控件slide
  var uiSlide = bui.slide({
        id: `#${module.id} .bui-slide`,
        height: 380,
        autopage: true,
        data: [{
          image: "images/banner01.png",
          url: "pages/ui_controls/bui.slide_title.html",
        },{
          image: "images/banner02.png",
          url: "pages/ui_controls/bui.slide_title.html",
        }]
    })
})

組件傳參

組件內(nèi)部需要通過不同參數(shù)來區(qū)分不同的控件, 比方新聞輪播圖,圖片輪播圖,視頻輪播圖. type是自定義屬性.

<!-- 新聞輪播圖 -->
<component name="pages/slide" type="news"></component>
<!-- 圖片輪播圖 -->
<component name="pages/slide" type="photo"></component>
<!-- 視頻輪播圖 -->
<component name="pages/slide" type="video"></component>

組件接收參數(shù)

在內(nèi)部通過 bui.history.getParams(module.id)來獲取. 所有屬性的參數(shù)都會被拿到.

模塊: pages/slide.js

// 定義一個模塊
loader.define(function(require,export,module){


  // 通過模塊的id來獲取不同的參數(shù), 所有屬性的參數(shù)都會被拿到.
  var params = bui.history.getParams(module.id);
  // 區(qū)分不同的接口
  var url = "http://localhost/api/"+params.type;


  // module.id 如果component沒有id則隨機(jī)生成, 通過外層component生成的id 來區(qū)分不同的控件slide
  var uiSlide = bui.slide({
        id: `#${module.id} .bui-slide`,
        height: 380,
        autopage: true,
        data: []
  })


  // 請求數(shù)據(jù)后渲染
  bui.ajax({
    url:url,
    success: function(res){
      // 測試數(shù)據(jù)
      res = [{
          image: "images/banner01.png",
          url: "pages/ui_controls/bui.slide_title.html",
        },{
          image: "images/banner02.png",
          url: "pages/ui_controls/bui.slide_title.html",
        }]
      // 修改輪播圖的數(shù)據(jù)
      uiSlide.option("data",res);
    }
  })


})

組件延遲加載

常用于tab的按需加載. 第1個新聞輪播圖的 component會由路由去編譯, 有delay="true"屬性則不編譯.

例子:

pages/tab.html

<div id="uiTab" class="bui-tab">
  <div class="bui-tab-head">
    <ul class="bui-nav">
      <li class="bui-btn">新聞</li>
      <li class="bui-btn">圖片</li>
      <li class="bui-btn">視頻</li>
    </ul>
  </div>
  <div class="bui-tab-main">
    <ul>
      <li>
        <!-- 新聞輪播圖 默認(rèn)編譯 -->
        <component id="tab0" name="pages/slide" type="news"></component>
      </li>
      <li style="display: none;">
        <!-- 圖片輪播圖延遲 暫不編譯 -->
        <component id="tab1" name="pages/slide" type="photo" delay="true"></component>
      </li>
      <li style="display: none;">
        <!-- 視頻輪播圖延遲 暫不編譯 -->
        <component id="tab2" name="pages/slide" type="video" delay="true"></component>
      </li>
    </ul>
  </div>
</div>

pages/tab.js

tab有多種操作跳轉(zhuǎn),滑動,點(diǎn)擊,都會觸發(fā)to事件.

// 定義一個模塊
loader.define(function(require,export,module){


    var uiTab = bui.tab({
      id:"#uiTab"
    })


    // tab有多種操作跳轉(zhuǎn),滑動,點(diǎn)擊,都會觸發(fā)to事件, 在這里拿到對應(yīng)的索引, 執(zhí)行加載.
    uiTab.on("to",function(){
      var index = this.index();
      // 加載delay屬性的組件
      loader.delay({
        id:`#tab${index}`
      })
    })


})

預(yù)覽效果

組件編譯

component 默認(rèn)是由 router 跳轉(zhuǎn)時進(jìn)行編譯, 如果需要手動編譯, 比方延遲加載,我們使用 loader.delay 方法, 只編譯有delay屬性的 component, 沒有delay屬性的編譯呢? 有以下3種方法.

1. 編譯一個: loader.component

<component id="tab0" name="pages/slide"></component>
// 調(diào)用一次編譯一次
loader.component({
  id:"#tab0"
})

2. 編譯多個: loader.components

<div id="tabs"> 
  <component name="pages/slide"></component>
  <component name="pages/slide"></component>
</div>
// 編譯tabs 下面的2個component
loader.components({
  id:"#tabs"
})

3. 動態(tài)編譯: loader.load

component的區(qū)別便是它可以把任意一個組件加載到某個容器下.

<div id="slide"></div>
loader.load({
  id: "#slide",
  url: "pages/slide.html"
})

組件全局方法

npm run build 在新的工程執(zhí)行這個命令以后, js 文件全部變成了閉包, 原本你的var 聲明的全局變量, 變成了局部變量, 控制面板會拋出一堆錯誤. 如果有這個情況, 建議及早處理. 在1.6.2版本. 使用 loader.global() 來定義全局方法.

例子:

js/common.js

// 定義全局方法
loader.global(function(global){


    return {
      config: {},
      getDate: function(){
        console.log("獲取日期")
      }
    }
})Click to copy

全局使用

bui.ready(function(){


  // 全局調(diào)用
  loader.globals.getDate();
})Click to copy

模塊里面調(diào)用, 新增第4個參數(shù).

loader.define(function(require,exports,module,global){


  // 全局調(diào)用
  global.getDate();
})

綜合案例

最新安裝了buijs的開發(fā)者, 可以使用以下命令, 創(chuàng)建一個更加復(fù)雜的163 component示例.

buijs create 163 -t case-163

163新聞

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號