Vue全新技術棧重構黃老師餓了么商家應用總結

項目倉庫地址:https://github.com/konglingwen94/vue-elm-sell

項目線上地址: http://123.56.124.33:5000

前提

自從學習了Vue后蜕劝,能用Vue解決的場景用例最終我都盡可能的用Vue去實現(xiàn)笆环。單純的用例需求并沒有完整的項目開發(fā)流程级及,從中能學到的東西也是有限的壤躲。在這之前除了使用Vue做過vue-music的移動端音樂播放器項目和vue-bytedanceJob(重構某獨角獸互聯(lián)網(wǎng)公司官方招聘網(wǎng)站)之外乾蓬,自己并沒有用Vue涉獵web端更復雜的業(yè)務場景。

為了找一個項目練習内舟,我去github上開始了搜索游桩,當看到https://github.com/ustbhuangyi/vue-sell這個項目時,感覺這個移動端應用的一些業(yè)務場景是自己沒有接觸過的股缸,于是我就照著這個應用的UI功能用自己的知識體系技術棧進行了重構衡楞,大概不到半個月的時間,我完成了第一個commit提交到項目上線運行敦姻,本篇文章就從應用功能技術實現(xiàn)一些方面剖析此項目的開發(fā)過程以及采到的坑瘾境。

項目截圖

<img src="https://user-gold-cdn.xitu.io/2020/7/1/17308b5c66a54ae5?w=286&h=500&f=gif&s=1854225" width="200">
<img src="https://user-gold-cdn.xitu.io/2020/7/1/17308b647f0cba7f?w=286&h=500&f=gif&s=838667" width="200">
<img src="https://user-gold-cdn.xitu.io/2020/7/1/17308b6220974f7e?w=286&h=500&f=gif&s=1786516" width="200">
<img src="https://user-gold-cdn.xitu.io/2020/7/1/17308b316156fd95?w=286&h=500&f=gif&s=954705" width="200">
<img src="https://user-gold-cdn.xitu.io/2020/7/1/17308b33d9cb205e?w=286&h=500&f=gif&s=1187009" width="200">

項目技術棧

  1. 前端

    • vue開發(fā)項目核心框架
    • axios HTTP請求模塊
    • lib-flexible 移動端屏幕適配方案
    • better-scroll 仿IOS效果的移動端滾動庫
    • normalize.css 第三方css樣式初始化模塊
    • es 6/7 下一代javascript語法
  2. 后端

    • express 搭建服務端應用核心框架
  3. 開發(fā)

    • vue-cli 項目初始化腳手架
    • vue-devtools 項目開發(fā)環(huán)境調試工具
    • vscode chrome git macbookpro
  4. 部署

應用功能

  • 商品頁

    • 商品分類導航和商品列表的聯(lián)動效果
    • 點擊商品分類菜單展示對應商品列表信息
    • 添加/刪除商品到購物車
    • 點擊商品進入到詳情頁面
    • 商品添加到購物車動畫效果
    • 頁面滾動到對應商品類別時的標題吸頂效果
  • 評論頁

    • 綜合評論信息渲染
    • 切換評論篩選項按鈕展示對應的信息
    • 選擇展示是否有內容的評論
  • 商家頁

    • 商家店鋪信息展示
    • 收藏店鋪
    • 商家實景圖片具有bounce效果的滑動顯示
  • 應用頭部

    • 點擊展示詳情
    • 公告信息動態(tài)滾動顯示
  • 購物車

    • 根據(jù)商品個數(shù)顯示不同的狀態(tài)
    • 購物車商品列表
    • 支付彈窗
    • 清空購物車
    • 增加/刪除商品
  • 應用局部優(yōu)化

bounce效果是指在應用中頁面位置滾動到一個端點繼續(xù)滑動時出現(xiàn)反彈的效果,常見場景是IOS系統(tǒng)應用滑動效果

功能難點

商品導航和內容的左右聯(lián)動效果

效果演示

完整的組件代碼點https://github.com/konglingwen94/vue-elm-sell/blob/master/src/views/goods/index.vue

image

思路

由于商品導航和內容是兩個獨立的滾動容器镰惦,當滾動到一個目標內容塊時怎么才能激活它所關聯(lián)的導航項呢?我們知道導航項列表和內容列表在排列順序上是一致的迷守,如果能計算出內容滾動位置處在對應區(qū)間塊的索引,也就得到了導航列表應該激活的目標索引旺入,然后就可以用Vue數(shù)據(jù)驅動視圖的思想去實現(xiàn)這一切兑凿。

容器的左右聯(lián)動效果是指容器滾動到目標內容時激活其關聯(lián)的導航菜單項并滾動到可視區(qū)域。

邏輯實現(xiàn)

