成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

編寫chameleon跨端組件的正確姿勢(下篇)

xiongzenghui / 3356人閱讀

摘要:在編寫跨端組件的正確姿勢上篇中,我們介紹了如何使用第三方庫封裝跨端組件,但是絕大多數(shù)組件并不需要那樣差異化實(shí)現(xiàn),絕大多數(shù)情況下我們推薦使用語法統(tǒng)一實(shí)現(xiàn)跨端組件。

在chameleon項(xiàng)目中我們實(shí)現(xiàn)一個(gè)跨端組件一般有兩種思路:使用第三方組件封裝與基于chameleon語法統(tǒng)一實(shí)現(xiàn)。
在《編寫chameleon跨端組件的正確姿勢(上篇)》中, 我們介紹了如何使用第三方庫封裝跨端組件,但是絕大多數(shù)組件并不需要那樣差異化實(shí)現(xiàn),絕大多數(shù)情況下我們推薦使用chameleon語法統(tǒng)一實(shí)現(xiàn)跨端組件。本篇是編寫chameleon跨端組件的正確姿勢系列文章的下篇,與上篇給出的示例相同,本篇也以封裝一個(gè)跨端的indexlist組件為例,首先介紹如何使用chameleon語法統(tǒng)一實(shí)現(xiàn)一個(gè)跨端組件,然后對比兩種組件開發(fā)方式并給出開發(fā)建議。

最終效果

以下效果依此為weex端、web端、支付寶小程序端、微信小程序端以及百度小程序端:



開發(fā) 項(xiàng)目初始化

創(chuàng)建一個(gè)新項(xiàng)目 cml-demo

cml init project 

進(jìn)入項(xiàng)目

cd cml-demo
組件創(chuàng)建
cml init component

選擇“普通組件”, 并并輸入組件名字“indexlist”, 完成組件的創(chuàng)建, 創(chuàng)建之后的組件位于src/components/indexlist文件夾下。

組件設(shè)計(jì)

為了方便說明,本例暫時(shí)實(shí)現(xiàn)一個(gè)具備基礎(chǔ)功能的indexlist組件。從功能方面講,indexlist組件主要由兩部分組成,主列表區(qū)域和索引區(qū)域。在用戶點(diǎn)擊組件右側(cè)索引時(shí),主列表能夠快速定位到對應(yīng)區(qū)域;在用戶滑動(dòng)組件主列表時(shí),右側(cè)索引跟隨滑動(dòng)不停切換當(dāng)前索引項(xiàng)。從輸入輸出方面講,組件至少應(yīng)該在用戶選擇某一項(xiàng)時(shí)拋出一個(gè)onselect事件,傳遞用戶當(dāng)前所選中項(xiàng)的數(shù)據(jù);至少應(yīng)該接受一個(gè)datalist,作為其渲染的數(shù)據(jù)源,這個(gè)datalist應(yīng)該是一個(gè)類似于以下結(jié)構(gòu)的對象數(shù)組:

  const dataList = [
    {
      name: "阿里",
      pinYin: "ali",
    }, {
      name: "北京",
      pinYin: "beijing",
    },
    .....
 ]
主要數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)

根據(jù)設(shè)計(jì)的組件功能與輸入輸出, 我們開始設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)。
indexlist組件右側(cè)的索引列對應(yīng)的數(shù)據(jù)結(jié)構(gòu)為一個(gè)數(shù)組,其中的每一項(xiàng)表示一個(gè)索引,具體結(jié)構(gòu)如下:

  this.shortcut = [ "A", "B", "C", ....]

indexlist組件的主列表區(qū)域?qū)?yīng)的數(shù)據(jù)結(jié)構(gòu)也是一個(gè)數(shù)組,其中的每一項(xiàng)表示一個(gè)子列表區(qū)域(例如以首字母a開頭的子列表)。下面我們考慮每一個(gè)子列表區(qū)域中至少應(yīng)該包含的字段:

一個(gè)name字段,表示該子列表區(qū)域的名稱;

一個(gè)items字段,該字段也是一個(gè)數(shù)組,數(shù)組中的每一項(xiàng)表示該子列表區(qū)域的每一項(xiàng);

