返回顶部
首页 > 资讯 > 数据库 >基于Vue+nodejs+Element-ui的聊天框项目
  • 600
分享到

基于Vue+nodejs+Element-ui的聊天框项目

vue.jsmysqlnode.jselementui 2023-08-20 21:08:01 600人浏览 安东尼
摘要

目录 一、项目简介二、环境介绍三、系统展示四、视频功能展示五、前端核心代码展示六、MySQL 数据库创建功能展示七、node.js 核心代码八、总结 一、项目简介 本项目基于纯前端(移动端)技术开发一个聊天系统,界面美观大方,采

一、项目简介

本项目基于纯前端(移动端)技术开发一个聊天系统,界面美观大方,采用nodejs+Vue+ElemenetUI开发实现,主要包含:登录注册,修改个人资料,更改头像,发送消息,单对单聊天等。

二、环境介绍

语言环境:nodejs

数据库Mysql

应用服务器:nodejs

开发工具vscode

开发技术:nodejs+vue+elementUI

三、系统展示

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、视频功能展示

基于Vue+nodejs+Element-ui的聊天系统项目

五、前端核心代码展示

  • 头部导航功能代码
  • 登录注册页居中旋转功能代码
  • 登录页代码
  • 注册页代码
  • 我的主页代码
  • 修改个人信息代码
  • 聊天框内容代码
  • 好友页代码
  • router 路由页代码