找到要激活的目標導航項索引的第一步需要把商品內容的各個類別塊在容器內的縱坐標位置存儲起來(給之后找到激活的目標索引提供比較對象)茵瘾,由于列表內容時動態(tài)渲染的礼华,所以這里需要等所有數(shù)據(jù)已經(jīng)渲染完成后才能操作,下面直接看代碼演示吧龄捡!

template部分

<template>
    /* 這里只顯示部分代碼*/
     <ul class="foods-list">
          <li ref="foodsGroup" class="foods-group" v-for="(item,index) in data" :key="index">
            <dl class="foods-group-wrapper">
              <dt :class="{fixed:currentIndex===index}" class="foods-group-name">{{item.name}}</dt>
              <dd
                class="foods-group-item"
                v-for="(food ,key) in item.foods"
                :key="key"
              >
                 {{food.name}}
              </dd>
            </dl>
          </li>
        </ul>
</template>

script部分

 
export default {
    data(){
      return {
          currentIndex: 0,//導航項激活的索引
          currentFood: {},
          data:[],
          sectionHeight: [0],//第一個高度塊坐標`y`值為`0`
          // 渲染完成后的值為 `[0,1281,1459,1612,2000,2270,2565,2952,3574,4436]`
      }  
    },
    created() {
        request
          .get("/goods")
          .then(response => {
            this.data = response;
          })
          .then(() => {
            setTimeout(() => {
              const sections = this.$refs.foodsGroup;
    
              sections.reduce((prevTotal, current) => {
                const sectionHeight = prevTotal + current.clientHeight;
                this.sectionHeight.push(sectionHeight);
    
                return sectionHeight;
              }, 0);
            });
        });
  }
}

有了各個商品塊的y坐標卓嫂,下一步就需要注冊容器元素的滾動事件了,在回調函數(shù)里通過找到實時滾動位置disanceY處在sectionHeight數(shù)組中兩個相鄰元素之間的位置從而就得到了待激活導航索引currentIndex的值聘殖,具體代碼實現(xiàn)如下

<template>
    <div>
        <!--導航菜單-->
         <scroll class="menu">
            <ul class="menu-list">
              <li
                @tap="selectMenu(index)"
                class="menu-item"
                :class="{selected:currentIndex===index}"
                v-for="(item,index) in data"
                :key="index"
              >
               <span>{{ item.name}}</span>
              </li>
            </ul>
          </scroll>
          
        <!--商品內容-->
        <scroll ref="foodsScroll" @scroll="onFoodScroll" class="foods">
        <!--這里省略商品內容模板的代碼-->
        </scroll>
    
    </div>
</template>

export default {

    // 這里省略其他代碼
    
    methods:{
        onFoodScroll({ x, y }) {
          const distanceY = Math.abs(Math.round(y));
          for (let index = 0; index < this.sectionHeight.length; index++) {
            if (
              distanceY >= this.sectionHeight[index] &&
              distanceY < this.sectionHeight[index + 1]
            ) {
              this.currentIndex = index;
            }
          }
        }
    }
}

完整的組件代碼點https://github.com/konglingwen94/vue-elm-sell/blob/master/src/views/goods/index.vue晨雳。由于左右兩側的布局容器都是基于better-scroll實現(xiàn)的頁面滾動行瑞,所以這里需要偵聽better-scroll提供的scroll事件而不是瀏覽器原生的滾動事件。查看better-scrollscroll事件API這里餐禁。

添加/刪除 商品到購物車

效果截圖

image

完整代碼https://github.com/konglingwen94/vue-elm-sell/blob/master/src/components/food-picker/index.vue

思路

添加商品到購物車是一個多場景的功能血久,由于這里的購物車功能是一個多頁面聯(lián)動的效果,購物車商品數(shù)量的實時更改也需要同步到商品內容頁和商品詳情頁帮非。從功能映射到javascript語言數(shù)據(jù)結構層面的話氧吐,不難想到對象引用傳遞的特點可以作為實現(xiàn)此功能的底層架構思路,那就讓我們去實現(xiàn)它吧末盔。

實現(xiàn)

為了統(tǒng)計商品的數(shù)量筑舅。首先需要給每一個商品信息對象添加一個默認值為0count屬性,添加后的對象長這樣

{
  "count": 0, // 此變量用來存儲添加到購物車的數(shù)量
  "name": "皮蛋瘦肉粥",
  "price": 10,
  "oldPrice": "",
  "description": "咸粥",
  "sellCount": 229,
  "rating": 100,
  "info": "一碗皮蛋瘦肉粥陨舱,總是我到粥店時的不二之選翠拣。香濃軟滑,飽腹暖心游盲,皮蛋的Q彈與瘦肉的滑嫩伴著粥香溢于滿口误墓,讓人喝這樣的一碗粥也覺得心滿意足",
  "ratings": [
    {
      "username": "3******b",
      "rateTime": 1469261964000,
      "rateType": 1,
      "text": "",
      "avatar": "http://static.galileo.xiaojukeji.com/static/tms/default_header.png"
    }
  ],
  "icon": "http://fuss10.elemecdn.com/c/cd/c12745ed8a5171e13b427dbc39401jpeg.jpeg?imageView2/1/w/114/h/114",
  "image": "http://fuss10.elemecdn.com/c/cd/c12745ed8a5171e13b427dbc39401jpeg.jpeg?imageView2/1/w/750/h/750"
}

