快應用入門--頁面佈局篇

james9527發表於2018-04-05

前戲--什麼是快應用

3月20號快應用標準啟動釋出會後,這一新生技術瞬間火了。前端群裡號召大家有興趣的去調研下快應用,於是我用一天時間寫了個京東金融快應用簡易demo,接下來總結下遇到的一些問題和個人見解:

首先介紹下什麼是快應用

  1. 快應用是基於手機硬體平臺的新型應用形態,標準是由主流手機廠商組成的快應用聯盟聯合制定。
  2. 快應用標準的誕生將在研發介面、能力接入、開發者服務等層面建設標準平臺,以平臺化的生態模式對個人開發者和企業開發者全品類開放。
  3. 快應用具備傳統APP完整的應用體驗,無需安裝、即點即用。

快應用技術棧

利用前端技術棧編寫,轉換成原生語法:

快應用入門--頁面佈局篇
圖片來源:快應用釋出會PPT
快應用入門--頁面佈局篇

圖片來源:快應用釋出會PPT

理論到實踐--實現京東金融小程式Demo

入門千篇一律 請看官方文件

開發心得體會『佈局篇』

需安裝6.0以上版本的NodeJS,請從NodeJS官網下載,推薦v6.11.3(高於8.0會報錯),同時最好有一部安卓系統8.0的安卓機,編譯後可以掃碼安裝,這樣便可以一路順暢見到官方的"Hello Word"頁面。
  1. 要實現自動編譯專案,需開啟兩個視窗,一個執行npm run build->npm run server,另一個執行npm run watch.
  2. 命令hap init初始化專案後,先設定專案配置資訊,在src目錄下的manifest.json配置檔案裡,比如設計稿是基於750px的,在config設定如下:
"config": {
   "designWidth":750
}
複製程式碼
  1. 頁面結構跟vuejs極其相似,dom元素寫在template裡,style標籤支援less語法,需安裝lessless-loader依賴,style標籤設定lang="less"即可,業務邏輯寫在script裡。這裡要強調一點的是,template裡只能有一個根節點。
  2. 為了解決螢幕適配問題,所有與大小相關的樣式(例如width、font-size)均以基準寬度(預設750px)為基礎,根據實際螢幕寬度進行縮放,例如width:100px,在1500px寬度螢幕上,width實際上為200px。框架目前僅支援長度單位px,百分比也不支援,"margin:0 auto;"這類寫法也不支援,官方文件說margin&padding屬性值可以有1~4個值,但在實際使用時卻不支援,上右下左4個值需要分開寫。
  3. 文字必須包含在text標籤內才能顯示,同時針對文字的樣式class也要寫在text標籤內才能生效(這點跟react-native的Text標籤一樣)。
  4. position屬性不支援absolute和relative,可以為fixed和none;(不支援的屬性值會報錯)
  5. background屬性不支援url寫法,要用背景圖得用background-image屬性。需要強調的是,background屬性支援漸變樣式,暫時不能與background-colorbackground-image同時使用。background-image暫時不支援與background-colorborder-color同時使用;不支援網路圖片資源,支援本地圖片資源。 背景顏色則要用background-color去設定,顏色值也必須為6位的十六進位制,如:"background-color:#ffffff;"
  6. box-shadowfont-family屬性暫時不支援;
  7. 框架提供了一套基礎的介面元件,介面元件標籤除了支援常用的HTML5標籤,例如div,a,input等標籤之外,還提供與原生UI相關的元件標籤,例如switch,slider,list等(注意:不支援ul li 、dl dt dd等標籤)。不支援的標籤會報錯,具體使用請參考官方文件--元件
  8. 頁面佈局雖然預設採用了flex盒佈局,但justify-content支援的屬性值有限,有效列舉值為: flex-start|flex-end|center|space-between,報錯如下所示:
    快應用入門--頁面佈局篇
  9. list元件的使用,其子元件必須是block,然後block的子元件必須是list-item。block元件不支援class屬性,支援的屬性有[for,tid,if,elif,else],注意:1)list-item內不能再巢狀list;2)list-item的type屬性為必填屬性;3)list-item內部需謹慎使用if指令或for指令,因為相同type屬性的list-item的DOM結構必須完全相同,而使用if指令或for指令會造成DOM結構差異;
  10. div元件支援的屬性有 [id, style, class, disabled, if, elif, else, for, tid, show]。
  11. 當DOM結構複雜時,滾動頁面會出現卡頓現象,因為Native無法複用div元件實現的列表元素,為了得到流暢的列表滾動體驗,推薦使用list元件替代div元件實現長列表佈局,因為Native會複用相同type屬性的list-item。

