angular2与vue的那些事Vue.jsVue

基于vue+vue-socket.io +express + m

2019-02-13  本文已影响19人  阿踏

先上成品图片


chat.PNG

技术应用以及功能介绍

1.前端框架时用vue2搭建,基于elementUI
2.vue-socket.io长连接的使用
3.用户登陆退出的实时显示
4.聊天数据的保存
3.后端使用express + mongoose来对数据进行操作,主要包括增删改查等

上面技术的使用之前的文章有写,包括vue+express的使用以及mongoose数据库的连接https://www.jianshu.com/p/f50aa818ab66:vue+express的使用
https://www.jianshu.com/p/440bb0c9d7f8 :mongoose数据库的连接

下面介绍vue-socket.io长连接的使用

1.安装

cnpm i vue-socket.io --save
//这里安装使用可能会报错,如果报错使用vue-socket.io的`^2.1.1-a`版本安装

2.在main.js引入

import VueSocketio from 'vue-socket.io';
 Vue.use(VueSocketio,'http://localhost:3000/');
//后面的连接为后端地址,这里express启动的地址端口默认时3000

3.在server/bin/www也就是express目录文件夹下加入以下代码:

var io = require('socket.io').listen(server.listen(port));

4.定义用户表结构:models文件夹下定义chat.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var chatObj = new Schema({
    groupPepole: String,
    groupTime: String
});
module.exports = mongoose.model('chats',chatObj);
// chatName: String,
// chatTime: String

5.定义内容表结构在:models文件夹下定义chatcontent.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var chatconObj = new Schema({
    chatName: String,
    chatTime: String,
    chatContent: String
});
module.exports = mongoose.model('chatcontents',chatconObj);

6.基于experss的增删改查如下:在routers下定义chat.js,并在app.js下引入
var chatRouter = require('./routes/chat');
app.use('/chat', chatRouter);
chat.js代码如下:

