Vue全家桶+Socket.io+Express/Koa2打造網頁版手機QQ
Vue全家桶+Socket.io+Express/Koa2打造的網頁版手機QQ(web app),高仿手機QQ7.1.0版本。為了方便大家學習,現在IP定位介面和實時氣溫介面也開放了!介面請在原始碼中檢視。
預覽
線上預覽地址:https://qq.lenshen.com (儘量使用Chrome瀏覽器體驗最佳效果,另外提供了3個測試賬號,需要賬號才能登入哦)
三個測試賬號如下:
-
qq:986992484 密碼:111111
-
qq:986992483 密碼:111111
-
qq:986992482 密碼:111111
技術棧
- Vue2.0:實現前端頁面構建
- Vuex:實現不同元件間的狀態共享
- Vue-router:頁面路由切換,實現單頁的核心
- vueg:頁面複雜場景切換效果
- Socket.io:實現實時訊息推送
- axios:一個基於
Promise
的 HTTP 庫,向後端發起請求 - Express、Koa2:開發環境使用Express,生產環境使用Koa2
- ES6、ES7、ES8:服務端和客戶端均使用ES6語法,promise/async/await 處理非同步
- localStorage:本地儲存使用者資訊
- Webpack:模組打包,前端專案構建工具首選
- SASS(SCSS):CSS預處理語言
- Flex:flex彈性佈局,簡單適配手機、PC端
- CSS3:CSS3過渡動畫及樣式
- IScroll:模擬原生app的列表滾動效果(ListView)
- MySQL:MySQL關係型資料庫持久化資料(考慮到表與表之間關係複雜,需要多表查詢,最複雜的時候是六張表聯查,用MySQL會比Mongodb好得多)
- jsonp:跨域請求資料
- nginx:服務端使用nginx代理埠轉發
使用方式
先將根目錄下的qq.sql匯入到你的MySQL資料庫裡(可以使用Navicat),使用者名稱為root,登入密碼為空。啟動MySQL服務。然後使用cnpm install 安裝所有依賴(最好用cnpm安裝,因為專案依賴很多,npm用的是國外的映象,在網路不穩定的情況下很有可能會導致安裝失敗,而且下載速度遠遠慢於國內的cnpm),最後執行npm run dev。伺服器部署執行專案只需要npm run pm2,這樣就可以常駐程序,不過前提是得先全域性安裝pm2。
目前已經實現了QQ的核心功能,如訊息列表、好友列表、新朋友、好友申請、實時群聊、實時私聊、聊天設定、遮蔽對方聊天、特別關心、會員等級、個性名片、新增好友、刪除好友、好友分組、查詢使用者、登入、登出、切換使用者、右滑顯示側欄、IP地理定位、實時氣溫等等。後期會考慮增加更多功能。如果你想體驗實時聊天的酷炫效果,那麼你可以開啟兩個瀏覽器,用上面不同的賬號登入即可。
截圖
- 訊息頁面
- 聯絡人頁面
- 群聊
- 私聊
分析
-
服務端使用ES6語法
不需要使用babel轉碼以及一系列的配置,只需要將node升級到V8版本,V8已經很好地支援了ES6/ES7/ES8等最新特性,這是目前最好的辦法。升級到V8版本,可以直接到nodejs中文網(http://nodejs.cn/download/) 下載即可,也可以使用NVM切換node版本。
升級到V8後,還不支援通過import/export關鍵字來匯入匯出模組(因為服務端已經有了CommonJS規範,如果再使用import/export的話就有點衝突了),如果一定要使用import/export關鍵字,這時可以在服務端的入口檔案首行新增以下程式碼:
require("babel-core/register")({ presets: ['es2015', 'stage-0'] }) require("babel-polyfill")
上面的模組不可以使用import來匯入,必須使用require,同時需要通過npm安裝babel-core、babel-preset-es2015、babel-preset-stage-0、babel-polyfill等依賴。這樣就可以愉快地使用import/export了。
服務端程式碼片段如下:
// ES7 async/await import express from 'express' import login from '../../controller/login' const loginRouter = express.Router() loginRouter .get('/:user/:pwd', async(req, res) => { // 登入 const result = await login.login(req, res) res.json(result) }) export default loginRouter
-
Socket.io
服務端(結合Express/Koa):
// Server import express from 'express' import http from 'http' import socketio from 'socket.io' const app = express() const server = http.createServer(app) const io = socketio(server) server.listen(3000) io.on('connection', (socket)=>{ socket.emit('news', { hello: 'world' }) socket.on('my other event', function (data) { console.log(data) }) })
客戶端:
// Client <script src="http://localhost:3000/socket.io/socket.io.js"></script> <script> const socket = io.connect('http://localhost:3000') socket.on('news', (data)=>{ socket.emit('my other event', { my: 'data' }) }) </script>
socket.io最核心的兩個api就是emit
和 on
了
,服務端和客戶端都有這兩個api。通過 emit
和 on
可以實現伺服器與客戶端之間的雙向通訊。
emit
:發射一個事件,第一個引數為事件名,第二個引數為要傳送的資料,第三個引數為回撥函式(如需對方接受到資訊後立即得到確認時,則需要用到回撥函式)。
on
:監聽一個 emit 發射的事件,第一個引數為要監聽的事件名,第二個引數為回撥函式,用來接收對方發來的資料,該函式的第一個引數為接收的資料。
服務端常用API:
socket.emit()
:向建立該連線的客戶端傳送訊息
socket.on()
:監聽客戶端傳送資訊
io.to(socketid).emit()
:向指定客戶端傳送訊息
io.sockets.socket(socketid).emit()
:向指定客戶端傳送訊息,新版本用io.sockets.socket[socketid].emit()
,陣列訪問
socket.broadcast.emit()
:向除去建立該連線的客戶端的所有客戶端廣播
io.sockets.emit()
:向所有客戶端廣播
客戶端常用API:
socket.emit()
:向服務端傳送訊息
socket.on()
:監聽服務端發來的資訊
FAQ
若使用的過程中遇到問題,可以加官方群交流:611212696。
如果覺得不錯,就毫不吝嗇地給個star吧。後期專案還會繼續更新和完善。