輕鬆實現京東金融小程式首頁

掌握了一些原理後,接下來進入採坑之旅(建議:先看官方文件,特別是css屬性的支援範圍)先來張首頁初版截圖:

快應用入門--頁面佈局篇

一言不合就上程式碼『Dom部分』
<template>
  <!-- template裡只能有一個根節點 -->
  <div class="mainWrapper">
        <div class="topPart">
              <div class="topBg"></div>
              <div class="slogan_title">
                    <image class="slogan" src="./../Images/slogan@3x.png"></image>
                    <image class="title" src="./../Images/logo.png"></image>
              </div>
              <div class="menu_icons">
                     <div class="menu" for="{{menuList}}" onclick="routeDetail($idx+1)">
                          <div class="icon">
                               <image src={{$item.icon}}></image>
                          </div>
                          <div>
                               <text class="name">{{$item.name}}</text>
                          </div>
                     </div>
              </div>
        </div>
        <div class="contentPart" onclick="routeDetail(7)">
              <div class="articleWrap" for="{{articleList}}">
                    <div>
                         <text class="title">{{$item.title}}</text>
                    </div>
                    <div>
                          <image class="thumbnail" src={{$item.img}}></image>
                    </div>
                    <div>
                          <text class="brief">{{$item.brief}}</text>
                    </div>
                    <div class="readAll">
                           <div>
                                 <text class="tip">閱讀全文</text>
                           </div>
                           <div>
                                 <text class="arrow">></text>
                           </div>
                    </div>
              </div>
        </div>
        <image class="bottomPart" src="./../Images/logo_grey@3X.png"></image>
  </div>
</template>

複製程式碼
一言不合就上程式碼『css部分』
<style lang="less">
      .mainWrapper{
              flex-direction: column;
              justify-content:flex-start;
              background-color:rgba(84,95,113,0.10);
             .topPart{
                   flex-direction: column;
                   justify-content:flex-start;
                   .topBg{
                         width:750px;
                         height:326px;
                         background-image:url('./../Images/index_top_bg@3x.png');
                         background-size:cover;
                   }
                  .slogan_title{
                       justify-content:space-between;
                       margin-left:40px;
                       margin-top:-263px;
                       width:680px;
                       .slogan{
                            width:381px;
                            height:52px;
                       }
                       .title{
                            width:66px;
                            height:66px;
                            margin-left:233px;
                            border-radius:50px;
                       }
                  }
                  .menu_icons{
                        width:710px;
                        height:220px;
                        background-color:#ffffff;
                        margin-left:20px;
                        margin-top:40px;
                        border-radius:6px;
                        justify-content:space-between;
                        align-items:center;
                        .menu{
                             width:138px;
                             display:flex;
                             flex-direction:column;
                             justify-content:space-between;
                             align-items:center;
                             margin-left:10px;
                             margin-top:48px;
                             margin-bottom:54px;
                             .icon{
                                   width:64px;
                                   height:64px;
                             }
                            div>.name{
                                 font-size:24px;
                                 line-height:34px;
                                 color:#666666;
                                 margin-top:20px;
                             }
                        }
                  }
             }
            .contentPart{
                margin-top:40px;
                margin-left:20px;
                margin-right:20px;
                flex-direction:column;
                justify-content:flex-start;
                .articleWrap{
                     width:710px;
                     background-color:#ffffff;
                     border-radius:6px;
                     flex-direction:column;
                     justify-content:flex-start;
                     padding-left:30px;
                     padding-right:30px;
                     margin-bottom:40px;
                     .title{
                          padding-top:33px;
                          padding-bottom:33px;
                          font-size:32px;
                          color:#333333;
                          font-weight:bold;
                     }
                     .thumbnail{
                         width:650px;
                     }
                     .brief{
                         padding-top:30px;
                         padding-bottom:30px;
                         font-size:28px;
                         color:#999999;
                         line-height:32px;
                     }
                     .readAll{
                          justify-content:space-between;
                          align-items:center;
                          border-top-width:0.5px;
                          border-top-color:#eeeeee;
                          padding-top:20px;
                          padding-bottom:20px;
                          .tip{
                               color:#333333;
                               font-size:28px;
                          }
                          .arrow{
                               color:#cccccc;
                               font-size:28px;
                          }
                     }
                }
            }
            .bottomPart{
                 width:180px;
                 height:54px;
                 margin-top:20px;
                 margin-left:284px;
                 margin-bottom:30px;
            }
      }
