WeGeek直播課:從0到1快速開發電商小程序(文字版)

做者:鍾鑫css

源碼示例

Taro • 雲開發電商小程序示例html

簡介

hi, 你們好。我是來自京東凹凸實驗室的鐘鑫,Taro 框架核心開發成員。 目前我主要負責 Taro 框架多端組件及 API 相關。還有京東購物小程序首頁和搜索的相關研發。 電商類的應用,在在全部應用中比較常見,也是比較複雜的場景之一。那本次課程,基於 Taro 框架和 雲開發,來次電商小程序的實戰,教你搭建的電商小程序。前端

背景

微信小程序是一種不須要安裝便可使用的應用,它的優點有不少。好比:git

  • 速度快,無需下載安裝,隨時可用
  • 無適配,一次開發,免除對各類手機機型的適配。
  • 可分享,支持圖文分享、支持分享給微信好友和羣聊。
  • 體驗好, 能夠達到和原生 App 相同的操做體驗和流暢度。
  • 易獲取, 支持掃碼、微信搜索、好友推薦等發起場景。
  • 低門檻,已有公衆號的組織能夠快速支持、可快速生成門店小程序。

本次課程,咱們使用 Taro 框架開發小程序。那 Taro 是什麼? 來看看官方文檔描述github

Taro 是一套遵循 React 語法規範的 多端開發 解決方案。現現在市面上端的形態多種多樣,Web、React-Native、微信小程序等各類端大行其道,當業務要求同時在不一樣的端都要求有所表現的時候,針對不一樣的端去編寫多套代碼的成本顯然很是高,這時候只編寫一套代碼就可以適配到多端的能力就顯得極爲須要。
使用 Taro,咱們能夠只書寫一套代碼,再經過 Taro 的編譯工具,將源代碼分別編譯出能夠在不一樣端(微信/百度/支付寶/字節跳動小程序、H五、React-Native 等)運行的代碼。數據庫

Taro 有一套完善的開發流程,在開發的時候也有很好的代碼智能提示,實時的代碼檢查,開發效率大幅提高。使用 Taro 能夠快速的發開小程序,未來若有其餘端的需求,咱們也只要維護一份代碼就行了~json

其次,本次課程選用的是小程序·雲開發做爲咱們的後臺服務。 那小程序·雲開發是什麼呢? 先來看看官方文檔的描述小程序

小程序·雲開發爲開發者提供完整的原生雲端支持和微信服務支持,弱化後端和運維概念,無需搭建服務器,使用平臺提供的 API 進行核心業務開發,便可實現快速上線和迭代,同時這一能力,同開發者已經使用的雲服務相互兼容,並不互斥後端

其實翻譯過來就是,一個在小程序中使用的,不用購買服務器,不用運維的簡易後端體系,主要是爲了突出快和簡便。因此小程序·雲開發,就很是適合那些對數據自己弱依賴的,中小型的功能性小程序使用。微信小程序

小程序·雲開發主要有幾大部分組成,分別是雲控制檯、數據庫、雲函數、存儲、雲調用。以及分別在小程序端,和雲端使用的 SDK。關於這幾部分的具體內容,能夠在官方文檔中查看。

與傳統的電商後端開發相比,小程序·雲開發有如下區別

傳統電商後端開發 小程序·雲開發
後端代碼 自主編寫、開發接口 開發接口,雲函數部署
服務器 自主購買、部署 官方提供,部署
數據監控 自主搭建 官方提供,控制檯查看
調用日誌 自主搭建 官方提供,控制檯查看
費用 服務器購買成本 免費配額,可申請上調

使用小程序•雲開發,咱們能夠省略後端部署、運維等步驟,能夠快速地構建所須要的後端應用。同時,雲函數的開發都是很是簡單的,官方提供的API可讓咱們便捷地進行操做。它能夠很快速上手。只需掌握 JavaScript 和一些異步處理相關的知識,對前端同窗比較友好。小程序·雲開發是小程序官方推出的一種解決方案,不用擔憂是否會繼續維護、升級迭代等的問題。

項目實戰

說了這麼多,是否是有點火燒眉毛的想體驗一下了?那接下來,開始搭建咱們的小程序。