import Vue from 'vue'import VueRouter from 'vue-router'import HomeView from '@/components/home'import axios from 'axios'import store from '@/store/index'Vue.use(VueRouter)const routes = [  {    path: '/',    name: 'home',    redirect: 'footer',    component: HomeView,    meta: {      isLogn:true    }  },  {    path: '/login',    name: 'login',    component: () => import('@/views/login/index'),  },  {    path: '/footer',    name: 'footer',    redirect: {name:'user'},    component: () => import('@/views/home/footer.vue'),    meta: {      isLogn:true    },    children: [      {        path: 'user',        name: 'user',        component: () => import('@/views/user/index.vue'),        meta: {          isLogn:true        }      },      {        path: 'mine',        name: 'mine',        component: () => import('@/views/mine/index.vue'),        meta: {          isLogn:true        }      },    ]  },  {    path: '/chat',    name: 'chat',    component: () => import('@/views/chat/index.vue'),    meta: {      isLogn:true    }  },  {    path: '/setMessage',    name: 'setMessage',    component: () => import('@/views/mine/setMessage.vue'),      }]const router = new VueRouter({  mode: 'history',  base: process.env.BASE_URL,  routes})router.beforeEach((to, from, next) => {  const token = localStorage.getItem('token')  const islogin = !!token  // console.log(token, islogin)  var data = ''  axios({    url: `/api/my/myuser`,      method: "get",      headers: {        Authorization: localStorage.getItem("token"),      },    }).then(({ data }) => {      store.commit('userInfo', data.list)      if (to.matched.some((item) => item.meta.isLogn)) {        if (data.status === 1) {          localStorage.removeItem('token')          window.location.href = '/login'        } else {          if (islogin) {            next()          } else {            // 没有跳转至登录            window.location.href = '/login'          }        }      } else {        if (islogin && to.path === '/login') {          // 跳转至首页          window.location.href = '/'          return        }        next()      }    })  })export default router
  • vuex 页代码
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({  state: {    userInfo: [],    isRolling: false,  },  getters: {    isLogin(userInfo) {      return !!userInfo.username     }  },  mutations: {    addlogin(state) {      state.isRolling = !state.isRolling    },    userInfo(state, data) {      state.userInfo = data    }  },  actions: {  },  modules: {  }})
  • package.JSON 页代码
{  "name": "chat_vue",  "version": "0.1.0",  "private": true,  "scripts": {    "serve": "vue-cli-service serve",    "build": "vue-cli-service build"  },  "dependencies": {    "axiOS": "^1.1.3",    "core-js": "^3.8.3",    "element-ui": "^2.15.12",    "vue": "^2.6.14",    "vue-router": "^3.5.1",    "vuex": "^3.6.2"  },  "devDependencies": {    "@vue/cli-plugin-babel": "~5.0.0",    "@vue/cli-plugin-router": "~5.0.0",    "@vue/cli-plugin-vuex": "~5.0.0",    "@vue/cli-service": "~5.0.0",    "sass": "^1.32.7",    "sass-loader": "^12.0.0",    "vue-template-compiler": "^2.6.14"  }}
  • 移动端代码
const WIDTH = 375//如果是尺寸的设计稿在这里修改const setView = () => {    //设置html标签的fontSize    document.documentElement.style.fontSize = (100 * document.documentElement.clientWidth / WIDTH) + 'px'}window.onresize = setViewsetView()
  • main.js页面代码
import Vue from 'vue'import App from './App.vue'import router from './router'import store from './store'import ElementUI from 'element-ui';import 'element-ui/lib/theme-chalk/index.css';import axios from 'axios'import '@/rem/index'Vue.prototype.$axios = axiosVue.use(ElementUI);Vue.config.productionTip = falsenew Vue({  router,  store,  render: h => h(App)}).$mount('#app')

六、mysql 数据库创建功能展示

  • 用户信息表
    在这里插入图片描述
  • 聊天发布内容表
    在这里插入图片描述

七、node.js 核心代码

在这里插入图片描述

  • 根页面
// 导入 express 模块const express = require('express')// 创建 express 的服务器实例const app = express()// 导入 cors 中间件const cors = require('cors')// 将 cors 注册为全局中间件app.use(cors())// 配置解析表单数据的中间件app.use(express.json()) // 解析 json 格式// 注意:这个中间件,只能解析 application/x-www-form-urlencoded 格式的表单数据app.use(express.urlencoded({ extended: false }))// 响应数据的中间件app.use(function (req, res, next) {    // status = 0 为成功; status = 1 为失败; 默认将 status 的值设置为 1,方便处理失败的情况    res.cc = function (err, status = 1) {      res.send({        // 状态        status,        // 状态描述,判断 err 是 错误对象 还是 字符串        message: err instanceof Error ? err.message : err,      })    }    next()})const joi = require('@hapi/joi')// 错误中间件app.use(function (err, req, res, next) {  // 数据验证失败  if (err instanceof joi.ValidationError) return res.cc(err)  // 未知错误  res.cc(err)})// 导入配置文件const config = require('./config')// 解析 token 的中间件const expressJwt = require('express-jwt')// 使用 .unless({ path: [/^\/api\//] }) 指定哪些接口不需要进行 Token 的身份认证app.use(expressJWT({ secret: config.jwtSecreTKEy }).unless({ path: [/^\/api\//] }))// 错误中间件app.use(function (err, req, res, next) {    // 捕获身份认证失败的错误    if (err.name === 'UnauthorizedError') return res.cc('身份认证失败!')})// 导入并注册用户路由模块const userRouter = require('./router/user')app.use('/api', userRouter)// 导入并使用用户信息路由模块const userallRouter = require('./router/userall')// 注意:以 /my 开头的接口,都是有权限的接口,需要进行 Token 身份认证app.use('/my', userallRouter)app.listen(0830, function () {    console.log('api server running at Http://127.0.0.1:0830')})
  • 接口页面

不加密

// 导入 express 模块const express = require('express')// 创建路由对象const router = express.Router()const multiparty = require('multiparty')var multer = require('multer')const fs = require("fs");// 导入用户路由处理函数模块const userHandler = require('../router_handler/user')router.post('/reguser',userHandler.reguser)router.post('/login',userHandler.login)router.get('/uploads', userHandler.image)// 单图上传router.post(    "/upload",    multer({      //设置文件存储路径      dest: "public/image",    }).array("file", 1),    function (req, res, next) {      let files = req.files;      let file = files[0];      let fileInfo = {};      let path = "public/image/" +  'image_' + file.originalname;      fs.renameSync("./public/image/" + file.filename, path);      //获取文件基本信息      fileInfo.type = file.mimetype;      fileInfo.name = file.originalname;      fileInfo.size = file.size;      fileInfo.path = path;      res.json({        code: 200,        msg: "OK",        data: fileInfo,      });    console.log(fileInfo.path)    });// 将路由对象共享出去module.exports = router

加密:

// 导入 expressconst express = require('express')// 创建路由对象const router = express.Router()// 导入用户路由处理函数模块const userAll = require('../router_handler/userall')// 获取所有用户router.get('/userall',userAll.getUserall)// 获取指定用户router.get('/userid', userAll.getUserid)// 获取当前登录用户router.get('/myuser', userAll.getMyuser)// 发布消息router.post('/publish', userAll.setpublish)// 获取消息router.get('/messages', userAll.getMessage)// 更改用户信息router.post('/setmessages', userAll.setMessage)// 向外共享路由对象module.exports = router
  • 接口内容页面

不加密:

const db = require('../db/index')// 导入 bcryptjs 插件(对密码进行加密)const bcrypt = require('bcryptjs')// 导入 path 用来显示图片var path = require('path');// 用这个包来生成 Token 字符串const jwt = require('jsonwebtoken')// 导入全局的配置文件const config = require('../config')// 注册用户的处理函数exports.reguser = (req, res,next) => {    // 接收表单数据    const userinfo = req.body    // 判断数据是否合法    if (!userinfo.username || !userinfo.password) {        return res.send({ status: 1, message: '用户名或密码不能为空!' })    }    const sql = `select * from users where username=?`    db.query(sql, [userinfo.username], function (err, results) {        // 执行 SQL 语句失败        if (err) {          return res.send({ status: 1, message: err.message })        }        // 用户名被占用        if (results.length > 0) {          return res.send({ status: 1, message: '用户名被占用,请更换其他用户名!' })        }        // 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串        userinfo.password = bcrypt.hashSync(userinfo.password, 10)        const articleInfo = {            // 标题、内容、状态、所属的分类Id            ...req.body,            // 文章封面在服务器端的存放路径            image: 'http://127.0.0.1:830/api/uploads?img=1669116817314_21.jpg',            // 账号创建时间            time: new Date(),            // 作者的Id            user_id: Math.floor(Math.random()*(9999999999-100000)+100000)        }        // console.log(articleInfo)        const sql = 'insert into users set ?'        db.query(sql, articleInfo, function (err, results) {            // 执行 SQL 语句失败            if (err) return res.send({ status: 1, message: err.message })            // SQL 语句执行成功,但影响行数不为 1            if (results.affectedRows !== 1) {              return res.send({ status: 1, message: '注册用户失败,请稍后再试!' })            }            // 注册成功            res.send({ status: 0, message: '注册成功!' })        })    })}// 登录的处理函数exports.login = (req, res) => {    const userinfo = req.body    const sql = `select * from users where username=?`    db.query(sql, userinfo.username, function (err, results) {        // 执行 SQL 语句失败        if (err) return res.cc(err)        // 执行 SQL 语句成功,但是查询到数据条数不等于 1        if (results.length !== 1) return res.cc('登录失败!')        // TODO:判断用户输入的登录密码是否和数据库中的密码一致        // 拿着用户输入的密码,和数据库中存储的密码进行对比        const compareResult = bcrypt.compareSync(userinfo.password, results[0].password)        // 如果对比的结果等于 false, 则证明用户输入的密码错误        if (!compareResult) {            return res.cc('登录失败!')        }        // 剔除完毕之后,user 中只保留了用户的 id, username, nickname, email 这四个属性的值        const user = { ...results[0], password: '', user_pic: '' }        // 对用户的信息进行加密,生成 Token 字符串        const tokenStr = jwt.sign(user, config.jwtSecretKey, {            expiresIn: config.expiresIn, // token 有效期为 72 个小时        })        res.send({            status: 0,            message: '登录成功!',            // 为了方便客户端使用 Token,在服务器端直接拼接上 Bearer 的前缀            token: 'Bearer ' + tokenStr,        })    })}// 显示图片exports.image = (req, res) => {    // console.log(__dirname)    // res.sendFile(path.join(__dirname, 'public/image'));    res.sendFile(path.join(process.cwd(), '/public/image/' + req.query.img));    // res.send('image ok')    // console.log(process.cwd(),__dirname)}

加密:

const db = require('../db/index')// 获取所有用户exports.getUserall = (req, res) => {  const sql = `select * from users where user_id!=?`  // console.log(req.user.user_id)  db.query(sql, req.user.user_id,function (err, results) {    // console.log(err, results)    if(err) return res.cc(err)    res.send({      status: 0,      message: '获取所有用户信息成功',      list: results,    })  })  // res.send('ok')}// 获取指定用户exports.getUserid = (req, res) => {  const userinfo = req.url.split('=')  const user_id = userinfo[userinfo.length - 1]    const sql = `select * from users where user_id=?`;  db.query(sql, user_id, (err, results) => {    // 1. 执行 SQL 语句失败    if (err) return res.cc(err)      // 2. 执行 SQL 语句成功,但是查询到的数据条数不等于 1    if (results.length !== 1) return res.cc('获取用户信息失败!')      // 3. 将用户信息响应给客户端    res.send({      status: 0,      message: '获取用户基本信息成功!',      list: results[0],    })  })}// 获取当前用户信息exports.getMyuser = (req, res) => {  const sql = `select * from users where user_id=?`;  db.query(sql, req.user.user_id, function (err, results) {    if (err) return res.cc(err)    if (results.length !== 1) return res.cc('获取用户信息失败!')      // 将用户信息响应给客户端    res.send({      status: 0,      message: '获取当前登录用户信息成功!',      list: results[0],    })  })}// 发布消息exports.setpublish = (req, res) => {  // console.log(req.body.receive_id)  // 接收表单数据  const articleInfo = {    // 发布内容    ...req.body,    // 信息发布时间    time: new Date(),    // 发布者 id    user_id: req.user.user_id,    display_position: req.user.user_id + '' + req.body.receive_id  }  // console.log(articleInfo)  const sql = `insert into chat_table set ?`  db.query(sql, articleInfo,function (err, results) {    // 执行 SQL 语句失败    if (err) return res.send({ status: 1, message: err.message })    // SQL 语句执行成功,但影响行数不为 1    if (results.affectedRows !== 1) {      return res.send({ status: 1, message: '发布消息失败,请稍后再试!' })    }    // 注册成功    // res.send({ status: 0, message: '发布成功!', list: req.body.content })    // console.log(req.body.receive_id,req.user.user_id)    const sql = `select * from chat_table where state=0 and display_position=${req.user.user_id + '' + req.body.receive_id} or display_position=${req.body.receive_id + '' + req.user.user_id}`;    db.query(sql, 0,function (err, results) {      // 1. 执行 SQL 语句失败      if (err) return res.cc(err)          // 3. 将用户信息响应给客户端      res.send({        status: 0,        message: '发布成功!',        list: results,      })    })  })}// 获取指定信息exports.getMessage = (req, res) => {  const userinfo = req.url.split('=')  const user_id = userinfo[userinfo.length - 1]  const sql = `select * from chat_table where state=0 and display_position=${req.user.user_id + '' + user_id} or display_position=${user_id + '' + req.user.user_id}`;  db.query(sql, 0,function (err, results) {    // 1. 执行 SQL 语句失败    if (err) return res.cc(err)      // 3. 将用户信息响应给客户端    res.send({      status: 0,      message: '获取信息成功!',      list: results,    })  })}// 更改用户信息exports.setMessage = (req, res) => {  console.log(req.body,req.user.user_id)  const sql = `update users set ? where user_id=?`  db.query(sql, [req.body,req.user.user_id], (err, results) => {    // 执行 sql 语句失败    console.log(err)    if (err) return res.cc(err)      // 执行 SQL 语句成功,但影响行数不为 1    // if (results.affectedRows !== 1) return res.cc('修改用户基本信息失败!')      // 修改用户信息成功    return res.cc('修改用户基本信息成功!', 0)  })}
  • 验证规则页面
const joi = require('joi')// 用户名的验证规则const username = joi.string().min(1).max(10).required()// 密码的验证规则// const password = joi.string().min(1).max(50).required()// 头像const image = joi.string()// 用户 id 的验证规则const user_id = joi.number().integer().min(1)// 状态const state = joi.string().valid('0', '1')// 注册和登录表单的验证规则对象exports.reg_login_schema = {  // 表示需要对 req.body 中的数据进行验证  body: {    username,    // password,    image,    user_id,    state  },}
  • 链接数据库页面
// 导入 mysql 模块const mysql = require('mysql')// 创建数据库连接对象const db = mysql.createPool({  host: '127.0.0.1',  user: 'root',  password: 'wang20030830',  database: 'chat',})// 向外共享 db 数据库连接对象module.exports = db
  • 加密页面
// 这是一个全局的配置文件module.exports = {    // 加密和解密 Token 秘钥    jwtSecretKey: 'wangshihao No1. ^_^',    // Token 的有效期    expiresIn: '72h'}
  • package.json 页面
{  "name": "chat_node",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"  },  "keywords": [],  "author": "",  "license": "ISC",  "dependencies": {    "@escook/express-joi": "^1.1.1",    "@hapi/joi": "^17.1.0",    "bcryptjs": "^2.4.3",    "cors": "^2.8.5",    "express": "^4.17.1",    "express-jwt": "^5.3.3",    "fs": "^0.0.1-security",    "joi": "^17.7.0",    "jsonwebtoken": "^8.5.1",    "multer": "^1.4.5-lts.1",    "multiparty": "^4.2.3",    "mysql": "^2.18.1",    "path": "^0.12.7"  }}

八、总结

以上就是 聊天框项目的所有功能简介和代码,不懂得可以在评论区里问我或私聊我询问,以后会持续发布一些新的功能,敬请关注。
我的其他文章:https://blog.csdn.net/weixin_62897746?type=blog

来源地址:https://blog.csdn.net/weixin_62897746/article/details/128150447

您可能感兴趣的文档:

--结束END--

本文标题: 基于Vue+nodejs+Element-ui的聊天框项目

本文链接: https://www.lsjlt.com/news/376670.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作