一個(gè)offsetTop, 表示該子列表區(qū)域距離主列表頂部的距離,通過該字段實(shí)現(xiàn)點(diǎn)擊右側(cè)索引時(shí)能夠通過滾動(dòng)相應(yīng)距離快速定位到該子列表;

一個(gè)totalHeight字段,表示該子列表區(qū)域的所占的高度,通過該字段與offsetTop字段可以確定每個(gè)子列表所在的高度范圍, 以此實(shí)現(xiàn)右側(cè)索引跟隨滑動(dòng)不停切換當(dāng)前索引項(xiàng)

由上面分析可得主列表區(qū)域數(shù)據(jù)結(jié)構(gòu)如下:

  this.list = [
    {
      name: "B",
      items:[
        {
          name: "北京",
          pinYin: "beijing"
        },
        {
          name: "包頭",
          pinYin: "baotou"
        }
        ...
      ],
      offsetTop: 190,
      totalHeight: 490
    },
    ....
  ]
功能實(shí)現(xiàn)

從前文可知,輸入組件的datalist具有如下結(jié)構(gòu):

  const dataList = [
    {
      name: "阿里",
      pinYin: "ali",
    }, {
      name: "北京",
      pinYin: "beijing",
    },
    .....
 ]

可以發(fā)現(xiàn)該datalist結(jié)構(gòu)是扁平并且缺乏很多信息(例如totalHeight等)的,因此首先要從輸入數(shù)據(jù)中整理出來所需的數(shù)據(jù)結(jié)構(gòu),修改src/components/indexlist/indexlist.cml的js部分:

  initData() {
      // get shortcut
      this.dataList.forEach(item => {
        if (item.pinYin) {
          let firstName = item.pinYin.substring(0, 1);
          if (item.pinYin && this.shortcut.indexOf(firstName.toUpperCase()) === -1) {
            this.shortcut.push(firstName.toUpperCase());
          };
        };
      });  

      // handle input data
      const cityData = this.shortcut.map(item => ({items:[], name: item}));
      this.dataList.forEach((item) => {
        let firstName = item.pinYin.substring(0, 1).toUpperCase();
        let index = this.shortcut.indexOf(firstName);
        cityData[index].items.push(item);
      });
      
      // calculate item offsetTop && totalHeight
      cityData.forEach((item, index) => {
        let arr = cityData.slice(0, index);
        item.totalHeight = this.itemNameHeight + item.items.length * this.itemContentHeight;
        item.offsetTop = arr.reduce((total, cur) => (total + this.itemNameHeight + cur.items.length * this.itemContentHeight), 0);
      });
      this.list = cityData;
    },

這樣我們就拿到了主列表數(shù)組this.list與索引列表數(shù)組this.shortcut, 然后根據(jù)數(shù)組結(jié)構(gòu)編寫模板內(nèi)容。模板內(nèi)容分為兩大部分,一個(gè)是主列表區(qū)域,修改src/components/indexlist/indexlist.cml文件模板部分:

  
    
      
        {{listitem.name}}
      
      
         {{subitem.name}}
      
    
  

其中scroller是一個(gè)chameleon提供的內(nèi)置滾動(dòng)組件,其屬性值scrolltop表示當(dāng)前滾動(dòng)的距離,onscroll表示滾動(dòng)時(shí)觸發(fā)的事件。在主列表這一部分,我們要實(shí)現(xiàn)如下功能:

在滾動(dòng)時(shí),右側(cè)索引不停切換當(dāng)前索引項(xiàng)的功能

點(diǎn)擊列表中的每一項(xiàng)時(shí),向外拋出onselect事件

修改src/components/indexlist/indexlist.cml文件js部分:

    handleScroll(e) {
      let { scrollTop } = e.detail;
      scrollTop = Math.ceil(scrollTop);
      this.activeIndex = this.list.findIndex(item => scrollTop >= item.offsetTop && scrollTop < item.totalHeight + item.offsetTop )
    },
    handleSelect(e) {
      this.$cmlEmit("onselect", e)
    }