由于每一個商品項都有一個添加到購物車的數(shù)量選擇器功能,這樣我們直接給商品數(shù)量選擇器組件設計一個名為foodInfo的對象類型props益缎,這樣在增加/減少商品數(shù)量的時候直接操作foodInfocount屬性來實現(xiàn)同步數(shù)據(jù)的效果谜慌。

/components/food-picker.vue 組件代碼

<template>
  <div class="food-picker" @click.stop>
    <div class="reduce-wrapper" @click="reduce">
      <i class="iconfont reduce"></i>
    </div>
    <div class="counter">{{foodInfo.count}}</div>
    <div class="add-wrapper" @click="add">
      <i class="iconfont add"></i>
    </div>
  </div>
</template>
<script>
export default {
  name: "food-picker",
  props: {
    foodInfo: {
      type: Object,
      default: () => ({})
    }
  },
  methods: {
    reduce() {
      if (parseInt(this.foodInfo.count) > 0) {
        this.foodInfo.count--;
      }
    },
    add() {
      this.foodInfo.count++;
    }
  }
};
</script>
<style lang="less" scoped>
.food-picker {
  min-width: 180px;
  max-width: 200px;

  display: flex;
  align-items: center;
  width: 100%;
  justify-content: space-between;
  .iconfont {
    color: #00a0dc;
    font-size: 38px;
  }
  .counter {
    // margin: 0 20px;
  }
}
</style>

下一個目標

基于目前已經(jīng)實現(xiàn)的功能,整個應用的數(shù)據(jù)都是以json文件的格式存儲在服務器莺奔,服務端并沒有可以用來增刪改查API接口可供使用欣范。下一步我計劃做出管理后臺和服務端API用來管理前端頁面的數(shù)據(jù),使所有模塊的數(shù)據(jù)都是可配置的弊仪,這樣前端所渲染出來的數(shù)據(jù)也都是動態(tài)的,能夠整合三端到一個項目也滿足了當下Web全棧開發(fā)的場景需要熙卡。

總結

通過真實的開發(fā)這樣一個復雜交互的應用,自己對Vue在實際業(yè)務場景中的使用和理解有深入了一步励饵。深入理解了Vue數(shù)據(jù)驅動視圖改變的思想驳癌,熟練的掌握了組件化開發(fā)項目的流程,同時也感受到所帶來的便利役听,為自己接下來預備做的中大型項目建筑好了橋梁颓鲜。

支持

如果本項目對您學習有幫助,請您動手點個starhttps://github.com/konglingwen94/vue-elm-sell典予。也希望您繼續(xù)關注我的動態(tài)https://github.com/konglingwen94甜滨,有了您的支持我會有動力開源更多有趣的項目。

歡迎點贊和留言瘤袖,謝謝衣摩!

本篇文章屬于作者原創(chuàng),轉載參考請注明出處捂敌,謝謝艾扮!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末既琴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子泡嘴,更是在濱河造成了極大的恐慌甫恩,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酌予,死亡現(xiàn)場離奇詭異磺箕,居然都是意外死亡,警方通過查閱死者的電腦和手機抛虫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門松靡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人莱褒,你說我怎么就攤上這事击困∠雅” “怎么了广凸?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蛛枚。 經(jīng)常有香客問我谅海,道長,這世上最難降的妖魔是什么蹦浦? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任扭吁,我火速辦了婚禮,結果婚禮上盲镶,老公的妹妹穿的比我還像新娘侥袜。我一直安慰自己,他們只是感情好溉贿,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布枫吧。 她就那樣靜靜地躺著,像睡著了一般宇色。 火紅的嫁衣襯著肌膚如雪九杂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天宣蠕,我揣著相機與錄音例隆,去河邊找鬼。 笑死抢蚀,一個胖子當著我的面吹牛镀层,可吹牛的內容都是我干的。 我是一名探鬼主播皿曲,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼唱逢,長吁一口氣:“原來是場噩夢啊……” “哼羡微!你這毒婦竟也來了?” 一聲冷哼從身側響起惶我,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤妈倔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绸贡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盯蝴,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年听怕,在試婚紗的時候發(fā)現(xiàn)自己被綠了捧挺。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡尿瞭,死狀恐怖闽烙,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情声搁,我是刑警寧澤黑竞,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站疏旨,受9級特大地震影響很魂,放射性物質發(fā)生泄漏。R本人自食惡果不足惜檐涝,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一遏匆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谁榜,春花似錦幅聘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至撕瞧,卻和暖如春陵叽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丛版。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工巩掺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人页畦。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓胖替,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子独令,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348