基於react/vue開發一個專屬於程序員的朋友圈應用

前言

今天原本想開源本身寫的CMS應用的,可是因爲五一期間筆者的mac電腦忽然崩潰了,全部數據沒法恢復,致使部分代碼丟失,但慶幸的是cms的打包文件已上傳服務器,感興趣的朋友能夠在文末連接中訪問查看。javascript

今天要寫的H5朋友圈也是基於筆者開發的cms搭建的,我將仿照微信朋友圈,帶你們一塊兒開發一個能發佈動態(包括圖片上傳)的朋友圈應用。有關服務端部分筆者在本文中不會細講,後續會在cms2.0中詳細介紹。css

你將收穫

  • 使用umi快速建立一個H5移動端應用
  • 基於react-lazy-load實現圖片/內容懶加載
  • 使用css3基於圖片數量動態改變佈局
  • 利用FP建立一個朋友圈form
  • 使用rc-viewer查看/旋轉/縮放朋友圈圖片
  • 基於axios + formdata實現文件上傳功能
  • ZXCMS介紹

應用效果預覽

朋友圈列表

查看朋友圈圖片

發佈動態
html

正文

在開始文章以前,筆者想先粗略總結一下開發H5移動端應用須要考慮的點。對於任何移動端應用來講,咱們都要考慮以下問題:前端

  • 首屏加載時間
  • 適配問題
  • 頁面流暢度
  • 動畫性能
  • 交互友好
  • 提供用戶反饋

這些不只僅是前端工程師須要考慮的問題,也是產品經理和交互設計師考慮的範疇。固然還有不少實際的考慮點須要根據自身需求去優化,以上幾點大體解決方案以下:vue

  1. 提升首屏加載時間 能夠採用資源懶加載+gzip+靜態資源CDN來優化,而且提供加載動畫來下降用戶焦慮。
  2. 適配問題 移動端適配問題能夠經過js動態設置視口寬度/比率或者採用css媒介查詢來處理,這塊市面上已經有很是成熟的方案
  3. 頁面流暢度 咱們能夠在body上設置-webkit-overflow-scrolling:touch;來提升滾動流暢度,而且能夠在a/img標籤上使用 -webkit-touch-callout: none來禁止長按產生菜單欄。
  4. 動畫性能 爲了提升動畫性能, 咱們能夠將須要變化的屬性採用transform或者使用absolute定位代替,transform不會致使頁面重繪。
  5. 提供用戶反饋 提供友好的用戶反饋咱們能夠經過合理設置toastmodal等來控制

以上介紹的只是移動端優化的百裏挑一,有關前端頁面性能優化的方案還有不少,筆者在以前的文章中也詳細介紹過,下面咱們進入正文。java

1. 使用umi快速建立一個應用

筆者將採用umi做爲項目的前端集成解決方案,其提供了很是多了功能,使用起來也很是方便,而且對於antd和antd-mobile自動作了按需導入,因此熟悉react的朋友能夠嘗試一下,本文的方案對於vue選手來講也是適用的,由於任何場景下,方法和思惟模式都是跨語言跨框架的。node

目前umi已經升級到3.0,本文所使用的是2.0,不過差別不是很大,你們能夠放心使用3.0. 具體使用步驟以下react

// umi2.0
// 新建項目目錄
mkdir friendcircle
// 建立umi項目
cd friendcircle
yarn create umi
// 安裝依賴
yarn
yarn add antd-moblie

這樣一個umi項目就建立好了。webpack

2. 基於react-lazy-load實現圖片/內容懶加載

在項目建立好以後,咱們先分析咱們須要用到那些技術點:

筆者在設計時研究了不少懶加載實現方式,目前採用react-lazy-load來實現,好處是支持加載事件通知,好比咱們須要作埋點或者廣告上報等功能時很是方便。固然你們也能夠本身經過observer API去實現,具體實現方案筆者在幾個很是有意思的javascript知識點總結文章中有所介紹。
具體使用方式:ios

<LazyLoad key={item.uid} overflow height={280} onContentVisible={onContentVisible}>
    // 須要懶加載的組件
    <ComponentA />
</LazyLoad>

react-lazy-load使用方式很是簡單,你們不懂的能夠在官網學習瞭解。

3. 使用css3基於圖片數量動態改變佈局

目前在朋友圈列表頁有個核心的需求就是咱們須要在用戶傳入不一樣數量的圖片時,要有不一樣的佈局,就像微信朋友圈同樣,主要做用就是爲了讓用戶儘量多的看到圖片,提升用戶體驗,以下圖所示例子:

咱們用js實現起來很方便,可是對性能及其不友好,並且對於用戶發佈的每一條動態的圖片都須要用js從新計算一遍,做爲一個有追求的程序員是不可能讓這種狀況發生的,因此咱們用css3來實現,其實有關這種實現方式筆者在以前的css3高級技巧的文章中有詳細介紹,咱們這裏用到了子節點選擇器,具體實現以下:

.imgItem {
    margin-right: 6px;
    margin-bottom: 10px;
    &:nth-last-child(1):first-child {
      margin-right: 0;
      width: 100%;
    }
    &:nth-last-child(2):first-child,
    &:nth-last-child(3):first-child,
    &:nth-last-child(4):first-child,
    &:first-child:nth-last-child(n+2) ~ div {
      width:calc(50% - 6px);
      height: 200px;
      overflow: hidden;
    }
    &:first-child:nth-last-child(n+5),
    &:first-child:nth-last-child(n+5) ~ div {
      width: calc(33.33333% - 6px);
      height: 150px;
      overflow: hidden;
    }
}

以上代碼中咱們對於一張圖片,2-4張圖片,5張以上的圖片分別設置了不一樣的尺寸,這樣就能夠實現咱們的需求了,還有一個要注意的是,當用戶上傳不一樣尺寸的圖片時,有可能出現高低不一致的狀況,這個時候爲了顯示一致,咱們可使用img樣式中的object-fit屬性,有點相似於background-size,咱們能夠把img便籤看做一個容器,裏面的內容如何填充這個容器,徹底用object-fit來設置,具體屬性以下:

  • fill 被替換的內容正好填充元素的內容框。整個對象將徹底填充此框。若是對象的寬高比與內容框不相匹配,那麼該對象將被拉伸以適應內容框
  • contain 被替換的內容將被縮放,以在填充元素的內容框時保持其寬高比。 整個對象在填充盒子的同時保留其長寬比,所以若是寬高比與框的寬高比不匹配,該對象將被添加「黑邊」
  • cover 被替換的內容在保持其寬高比的同時填充元素的整個內容框。若是對象的寬高比與內容框不相匹配,該對象將被剪裁以適應內容框
  • scale-down 內容的尺寸與 none 或 contain 中的一個相同,取決於它們兩個之間誰獲得的對象尺寸會更小一些
  • none 被替換的內容將保持其原有的尺寸

因此爲了讓圖片保持一致,咱們這麼設置img標籤的樣式:

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

4. 利用FP建立一個朋友圈form

FP是筆者開源的一個表單配置平臺,主要用來定製和分析各類表單模型,界面以下:


經過該平臺能夠定製各類表單模版並分析表單數據。這裏朋友圈功能咱們只須要配置一個簡單的朋友圈發佈功能便可,以下:

因爲筆者電腦數據丟失致使代碼部分損失,感興趣能夠了解一下。

5. 使用rc-viewer查看/旋轉/縮放朋友圈圖片

對於朋友圈另外一個重要的功能就是能查看每一條動態的圖片,相似於微信朋友圈的圖片查看器,這裏筆者採用第三方開源庫rc-viewer來實現,具體代碼以下:

<RcViewer options={{title: 0, navbar: 0, toolbar: 0}} ref={imgViewRef}>
  <div className={styles.imgBox}>
    {
      item.imgUrls.map((item, i) => {
        return <div className={styles.imgItem} key={i}>
          <img src={item} alt=""/>
        </div>
      })
    }
  </div>   
</RcViewer>

由上代碼可知咱們只須要在RcViewer組件裏寫咱們須要的查看的圖片結構就好了,其提供了不少配置選項但是使用,這裏筆者在option中配置了title,navbar,toolbar均爲0,意思是不顯示這些功能,由於移動端只須要有基本的查看,縮放,切換圖片功能便可,儘量輕量化。效果以下:

當咱們點擊動態中的某一張圖片時,咱們能夠看到它的大圖,並經過手勢進行切換。

6. 基於axios + formdata實現文件上傳功能

實現文件上傳,除了採用antd的upload組件,咱們也能夠結合http請求庫和formdata來實現,爲了支持多圖上傳並保證時機,咱們採用async await函數,具體代碼以下:

const onSubmit = async () => {
    // ... something code
    const formData = new FormData()
    for(let i=0; i< files.length; i++) {
      formData.delete('file')
      formData.append('file', files[i].file)
      try{
        const res = await req({
          method: 'post',
          url: '/files/upload/tx',
          data: formData,
          headers: {
              'Content-Type': 'multipart/form-data'
          }
        });
        // ... something co
      }catch(err) {
        Toast.fail('上傳失敗', 2);
      }
    }

其中req是筆者基於axios封裝的http請求庫,支持簡單的請求/響應攔截,感興趣的朋友能夠參考筆者源碼。

7. ZXCMS介紹

ZXCMS是筆者開發的一個商業版CMS,能夠快速搭建本身的社區,博客等,而且集成了表單定製平臺,配置中心,數據分發中心等功能,後期會擴展H5可視化搭建平臺和PC端建站平臺,成爲一個更加只能強大的開源系統。設計架構以下:

具體界面以下:

一個筆者配置的社區平臺:

文章詳情頁:


社區支持評論,搜索文章等功能。如下介紹後臺管理系統:




簡單介紹一下,後期筆者會專門出文章介紹具體實現方式和源碼設計。

8. 源碼地址

因爲筆者電腦數據丟失,只能找到部分源碼,因此你們能夠參考如下地址:

開源不易,歡迎支持~

最後

若是想學習更多H5遊戲, webpacknodegulpcss3javascriptnodeJScanvas數據可視化等前端知識和實戰,歡迎在《趣談前端》一塊兒學習討論,共同探索前端的邊界。

相關文章
相關標籤/搜索