當(dāng)前激活的索引(this.activeIndex)經(jīng)過計(jì)算得到,規(guī)則為:如果當(dāng)前scroller滾動(dòng)的距離在對應(yīng)子列表所在的高度范圍內(nèi),則認(rèn)為該索引是激活的。

另一部分是索引區(qū)域,修改src/components/indexlist/indexlist.cml文件模板部分,增加索引區(qū)域模板內(nèi)容:

  
    
      {{item}}
    
  

在索引區(qū)域,我們要實(shí)現(xiàn)點(diǎn)擊索引值主列表能夠快速定位到對應(yīng)區(qū)域,修改src/components/indexlist/indexlist.cml文件js部分:

    scrollToItem(shortcut) {
      let { offsetTop } = this.list.find(item => item.name === shortcut);
      this.offsetTop = offsetTop;
    }

索引區(qū)域應(yīng)該定位在視窗右側(cè)并且上下居中。由于chameleon暫時(shí)不支持在css中使用百分比,因此我們通過chameleon-api提供的對外接口獲取屏幕視窗高度,然后使用js計(jì)算得到位置, 配合部分css來實(shí)現(xiàn)索引區(qū)域定位在視窗右側(cè)居中。修改src/components/indexlist/indexlist.cml文件js部分:

    // computed
    compScwStyle() {
      return `top:${this.viewportHeight / 2}cpx`
    }

    // method
    async getViewportHeight() {
      let res = await cml.getSystemInfo();
      this.viewportHeight = res.viewportHeight;
    },

至此便通過chameleon語法統(tǒng)一實(shí)現(xiàn)了一個(gè)跨端indexlist組件,該組件直接可以在web、weex、微信小程序、支付寶小程序與百度小程序五個(gè)端運(yùn)行。為了方便描述,上述代碼只是簡單介紹了組件實(shí)現(xiàn)的核心代碼,跳過了樣式和一些邏輯細(xì)節(jié)。

組件使用

修改src/pages/index/index.cml文件里面的json配置,引用創(chuàng)建的indexlist組件

"base": {
    "usingComponents": {
      "indexlist": "/components/indexlist/indexlist"
    }
},

修改src/pages/index/index.cml文件中的模板部分,引用創(chuàng)建的indexlist組件

  
    
  

其中dataList是一個(gè)對象數(shù)組,表示組件要渲染的數(shù)據(jù)源

一些思考

本篇文章主要介紹了如何通過chameleon語法實(shí)現(xiàn)跨端組件。對比編寫chameleon跨端組件的正確姿勢(上篇).md)介紹的通過第三方庫封裝的方法可以發(fā)現(xiàn),兩種方式是完全不同的,現(xiàn)詳細(xì)對比一下這兩種實(shí)現(xiàn)方式的優(yōu)勢與劣勢, 并給出開發(fā)建議:

優(yōu)勢 劣勢 開發(fā)建議
基于第三方組件庫實(shí)現(xiàn) - 可利用已有生態(tài)迅速完成跨端組件 - 組件的實(shí)現(xiàn)依賴第三方庫,如果沒有成熟的對應(yīng)端第三方庫則無法完成該端組件開發(fā)

- 由于各端第三方組件存在差異,封裝的跨端組件樣式與功能存在差異

- 第三方組件升級時(shí),要對應(yīng)調(diào)整跨端組件的實(shí)現(xiàn),維護(hù)成本較大

- 第三方組件庫質(zhì)量不能得到保證

- 將基于各端第三方組件封裝跨端組件庫的方法作為臨時(shí)方案

- 對于特別復(fù)雜并且已有成熟第三方庫或者框架能力暫時(shí)不支持的組件,可以考慮使用第三方組件封裝成對應(yīng)的跨端組件,例如圖表組件、地圖組件等等

基于chameleon統(tǒng)一實(shí)現(xiàn) - 新的端接入時(shí),能夠直接運(yùn)行

- 一般情況下,不存在各端樣式與功能差異

- 絕大部分組件不需要各端差異化實(shí)現(xiàn),使用chameleon語法實(shí)現(xiàn)開發(fā)與維護(hù)成本更低

