Vue全家桶+SSR+Koa2 全棧開發仿美團網
項目地址: https://github.com/Chocolate1999/Vue-family-bucket-SSR-Koa2-full-stack-development-from-Meituan
學習地址:傳送門
項目介紹
融匯 前端+服務端 全棧項目,提供後端數據接口,源碼開放,可進行二次開發與優化。
主要業務
- 首頁
- 登錄/註冊
- 產品列表
- 產品詳情
- 購物車
- 訂單
技術內容
- 使用 nuxt.js 和 koa2 兩者之間做 SSR
- 數據和狀態同步,使用 Vuex
- 前端使用最新版 Vue 語法 和 Vue Cli
- 後端使用 koa2 ,對應的是 redis 和 mongodb
- 使用了數據對象模型管理工具 mongoose
- 採用餓了麼 element-ui 框架構建頁面,簡潔,美觀
- 數據真實,杜絕 Mock ,逼真體驗
項目重點
Column 1 | Column 2 | Column 3 |
---|---|---|
登錄/註冊 | SMTP服務 | 城市服務 |
推薦服務 | 搜索服務 | 地圖服務 |
購物車 | 訂單設計 | 組件複用設計 |
接口設計 | 數據對象模型 | 思維&技巧 |
項目筆記
【Vue全家桶+SSR+Koa2全棧開發】(二)Vuex基礎
【Vue全家桶+SSR+Koa2全棧開發】(三)Koa2基礎
【Vue全家桶+SSR+Koa2全棧開發】(四)mongoose基礎
【Vue全家桶+SSR+Koa2全棧開發】(五) Redis基礎
【Vue全家桶+SSR+Koa2全棧開發】(六) Nuxt.js基礎
【Vue全家桶+SSR+Koa2全棧開發】(七) 項目搭建與配置
【Vue全家桶+SSR+Koa2全棧開發】學習筆記整合 (全)
項目運行步驟
本項目提供開發時的源碼,可以進行二次開發及優化,歡迎 contributor 參與!
① Star 本倉庫,然後 Fork 到自己 github,下載代碼到本地
# install dependencies
$ npm run install
② 配置後端數據庫文件,啓動 MongoDB 和 Redis 服務(詳情請見上文筆記)
③ 二次開發運行
npm run dev
項目部分技術亮點
1、城市服務組件
城市定位實現原理:
瀏覽器在發出請求的時候,會有一個 request
,在服務器端可以拿到 requset.ip
,然後就可以取數據中心作映射,根據 ip
來定位城市,服務器拿到 city
後再下發給瀏覽器。
原本實現方式: 當頁面渲染完了,向服務器發送請求,甚至可以發一個空內容,然後按照上述實現原理來獲取 city
。即在 mounted 事件之後,向服務器發送請求,然後服務器下發城市名稱。(頁面發送請求渲染,然後又異步請求獲取城市名,共兩次請求)
缺點:網絡請求浪費,影響用戶體驗,異步獲取的城市會 “閃” 一下。
項目實現方式:當瀏覽器去請求文檔的時候,服務端 ip已經知道了,那個時候就可以拿到對應的城市,立即返回數據給瀏覽器。做法就是通過 vuex
來同步狀態,然後通過 SSR
異步請求就能得到數據。
2、用戶數據&狀態
瀏覽器發送一個 request
請求,根據 cookie
,服務器通過 passport
與 redis
來驗證當前是否是登錄狀態,返回 username
。
3、產品詳情頁開發
本項目產品列表頁(如下圖所示)
產品詳情頁(如下圖所示)
每一個列表對應着多個 item
,每個 item
與詳情頁是一對一關係,而上述兩個頁面路由是沒有關聯關係的。特此說明:本項目沒有 產品庫,因此路由沒有根據 id
來,依舊是根據搜索關鍵詞 keyword
。另外,產品列表頁和產品詳情頁之間做了登錄攔截。
接着,關於產品詳情頁是如何跳轉到購物車的呢?
購物車頁面如下圖所示,可以看到,頁面路由依舊是沒有任何關聯,但從下圖地址欄可見,有一個重要的id
屬性。因爲產品詳情頁不能與購物車創建一對一映射關係,即在進入產品詳情頁時,購物車頁面是不存在的。當點擊購買跳轉到購物車時纔會創建一個購物車。另外,產品詳情頁和購物車之間做了登錄攔截。
4、登錄邏輯
- 將登錄頁面用戶輸入的username和password作爲參數,請求接口
/users/signin
- 對密碼加密
self.$axios.post('/users/signin', {
username : window.encodeURIComponent(self.username),
password : CryptoJS.MD5(self.password).toString()
})
- 請求成功跳轉到主頁面
location.href="/"
5、退出邏輯
退出(exit.vue)組件,採用中間件來實現退出操作。
點擊users/components/public/header/user.vue
文件中的退出後跳轉到退出頁(page/exit.vue)
之後,自動的去執行退出操作所以利用middleware
機制,觸發這個獲取退出的接口,讓接口響應完之後,我們再做自動化的執行動作
6、搜索相關
每輸入一個字母都進行一次請求,顯然浪費性能,因此引入lodash
插件,使用debounce
,函數防抖。
import _ from 'lodash'
input:_.debounce(async function(){
let self=this;
let city=self.$store.state.geo.position.city.replace('市','')
self.searchList=[]
let {status,data:{top}}=await self.$axios.get('/search/top',{
params:{
input:self.search,
city
}
})
self.searchList=top.slice(0,10)
},300)
7、購物車相關
父組件pages/cart.vue
通過asyncData獲取數據(接口:/cart/getCart
)
傳給子組件 list.vue
所有訂單數據,由子組件全部渲染出來,通過cartData
變量聯繫,如果我在子組件中更改了購買商品的數量,也就是cartData中的值被更改了,那麼,我們在父組件監聽的total(所有訂單總價),也會重新計算
另外,購物車會創建一個訂單,創建成功後纔會跳轉支付頁面,但需考慮支付的是哪一個訂單,於是支付和訂單之間有一個依賴邏輯聯繫,但是支付和購物車之間是沒有任何依賴的,雖然支付的動作是由購物車發起的,但是購物車和支付之間的橋樑是訂單。
項目成果展示
項目部分截圖如下文所示:
排版
筆記內容按照 中文文案排版指北 進行排版。
結尾
歡迎關注微信公衆號:小獅子前端Vue
謝謝您的支持!✿✿ヽ(°▽°)ノ✿
注:本倉庫不參與商業行爲,也請各位讀者周知。(This warehouse is not involved in commercial activities.)
轉載使用請註明出處,謝謝!