要進行 Taro 的項目開發,首先天然要安裝 taro-cli,具體的安裝方法可參照 Taro 文檔,這裏不作過多介紹了,默認你已經裝好了 taro-cli 並能運行命令。 而後咱們用 cli 新建一個項目, 選擇雲開發模板。

而後咱們會獲得這樣的項目模板

├── client
│   ├── config
│   │   ├── dev.js
│   │   ├── index.js
│   │   └── prod.js
│   ├── index.html
│   ├── package.json
│   └── src
│       ├── app.js
│       ├── app.scss
│       ├── components
│       │   └── login
│       │       └── index.weapp.js
│       └── pages
│           └── index
│               ├── index.js
│               └── index.scss
├── cloud
│   └── functions
│       └── login
│           ├── index.js
│           └── package.json
└── project.config.json
複製代碼

能夠看到目錄裏主要分了兩大塊 client和 cloud:

client 裏和咱們日常小程序的開發目錄,存放的都是小程序裏業務代碼。

cloud 裏則是放雲函數相關的代碼,而且是以模板進行分割,每一個模塊一個雲函數。

pages裏面是各個頁面的入口文件,簡單的頁面就直接一個入口文件能夠了,假若頁面比較複雜那麼入口文件就會做爲組件的聚合文件

組件都放在components裏面。裏面的目錄是這樣的,假若有個 search 搜索頁面,在 pages 天然先有個 search,做爲頁面入口,而後它的組件就會存放在 components/search 裏面,就是components裏面也會按照頁面分模塊,公共的組件能夠建一個 components/* 文件夾,進行復用。這樣的好處是頁面之間互相獨立,互不影響。

接下來咱們開始添加頁面代碼。
首先咱們在搭建小程序的時候,須要把總體的流程給梳理清楚。大體的流程如圖所示:

固然,實際的業務會有更加複雜的流程,這裏咱們不細談。接下來咱們分別來看看相應的後臺服務如何去搭建。

咱們知道一個最簡單的後端程序就是,開啓一個 HTTP服務,鏈接上數據庫,而後根據收到的請求進行相關操做,例如數據庫的增刪查改,返回 HTML,返回接口數據之類,若是要知足外網訪問還要部署上線等等。

而用上了小程序·雲開發以後,由於雲函數這個概念,咱們免去了開啓服務器和部署的步驟。同時,小程序是自然先後端分離的,也不須要返回HTML。因此在這種狀況下,咱們所搭建的後臺服務最主要爲了實現兩個部分的內容,分別是數據庫的創建和先後端的數據交互。

數據庫創建

數據庫創建,指的是數據集合及一些初始數據的建立。在本次搭建的示例中,主要含有一下數據集合:

  • Information 首頁的資訊數據集。主要是以一個資訊爲單位的數據集合,一個資訊可能含有商店圖片,商店介紹,商品介紹等,主要做導購做用,點擊後引導至相關頁面。
  • Shop - 商店頁的數據集。以商店爲單位,一個商店頁面裏主要是各類樓層數據。
  • Commodity - 商品的數據集。顯然,一個商品數據天然就是該商品所須要的各類信息。
  • Cart - 購物車的數據集。以用戶爲單位存放購物車數據。
  • Order - 訂單的數據集。以用戶爲單位存放訂單數據。
  • User - 用戶信息的數據集。存放用戶信息數據。

以上基本就涵蓋了一個最簡單的電商所須要的各類數據,能夠構成一個完整的購物流程。 同時以下圖,還能夠設置數據集權限。例如將 Information、 Shop、Commodity設置爲全部用戶可讀、僅管理員可寫;將 Cart、 Order、 User改爲僅建立者及管理員可讀寫。經過權限限制,加強了數據集的可靠性。

數據交互

數據集創建起來後,再往裏面填充一些假數據,基本的數據就有了,那麼在小程序中如何進行數據交互?

若是不是用小程序·雲開發,天然是經過request拉取接口數據,進行展現。而在使用了小程序·雲開發的狀況下,經過官方提供的 sdk,主要有兩種辦法進行數據拉取:

1.直接在小程序端操做數據庫,獲取所需數據,並進行增刪查改等操做。
2.使用雲函數,把數據庫的操做放到雲端;而後在小程序端調用雲函數,達到相似調用接口的效果。

第一種方法其實比較適合一些簡單的、對數據要求不高、量也不大的小程序。否則在小程序的代碼中混合着數據庫操做,實踐起來不太優雅,也不利於維護。

這裏咱們使用第二種方法。所謂雲函數,就是將一個函數放在 Node.js(即服務端)環境下運行。所以,咱們能夠將數據庫的操做放到雲函數中執行,而後在小程序中調用雲函數,達到一種相似調用接口的效果。

碼起來

有了大體的思路以後,咱們就開始動手寫碼了~ 先來配置整個小程序的配置。在 src 的 app.js 中設置好相關信息,並初始化雲函數

class App extends Component {

  config = {
    pages: [
      'pages/index/index'
    ],
    window: {
      backgroundTextStyle: 'light',
      navigationBarBackgroundColor: '#ffffff',
      navigationBarTitleText: 'Taro商城',
      navigationBarTextStyle: 'black'
    },
    tabBar: {
      color: '#7b7b7a',
      selectedColor: '#c0a369',
      backgroundColor: '#222222',
      list: [
        {
        pagePath: 'pages/index/index',
        text: '首頁',
        iconPath: 'asset/home.png',
        selectedIconPath: 'asset/home_active.png'
      },{
        pagePath: 'pages/cart/cart',
        text: '購物車',
        iconPath: 'asset/shoppingbag.png',
        selectedIconPath: 'asset/shoppingbag_active.png'
      }, {
        pagePath: 'pages/user/order/list/list',
        text: '訂單',
        iconPath: 'asset/mine.png',
        selectedIconPath: 'asset/mine_active.png'
      }]
    },
    cloud: true,
    networkTimeout: {
      request: 6000,
      connectSocket: 10000,
      uploadFile: 10000,
      downloadFile: 10000
    }
  }

  constructor () {
    super(...arguments)
  }

  componentDidMount () {
    Taro.cloud.init({
      env: 'eshop-env-wuivn', // 獲取環境ID:前往 雲開發控制檯-設置-環境ID
      traceUser: true // 是否要捕捉每一個用戶的訪問記錄。設置爲true,用戶可在管理端看到用戶訪問記錄
    })
  }
}
複製代碼

首頁部分

如題所示,首頁大體分爲頂部的搜索的組件,以及店鋪和商品展現的樓層組件。那很明顯能夠看出,搜索的組件,應該是一個公用的模塊,它會在搜索頁,分類頁之類的地方出現。那能夠把這塊組件抽離出來,進行復用。這裏由於時間關係,就不詳細展開。 而後下方的樓層組件,也是一些樣式佈局。由於時間關係,這裏咱們就用圖片代替。

index.js

<View className={indexClassNames}>
 <View className='index-search_into'> <SearchInto placeholder='搜索框' type='index' /> </View> <ScrollView scrollY className='index_list'> { floorList.map((floor, index) => { return ( <View key={index} className={floor.className} onClick= {this.onGotoPage.bind(this, floor.venderId)}> <Image mode='widthFix' className='index_item_img' src={floor.image} lazyLoad /> </View> ) })} </ScrollView> </View> 複製代碼

商詳部分

從首頁進商詳的店鋪入口,那這裏的也是店鋪內的搜索加上展現樓層,樣式佈局也很少說,擼起來。 到這裏你能夠看到,這兩個頁面的邏輯只是簡單的根據 id 拉取數據並返回,由於總體也並無過多與用戶發生交互的部分,也沒有須要後端邏輯處理的部分,總的來講仍是比較簡單的,在這裏便不做過多介紹。

從店鋪進到商品詳情頁,這裏在加入購物車時,須要選擇商品的一些具體規格,默認地址等等。 那這裏咱們就簡單的只選擇下單的商品的一些詳情。這裏增長了下浮層交互,其餘的仍是一些拉取數據展現,也很少細講,還有不少細節部分大家能夠額外時間去研究下。

購物車部分

購物車頁相較於首頁和商詳頁,其邏輯一定是複雜了不少,下面結合頁面結構來分析一下。 上面的圖是購物車的截圖。能夠看到在購物車裏,小程序·雲開發端須要處理的邏輯有商品的選擇與反選、商品刪除、商品數量的更改、商品型號的更改等等。所以,咱們把購物車操做分類,獲得以下一個 map:

const typeMap = {
    ADD: '2',   // 加車
    CHANGE_NUM: '3', // 改變數據
    DEL: '4', // 刪除商品
    CHECK: '5', // 選中商品
    INVERT_CHECK: '6', // 反選商品
    ...
}
複製代碼

而後,在用戶執行相應的操做時,咱們便會執行到對應的操做函數:

switch (type) {
     case typeMap['CHANGE_NUM']: newCartInfo = changCartNum(oldCartInfo, skus)
     break
     case typeMap['ADD']: newCartInfo = changCartNum(oldCartInfo, skus)
     ...
 }
複製代碼

數組)。而後返回處理後、最新的 newCartInfo (新的購物車裏的商品)。具體的操做函數的邏輯咱們便再也不闡述了,主要就是對數組進行遍歷而後根據相關操做處理數據,更新完數據庫後,便會返回給前端最新的購物車數據。若是後續有新的購物車操做須要迭代,或者處理邏輯須要變動,咱們也只須要改變小程序·雲開發端執行函數 這一部分裏面的內容便可。

訂單部分

訂單頁這塊主要處理的是生成訂單的邏輯。每一個用戶的購物車中,已勾選的商品數據都是存放在數據庫中的,因此當用戶點擊了去結算按鈕,觸發告終算請求時,後端會直接從用戶數據庫中的購物車數據,生成一份訂單。詳細的流程能夠用以下的流程圖描述:

下面咱們來看具體代碼:

let cartData = await cartColl.doc(_id).get()
  cartData = cartData.data

  // 獲取購物車中被選中的數據
  const payInfo = cartData.cartInfo.filter((item) => {
    return item.isCheck
  })

  // 使用新的商品map
  const oldShopMap = cartData.shopMap[0]
  const newShop = {}
  payInfo.forEach(item => {
    newShop[item.venderId] = oldShopMap[item.venderId]
  })

  if (payInfo.length === 0) {
    return {
      code: -1,
      msg: '購物車中沒有勾選物品'
    }
  }

  const orderId = Math.random().toString(36).substr(2)

  const orderData = {
    _id: orderId,
    dateSubmit: db.serverDate(),
    orderId,
    orderState: 1,
    ownerId: _id,
    payType,
    shopInfo: newShop,
    shouldPayPrice: cartData.totalPrice + freightPrice,
    skuInfoList: payInfo,
    cancelReasonText: '提交申請'
  }

  // 新插入訂單
  await orderColl.add({data: orderData}).catch(err => console.log(err))

  // 購物車中除移生成了訂單的商品
  let newCartNum = 0
  let newCartShopMap = {}
  const newCartInfo = cartData.cartInfo.filter((item) => {
    if (!item.isCheck) {
      newCartShopMap[item.venderId] = oldShopMap[item.venderId]
      newCartNum += item.num
      return true
    }
    return false
  })

  await cartColl.doc(_id).update({data: {
    cartInfo: newCartInfo,
    cartNum: newCartNum,
    shopMap: [newCartShopMap],
    totalPrice: 0
  }})

  return {
    code: 0,
    msg: '成功生成訂單',
    data: orderData
  }
複製代碼

從代碼中能夠看到,先是遍歷當前購物車中的商品,而後把已經勾選的商品存放到 payInfo中。接着根據 payInfo 生成訂單數據,同時除移購物車中已被結算的商品,並更新購物車數據庫。

總體來講,並無太複雜的操做,不過須要注意的是,由於存在不少異步的操做,因此會有使用不少 async/await 命令來進行同步書寫。

除了生成訂單以外,還有取消訂單、刪除訂單等操做。相較於生成訂單,這些就只是讀取訂單、更改狀態而已,便不贅敘。

總結

到這裏,今天的課程差很少也結束了。今天先談了 Taro 爲何選擇使用React語法,而後再從Taro項目的代碼組織,小程序•雲開發,項目的總體搭建思路,以及一些實現細節。 一個完整的電商小程序就算完成了,不過還有不少細節還能夠完善。好比,用戶的受權登陸,數據狀態管理器等等,這就算一些課外做業吧~ 最後,感謝你們參與本次課程,謝謝。

直播視頻回放地址

WeGeek直播課:從0到1快速開發電商小程序-直播視頻回放地址

相關文章
相關標籤/搜索