var express = require('express');
var Router = express.Router();
var chatModel = require('../models/chat');
var chatConModel = require('../models/chatcontent');
// 保存登陆用户
Router.post('/pepole',function(req,res,next){
      let newDate = new Date();
      let pepoleList = new chatModel({
         groupPepole: req.body.loginName,
         groupTime:  newDate.toLocaleDateString() + ' ' + newDate.toLocaleTimeString()
      });
      pepoleList.save(function(err,doc){
        if(err) {
            res.json({
                states: 0,
                msg: err.message
            });
        }else {
            res.json({
                states: 1,
                msg: '保存成功'
            });
        }
      });  
// 保存用户发布内容
Router.post('/content',function(req,res,next){
    let newDate = new Date();
    let conList = new chatConModel({
        chatName: req.body.chatName,
        chatContent: req.body.chatContent,
        chatTime: newDate.toLocaleDateString() + ' ' + newDate.toLocaleTimeString()
    });
    conList.save(function(err,doc){
      if(err) {
          res.json({
              states: 0,
              msg: err.message
          });
      }else {
          res.json({
              states: 1,
              msg: '保存成功'
          });
      }
    });  
});
//获取内容并返回
Router.post('/geContentList',function(req,res,next){
    chatConModel.find({}, function(err,doc){
      if(err) {
          res.json({
              states: 0,
              msg: err.message
          });
      }else {
          res.json({
              states: 1,
              msg: doc,
              count:doc.length
          });
      }
    });  
});
//获取用户列表
Router.post('/getUserList',function(req,res,next){
    chatModel.find({}, function(err,doc){
      if(err) {
          res.json({
              states: 0,
              msg: err.message
          });
      }else {
          res.json({
              states: 1,
              msg: doc,
              count:doc.length
          });
      }
    });  
});
//退出登陆
Router.post('/out',function(req,res,next){
    let conditions = {
        groupPepole: req.body.loginName
    }
    chatModel.remove(conditions, function (err,doc) {
        if(err) {
            res.json({
                states: 0,
                msg: err.message
            });
        }else {
            res.json({
                states: 1,
                msg: 'doc'
            });
        }
    });
});
module.exports = Router;

下面时长连接的使用

1.在server/bin/www下加入以下代码:

io.sockets.on('connection', (socket) => {
    console.log('链接成功了呀'); 
    //监听新用户加入
     socket.on('login', function(obj){
        //向所有客户端广播用户加入
        io.emit('login', obj);
        // console.log(obj.username+'加入了聊天室');
  });
  socket.on('out', function(obj){
        //向所有客户端广播用户加入
        io.emit('out', obj);
        // console.log(obj.username+'加入了聊天室');
  });
  socket.on('content', function(obj){
        //向所有客户端广播用户加入
        io.emit('content', obj);
        // console.log(obj.username+'加入了聊天室');
    });
});

在前端使用如下:

// 长连接
        sockets: {
            //不能改,j建立连接自动调用connect
            connect: function() {
                //与socket.io连接后回调
                console.log("socket connected");
            },
            //服务端向客户端发送login事件
            login: function(value) {
                //监听login(后端向前端emit  login的回调)
                this.userList.push(value);
                console.log(value, 'valuevaluevaluevaluevaluevalue')
            },
            out: function(value) {
                //监听out(后端向前端emit  out的回调)
                this.userList.push(value);
                console.log(value, 'valuevaluevaluevaluevaluevalue')
            },
            content: function(value) {
                //监听out(后端向前端emit  out的回调)
                this.contentList.push(value);
                console.log(value, 'valuevaluevaluevaluevaluevalue')
            }
        },

前端具体页面如下

<template>
    <div>
        <div id="chat" style="position: relative;">
            <div style="position:fixed;right:100px;top:20px">
                <p>当前用户:{{itemName}}</p>
                <el-button type="danger" style="margin-top:20px" @click="chatLoginOut">退出</el-button>
                
            </div>
            <div style="position:fixed;top:20px;left:20px">
                <el-input v-model="inputUser" placeholder="请输入用户名"></el-input>
                <el-button type="primary" style="margin-top:20px" @click="chatLogin">登陆</el-button>
                <p style="margin-top:10px;font-size:14px">在线人数:<span style="color:red">{{userListNew.length}}</span>人</p>
                <p style="margin-top:10px;font-size:14px" v-for="(item,i) in userList" :key="i">
                    <span style="color:red">{{item.groupPepole}}</span>
                    <span v-if="item.type==='in'">上线了</span>
                    <span v-if="item.type==='out'">下线了</span>
                    <span style="padding-left:10px;color:blue;font-size:12px">{{item.groupTime}}</span>
                </p>
                <p></p>
            </div>
            <div class="sidebar">
                <div class="m-card">
                  <header>
                    <img class="avatar" width="40" height="40" alt="Coffce" src="/static/img/1.jpg">
                    <p class="name">群名称</p>
                   </header>
                   <footer>
                       <input class="search" placeholder="search user...">
                   </footer>
                </div>
                <!--v-component-->
                <div class="m-list">
                    <ul>
                        <!--v-for-start-->
                        <!-- <li>
                            <img class="avatar" width="30" height="30" alt="示例介绍" src="/static/img/2.png">
                            <p class="name">示例介绍</p>
                        </li> -->
                        <li @click="changeName(item.groupPepole)" :class="itemName===item.groupPepole ? 'active' : ''" v-for="(item,i) in userListNew" :key="i">
                            {{item.groupPepole}}
                            <!-- <img class="avatar" width="30" height="30" alt="webpack" src="/static/img/3.jpg"> -->
                            <!-- <p class="name">{{item.groupPepole}}</p> -->
                        </li>
                        <!--v-for-end-->
                    </ul>
                </div>
                <!--v-component-->
             </div>
             <div class="main">
                 <div class="m-message">
                     <ul>
                         <!--v-for-start--><!--v-for-end-->
                         <li style="height:40px" v-for="(item,i) in contentList" :key="i">
                             <span v-if="item.chatName!==itemName" class="contentLeft">{{item.chatName}} : {{item.chatContent}}</span>
                             <span v-if="item.chatName===itemName" class="contentRight">{{item.chatContent}} : {{item.chatName}}</span>
                         </li>
                         <!-- <li style="text-alain:right">121212:23232</li>
                         <li>121212:232323</li> -->
                     </ul>
                 </div>
                 <!--v-component-->
                 <div class="m-text">
                     <textarea v-model="texts" placeholder="点击按钮发送"></textarea>
                     <el-button type="primary" style="margin-top:20px;position: absolute;bottom: 0px;right: 0;" @click="send">发送</el-button>
                 </div>
                 <!--v-component-->
            </div>
        </div>
    </div>   
</template>  
<style scoped>
.contentRight{
    display: inline-block;
    padding: 8px;
    width: auto;
    background: white;
    position: absolute;
    right: 20px;
}
.contentLeft{
    display: inline-block;
    padding: 8px;
    width: auto;
    background: white;
}
#chat {
    overflow: hidden;
    border-radius: 3px;
}
#chat {
    margin: 20px auto;
    width: 800px;
    height: 600px;
}
#chat .sidebar {
    float: left;
    width: 200px;
    color: #f4f4f4;
    background-color: #2e3238;
}
.m-card {
    padding: 9pt;
    border-bottom: 1px solid #24272c;
}
.m-card .avatar {
    border-radius: 2px;
}
.m-card .avatar, .m-card .name {
    vertical-align: middle;
}
.m-card .name {
    display: inline-block;
    margin: 0 0 0 15px;
    font-size: 1pc;
}
.m-card footer {
    margin-top: 10px;
}
.m-card .search {
    padding: 0 10px;
    width: 100%;
    font-size: 9pt;
    color: #fff;
    height: 30px;
    line-height: 30px;
    border: 1px solid #3a3a3a;
    border-radius: 4px;
    outline: 0;
    background-color: #26292e;
}
.m-list li {
    padding: 9pt 15px;
    border-bottom: 1px solid #292c33;
    cursor: pointer;
    -webkit-transition: background-color .1s;
    transition: background-color .1s;
    position: relative;
}
.m-list .avatar {
    border-radius: 2px;
}
.m-list .name {
    display: inline-block;
    margin: 0 0 0 15px;
    position: absolute;
    top: 19px;
}
.m-list li.active {
    background-color: hsla(0,0%,100%,.1);
}
#chat .main {
    position: relative;
    overflow: hidden;
    background-color: #eee;
}
#chat .m-message {
    height: calc(100% - 10pc);
}
.m-message {
    padding: 10px 15px;
    overflow-y: scroll;
}
#chat .main, #chat .sidebar {
    height: 100%;
}
#chat .m-text {
    position: absolute;
    width: 100%;
    bottom: 0;
    left: 0;
}
.m-text {
    height: 10pc;
    border-top: 1px solid #ddd;
}
.m-text textarea {
    padding: 10px;
    height: 100%;
    width: 100%;
    border: none;
    outline: 0;
    font-family: Micrsofot Yahei;
    resize: none;
}
</style>
<script>
    export default{
        components: {
        },
        data(){
            return{
               inputUser: '',
               userLoginIn: '',
               userList: [],
               userListNew: [],
               counts: '',
               itemName: '',
               texts: '',
               contentList: []
            }
        },
        // 长连接
        sockets: {
            //不能改,j建立连接自动调用connect
            connect: function() {
                //与socket.io连接后回调
                console.log("socket connected");
            },
            //服务端向客户端发送login事件
            login: function(value) {
                //监听login(后端向前端emit  login的回调)
                this.userList.push(value);
                console.log(value, 'valuevaluevaluevaluevaluevalue')
            },
            out: function(value) {
                //监听out(后端向前端emit  out的回调)
                this.userList.push(value);
                console.log(value, 'valuevaluevaluevaluevaluevalue')
            },
            content: function(value) {
                //监听out(后端向前端emit  out的回调)
                this.contentList.push(value);
                console.log(value, 'valuevaluevaluevaluevaluevalue')
            }
        },
        mounted(){
            this.getUser();
            this.getCon();
        //    this.$socket.emit('login', {username:'admin'});
        },
        methods: {
            chatLogin() {
               let newDate = new Date();
               // 像后端发数据
               this.$socket.emit('login', {groupPepole:this.inputUser, type: 'in'});
               this.loginIn('in');
               this.getUser();
            },
            chatLoginOut() {
               let newDate = new Date();
               this.$socket.emit('out', {groupPepole:this.itemName, type: 'out'});
               this.loginOut();
               this.getUser();
            },
            changeName(name) {
              this.itemName = name;
            },
            loginIn() {
                //发送请求,这里我封装了axios,报错的话可以用原生的axios请求
                let paramRegist = {
                    type: 'post',
                    path: '/chat/pepole',
                    datas: {
                        loginName: this.inputUser
                    }
                }
                this.$store.dispatch(paramRegist).then(res=>{
                    this.$message({
                    message: res.data.msg,
                    type: 'success'
                    });
                });
            },
            loginOut() {
                let paramRegist = {
                    type: 'post',
                    path: '/chat/out',
                    datas: {
                        loginName: this.itemName
                    }
                }
                this.$store.dispatch(paramRegist).then(res=>{
                    // this.$message({
                    // message: res.data.msg,
                    // type: 'success'
                    // });
                });
            },
            send() {
                this.$socket.emit('content', {chatName:this.itemName, chatContent: this.texts});
                let paramRegist = {
                    type: 'post',
                    path: '/chat/content',
                    datas: {
                        chatName: this.itemName,
                        chatContent: this.texts
                    }
                }
                this.$store.dispatch(paramRegist).then(res=>{
                    // this.contentList = res.data.msg;
                });
            },
             getUser() {
                let paramRegist = {
                    type: 'post',
                    path: '/chat/getUserList',
                    datas: {
                    }
                }
                this.$store.dispatch(paramRegist).then(res=>{
                    this.userListNew = res.data.msg;
                    this.itemName = this.userListNew[0].groupPepole
                });
            },
            getCon() {
                let paramRegist = {
                    type: 'post',
                    path: '/chat/geContentList',
                    datas: {
                    }
                }
                this.$store.dispatch(paramRegist).then(res=>{
                    this.contentList = res.data.msg;
                });
            }
        }

    }
</script>

这个就时实现简单的聊天工具,git地址如下https://github.com/a1218331130/vueBlog

上一篇 下一篇

猜你喜欢

热点阅读