- 能夠?qū)С鲈M件供多端使用

- 從零搭建時(shí)間與技術(shù)成本較高 從長期維護(hù)的角度來講,建議使用chameleon生態(tài)來統(tǒng)一實(shí)現(xiàn)跨端組件庫

如果僅僅是各端api層面的不同,建議使用多態(tài)接口抹平差異,而不使用多態(tài)組件

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102464.html

相關(guān)文章

  • 編寫chameleon跨端組件正確姿勢(上篇)

    摘要:使用語法統(tǒng)一實(shí)現(xiàn)跨端組件請關(guān)注文章編寫跨端組件的正確姿勢下篇依靠強(qiáng)大的多態(tài)協(xié)議,項(xiàng)目中可以輕松使用各端的第三方組件封裝自己的跨端組件庫。這種做法同時(shí)解決了組件命名沖突問題,例如在微信小程序端引用表示調(diào)用小程序原生的組件而不是內(nèi)置的組件。 在chameleon項(xiàng)目中我們實(shí)現(xiàn)一個(gè)跨端組件一般有兩種思路:使用第三方組件封裝與基于chameleon語法統(tǒng)一實(shí)現(xiàn)。本篇是編寫chameleon跨端...

    h9911 評論0 收藏0
  • 【重磅】Chameleon 開放跨端擴(kuò)展標(biāo)準(zhǔn)協(xié)議

    摘要:基于對跨端工作的積累,規(guī)范了一套跨端標(biāo)準(zhǔn),稱之為協(xié)議開發(fā)者只需要按照標(biāo)準(zhǔn)擴(kuò)展流程,即可快速擴(kuò)展任意架構(gòu)模式的終端。實(shí)現(xiàn)了微信端的基本擴(kuò)展,用戶可以以此為模板進(jìn)行開發(fā)。新框架太多?學(xué)不動(dòng)啦?有這一套跨端標(biāo)準(zhǔn),今后再也不用學(xué)習(xí)新框架了。各個(gè)小程序按自己喜好各自為政?有了這套標(biāo)準(zhǔn),再也不用重復(fù)開發(fā)各種新平臺啦。如今前端比較流行的 React Native、Weex、Flutter 等跨平臺開發(fā)框架...

    liangdas 評論0 收藏0
  • 【重磅】Chameleon 開放跨端擴(kuò)展標(biāo)準(zhǔn)協(xié)議

    摘要:但是從年微信推出小程序,到至今各大廠商都推出自己的小程序,跨端開發(fā)就不僅僅是技術(shù)的問題了。實(shí)現(xiàn)了微信端的基本擴(kuò)展,用戶可以以此為模板進(jìn)行開發(fā)。 新框架太多?學(xué)不動(dòng)啦?有這一套跨端標(biāo)準(zhǔn),今后再也不用學(xué)習(xí)新框架了。 各個(gè)小程序按自己喜好各自為政?有了這套標(biāo)準(zhǔn),再也不用重復(fù)開發(fā)各種新平臺啦。 如今前端比較流行的 React Native、Weex、Flutter 等跨平臺開發(fā)框架,對于開發(fā)來...

    shuibo 評論0 收藏0
  • 開源中國專訪:Chameleon原理首發(fā),其它跨多端統(tǒng)一框架都是假?

    摘要:中國互聯(lián)網(wǎng)絡(luò)信息中心發(fā)布的中國互聯(lián)網(wǎng)絡(luò)發(fā)展?fàn)顩r統(tǒng)計(jì)報(bào)告顯示,截至年月,我國網(wǎng)民規(guī)模達(dá)億人,微信月活億支付寶月活億百度月活億另一方面,中國手機(jī)占智能手機(jī)整體的比例超過,月活約億。在年末正式發(fā)布了面向未來的跨端的。 開源中國專訪:Chameleon原理首發(fā),其它跨多端統(tǒng)一框架都是假的? 原創(chuàng): 嘉賓-張楠 開源中國 以往我們說某一功能跨多端,往往是指在諸如 PC、移動(dòng)等不同類型的設(shè)備之...

    GraphQuery 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<