V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lensh
V2EX  ›  分享发现

Vue2.0 实现网页版手机 QQ

  •  1
     
  •   lensh · 2017-08-10 19:14:34 +08:00 · 3282 次点击
    这是一个创建于 2660 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Vue 全家桶+Socket.io+Express/Koa2 打造的网页版手机 QQ(web app),高仿手机 QQ7.1.0 版本

    预览

    在线预览地址: https://qq.lenshen.com (为了体验到最佳的效果,提供了 3 个测试账号,需要账号才能登陆哦,具体账号和密码下面有讲)

    目前项目已开源,源码地址: https://github.com/lensh/vue-qq

    技术栈

    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:跨域请求数据

    pm2:服务端使用 pm2 部署,常驻进程,比 forever 好用得多( https://github.com/Unitech/pm2

    nginx:服务端使用 nginx 代理端口转发

    使用方式

    先将根目录下的 qq.sql 导入到你的 MySQL 数据库里(可以使用 Navicat),用户名为 root,登录密码为空。启动 MySQL 服务。然后使用 cnpm install 安装所有依赖(最好用 cnpm 安装,因为项目依赖很多,npm 用的是国外的镜像,在网络不稳定的情况下很有可能会导致安装失败,而且下载速度远远慢于国内的 cnpm),最后运行 npm run dev。服务器部署运行项目只需要 npm run pm2,这样就可以常驻进程,不过前提是得先全局安装 pm2。

    尽量使用 Chrome 浏览器体验最佳效果。另外提供了三个测试账号,默认用户的密码都是 6 个 1:

    qq:986992484 密码:111111

    qq:986992483 密码:111111

    qq:986992482 密码:111111

    目前已经实现了 QQ 的核心功能,如消息列表、好友列表、新朋友、好友申请、实时群聊、实时私聊、聊天设置、屏蔽对方聊天、特别关心、会员等级、个性名片、添加好友、删除好友、好友分组、查找用户、登录、注销、切换用户、右滑显示滑动侧栏等等。后期会考虑增加更多功能。 如果你想体验实时聊天的酷炫效果,那么你可以打开两个浏览器,用上面不同的账号登录即可。

    分析

    服务端使用 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 了。

    服务端代码片段如下:

    // ES6 import/export

    import express from 'express'

    import loginRouter from './router/login'

    import registerRouter from './router/register'

    import friendRouter from './router/friend'

    import messageRouter from './router/message'

    import userRouter from './router/user'

    const apiRouter = express.Router()

    apiRouter

    .use('/login', loginRouter)
    
    .use('/register', registerRouter)
    
    .use('/friend', friendRouter)
    
    .use('/message', messageRouter)
    
    .use('/user', userRouter)
    

    export default apiRouter

    // ES8 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/&lt;a href=" http:="" <a="" href="http://socket.io" rel="nofollow">socket.io="" socket.io.js"="" rel="nofollow">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():监听服务端发来的信息

    最后

    如果觉得不错,就毫不吝啬地给个 star 吧。后期项目还会继续更新和完善。

    2 条回复    2017-08-11 17:36:04 +08:00
    90safe
        1
    90safe  
       2017-08-11 10:29:04 +08:00
    不错,功能还蛮全的
    fakeJas0n
        2
    fakeJas0n  
       2017-08-11 17:36:04 +08:00
    厉害了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5300 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 08:42 · PVG 16:42 · LAX 00:42 · JFK 03:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.