vue+websocket+Echarts的电商项目

本文最后更新于:8 个月前

说明

此项目根据黑马程序员视频教程编写。在此致谢黑马程序员,黑马程序员B站链接:点击进入>>>
此项目在线地址:http://echarts.starhe.xyz
github仓库:https://github.com/hzx17/echarts/

项目介绍

在生活以图表的形式更能给人直观的感受。此项目基于vue2,利用websocket与echarts来开发的。
项目截图

后端项目开发

  • 后端项目基于koa2框架开发

koa2框架介绍

  • 基于Node.js平台的web开发框架
  • 由express原班人马打造的,express异步是通过回调函数来实现的
  • koa异步处理是通过Generator+yieid实现的
  • koa2是通过async与await语法糖来实现的(node版本需要在7.6以上)
  • 支持洋葱模型的中间件

后台项目结构

   - app.js --运行文件
   - data/  --向前端返回的json数据
   - middleware/ -- 中间件
      - koa_response_data.js 
      - koa_response_duration.js
      - koa_response_header.js
   - utils/ --处理函数
      - file_utils.js
   - service --存放websocket

代码编写

在最开始时,我们并未引入websocket,而是前端通过axios请求来向后台请求数据,我们将最基本的接口与前端页面编写完成,再来通过websocket来对项目进行websocket改造。接口实现通过前端发来的请求名,来查询data文件下的json文件。具体实现过程比较简单,可以查看我的github仓库中middleware中中间件代码的编写。

前端项目页面的基本开发

  • 我们前台项目由六个页面组成,我们首先进行单独页面的开发,再将六个页面整合到一个页面。

切换主题的实现

在echarts官网中下载chalk与vintage两个主题,当然你也可以下载更多的主题来进行切换选择,将主题名存入vuex中theme,注册echarts图表时,传入的主题名为vuex中theme,当切换主题时,就完成了主题切换,当然点击切换主题时,要通过监视属性来监视vuex中theme的改变。将原有的图表销毁,重新调用创建图表的方法。

利用websocket改造项目

后台项目

  • 创建sevice文件,其下创建一个web_socket_serive.js来监听客户端的请求,代码如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    // webSocket使用步骤:
    // 1.引入ws包
    // 2.创建对象
    // 3.监听事件
    // - 连接事件
    // - 接收数据事件
    // 4.发送数据
    const path =require('path')
    const fileUtils=require('../utils/file_utils.js')
    const webSocket=require('ws') // 引入webSocket
    // 创建webSocket服务器对象,绑定的端口号时9998
    const wss = new webSocket.Server({
    port:9998
    })
    module.exports.listen = () => {
    // 监听客户端连接事件
    wss.on('connection',client => {
    console.log('客户端连接成功...')
    // msg:由客户端发送个服务端的数据
    client.on('message', async msg => {
    console.log('客户端发送了数据:'+msg)
    let payload = JSON.parse(msg) // 将前端发送而来的数据接收
    const action = payload.action
    if (action === 'getData') {
    let filePath = '../data/' +payload.chartName + '.json' // 选择的图表路径
    const ret = await fileUtils.getFileJsonData(filePath)
    payload.data = ret // 增加一个data字段,这个字段就是要返回的json文件内容
    client.send(JSON.stringify(payload))
    }else {
    // 原封不动的将所接收到的数据发送到所连接到的客户端
    wss.clients.forEach(client => {
    client.send(msg)
    })
    }
    })
    })
    }
  • 在app.js中开启websocket监听

前台项目

  • 创建一个utils文件,其下创建一个socket_service.js来连接websocket
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    export default class SocketService {
    /**
    * 单类
    * */
    static instance = null
    static get Instance () {
    if (!this.instance) {
    this.instance = new SocketService()
    }
    return this.instance
    }

    ws = null // 和服务器连接的Socket对象
    connected = false // 标识是否连接成功
    sendRetry = 0 // 记录尝试发送数据次数
    connectRetry = 0 // 记录尝试重连次数
    // 存储回调函数
    callBackMapping = {}
    /* 连接客户端的方法 */
    connect () {
    // 连接服务器
    if (!window.WebSocket) {
    return console.log('你的浏览器不支持WebSocket')
    }
    this.ws = new WebSocket('ws://43.138.103.76:9998')

    // 连接成功的事件
    this.ws.onopen = () => {
    console.log('连接服务器成功...')
    this.connected = true
    this.connectRetry = 0
    }
    // 连接失败的事件
    this.ws.onclose = () => {
    console.log('连接服务器失败了')
    this.connected = false
    this.connectRetry++
    if (this.connectRetry < 5) {
    // 重连尝试
    setTimeout(() => {
    this.connect()
    }, 1000)
    }
    }
    // 得到服务端发送过来的数据
    this.ws.onmessage = msg => {
    // console.log('从服务器端接收到了数据...' + msg.data)
    const recvData = JSON.parse(msg.data)
    const socketType = recvData.socketType
    // 判断回调函数是否存在
    if (this.callBackMapping[socketType]) {
    const action = recvData.action
    if (action === 'getData') {
    const realData = JSON.parse(recvData.data)
    this.callBackMapping[socketType].call(this, realData)
    } else if (action === 'fullScreen') {
    this.callBackMapping[socketType].call(this, recvData)
    } else if (action === 'themeChange') {
    this.callBackMapping[socketType].call(this)
    }
    }
    }
    }

    // 回调函数的注册
    registerCallBack (socketType, callBack) {
    this.callBackMapping[socketType] = callBack
    }

    // 取消回调函数
    unRegisterCallBack (socketType, callBack) {
    this.callBackMapping[socketType] = null
    }

    // 发送数据的方法
    send (data) {
    if (this.connected) {
    this.ws.send(JSON.stringify(data))
    } else {
    this.sendRetry++
    setTimeout(() => {
    this.ws.send(JSON.stringify(data))
    }, this.sendRetry * 300)
    }
    }
    }

  • 在vue的created生命周期内调用this.$socket.registerCallBack(‘rankData’, this.getData)将获取数据的函数作为回调函数,this.getData就成为callBackMapping存储函数,在调用发送数据的方法数据就会存储到callBackMapping ,也就是this.getData

其他

echarts的基本使用:http://starhe.xyz/2022/06/11/echarts/echarts基本图表的使用/
利用宝塔面板上线项目:http://starhe.xyz/2022/06/17/宝塔面板/利用宝塔面板上线项目/


本博客所有文章除特别声明外,如需转载或引用,请注明出处!