</style>
複製程式碼
一言不合就上程式碼『js部分』
<script>
  import router from '@system.router'

  export default {
    data: {
        title: '京東金融',
        menuList:[{
              icon:'./../Images/index_icon_asset@3x.png',
              name:'資產'
        },{
              icon:'./../Images/index_icon_profit@3x.png',
              name:'查收益'
        },{
              icon:'./../Images/index_icon_quota@3x.png',
              name:'查額度'
        },{
              icon:'./../Images/index_icon_bill@3x.png',
              name:'查賬單'
        },{
              icon:'./../Images/index_icon_credit@3x.png',
              name:'信用'
        }],
        articleList:[{
             title:'白條是什麼?怎麼申請?',
             img:'./../Images/bottom-img02.png',
             brief:'白條是京東金融推出的個人消費信貸產品,申請京東白條後,您可以使用白條額度在京東商城消費,享受先消費、後付款服務,同時支援最高24期分期還款。'
        },{
             title:'京東金融的理財產品,收益怎麼樣?',
             img:'./../Images/bottom-img01.png',
             brief:'京東定期理財是京東金融推出的簡單、安全的穩健型理財產品,多種定期理財產品的投資收益、投資時間一目瞭然。從投資歷史來看,收益高且穩定,得到了眾多好評。'
        }]
    },
    routeDetail(id) {
      let uri = ''

      // 跳轉到應用內的某個頁面,router用法詳見:文件->介面->頁面路由
      switch (id) {
        case 1:
          uri = '/Assets'
          break;
        case 2:
          uri = '/Income'
          break;
        case 3:
          uri = '/Quota'
          break;
        case 4:
          uri = '/Bill'
          break;
        case 5:
          uri = '/Credit'
          break;
        case 6:
          uri = '/About'
          break;
        case 7:
          uri = '/Detail'
          break;
        case 8:
          uri = '/Test'
          break;
        default:
          break;
      }

      router.push({
        uri: uri
      })
    }
  }
</script>

複製程式碼

底層架構和介面能力『下期預告』

底層架構:

快應用入門--頁面佈局篇
圖片來源:快應用釋出會PPT
快應用入門--頁面佈局篇
圖片來源:快應用釋出會PPT

介面能力:

快應用入門--頁面佈局篇
圖片來源:快應用釋出會PPT

寫在最後,雖然現在『快應用』相比『小程式』還有很多不成熟的地方,但是憑藉其【一觸即達】的能力,還有國內九大手機廠商聯手協同發展快應用生態,豐富的入口(包括負一屏、簡訊和拍照分享等入口),相信在不久的將來會越來越好的,甚至超過小程式的熱度,拭目以待。(PS:安利一波我們京東金融移動前端組原創文章公眾號:『前端工坊』⏬)
參考資料:

快應用開發文件官網 doc.quickapp.cn/

相關文章