工业仿真(simulation)--前端(七)--消息栏

在这篇文章中,主要讲解仿真软件的消息栏

那在我们的仿真软件中,消息栏是分为三部分的

  • 系统提示消息【包括打开某个窗口,系统出现了某个警告,错误,网络连接等等】
  • 画布操作消息【对画布的一切操作都会记录在上面,类似于一个历史操作步骤】
  • 仿真控制器【控制仿真的组件】

如图一,二,三

图一 提示消息

图二 画布操作

图三 仿真控制器

在这三个组件中,只有图二不需要和主进程进行通信,提示消息需要监听主进程发送的消息,比如说当有其他渲染进程有重要消息时,就需要通过主进程将消息传递给提示组件

其他渲染进程📢 --> 主进程 --> 👂消息组件

首先说一下提示和画布操作,这两个有异曲同工的地方

提示和画布

先看代码 message.ts

ts 复制代码
import { defineStore } from 'pinia'
import { CanvasOperateType, Message } from '@renderer/types/message'
import { generateUUID } from '@renderer/utils/utils'
import dayjs from 'dayjs'
import { nextTick } from 'vue'

export const useMessageStore = defineStore('message', {
  state: () => ({
    activeTab: 'prompt' as 'prompt' | 'canvas' | 'simControler',

    prompt: [] as Message[],
    messageContentRef: null as HTMLElement | null,
    showNewMessage: false as boolean,

    canvasOperate: [] as CanvasOperateType[],
    canvasOperateContentRef: null as HTMLElement | null
  }),
  actions: {
    //切换tab
    changeTab(tab: 'prompt' | 'canvas' | 'simControler') {
      this.activeTab = tab
    },

    //添加信息
    addPrompt(message: Message) {
      const msg = {} as Message
      //设置id
      msg.id = generateUUID()
      //获取当前时间
      msg.time = dayjs().format('HH:mm:ss')

      msg.content = message.content
      msg.source = message.source
      msg.type = message.type

      //判断当前消息内容是否和上一条消息内容一样
      if (this.prompt.length > 0 && this.prompt[this.prompt.length - 1].content === msg.content) {
        //获取上一条消息的次数,如果没有就默认为1
        const count = this.prompt[this.prompt.length - 1].count || 1
        //设置当前消息的次数
        msg.count = count + 1
        //删除上一条消息
        this.prompt.pop()
      }

      //判断消息是否超过了200条
      if (this.prompt.length > 200) {
        //删除前一百条
        this.prompt.splice(0, 100)
      }
      this.prompt.push(msg)

      if (this.activeTab !== 'prompt') {
        this.showNewMessage = true
      }

      nextTick(() => {
        //将messageContentRef滚动条滚动到最后
        if (this.messageContentRef) {
          this.messageContentRef.scrollTop = this.messageContentRef.scrollHeight
        }
      })
    },

    //添加画布操作信息
    addCanvasOperate(message: CanvasOperateType) {
      const msg = {} as CanvasOperateType
      //设置id
      msg.id = generateUUID()
      //获取当前时间
      msg.time = dayjs().format('HH:mm:ss')

      msg.content = message.content
      msg.source = message.source
      msg.otherMsg = message.otherMsg

      this.judgeCanvasOperate(msg)
      nextTick(() => {
        //将canvasOperateContentRef滚动条滚动到最后
        if (this.canvasOperateContentRef) {
          this.canvasOperateContentRef.scrollTop = this.canvasOperateContentRef.scrollHeight
        }
      })
    },

    //对画布操作进行判断
    judgeCanvasOperate(msg: CanvasOperateType) {
      //判断当前消息内容是否和上一条消息内容一样
      if (
        this.canvasOperate.length > 0 &&
        this.canvasOperate[this.canvasOperate.length - 1].content === msg.content
      ) {
        //获取上一条消息的次数,如果没有就默认为1
        const count = this.canvasOperate[this.canvasOperate.length - 1].count || 1
        //设置当前消息的次数
        msg.count = count + 1
        //删除上一条消息
        this.canvasOperate.pop()
      }

      //判断消息是否超过了200条
      if (this.canvasOperate.length > 200) {
        this.canvasOperate.splice(0, 100)
      }

      this.canvasOperate.push(msg)
    },

    //清除消息
    clearMessage() {
      if (this.activeTab === 'prompt') {
        this.prompt = []
      } else {
        this.canvasOperate = []
      }
    }
  }
})

提示的数据格式和画布操作的格式是差不多的

ts 复制代码
export interface Message {
  id?: string
  time?: string
  source?: string
  content: string
  type?: 'info' | 'warning' | 'error' | 'success'
  count?: number
}

export interface CanvasOperateType {
  id?: string
  time?: string
  source: string
  content: string
  otherMsg?: string
  count?: number
}
  • id:位移ID值,可以采用UUID形式
  • time:当前消息的时间
  • source:消息来源于哪个地方
  • content:消息内容
  • type:消息类型
  • count:当消息和上一条消息重复时,此count就会+1

那此时我们就需要考虑一下,怎么去监听主进程的消息,在我的上一篇文章,属性栏里面其实已经讲过,属性栏数据是来源于主进程的,那么同理,我们也需要写一个监听事件

ts 复制代码
  //监听主进程发送的消息数据
  window.electron.ipcRenderer.on('mainProcessMsg', (e, data): void => {
    useMessageStore().addPrompt(data)
  })

然后这个方法需要放到main.ts里面区立即执行

那么在我们的主进程中,也同样需要一个方法,这个方法起到统一接收消息,然后将消息传递给渲染进程,代码如下

ts 复制代码
import { mainWindow } from '../..'

//给渲染进程的消息框发消息
export const sendMsgToRender = (
  source: string,
  content: string,
  type?: 'info' | 'warning' | 'error' | 'success'
): void => {
  const data = {
    source,
    content,
    type
  }
  //判断mainWindow是否存在
  if (mainWindow) {
    mainWindow?.webContents?.send('mainProcessMsg', data)
  }
}

那么至此我们的消息栏已经将核心讲解完毕了,关于仿真控制器的部分,我需要留到后面和仿真引擎一起讲解

相关推荐
Jinuss3 小时前
Vue3源码reactivity响应式篇之computed计算属性
前端·vue3
落日沉溺于海3 小时前
React From表单使用Formik和yup进行校验
开发语言·前端·javascript
知识分享小能手3 小时前
React学习教程,从入门到精通, React 新创建组件语法知识点及案例代码(11)
前端·javascript·学习·react.js·架构·前端框架·react
会豪3 小时前
工业仿真(simulation)--前端(五)--标尺,刻度尺
前端
会豪3 小时前
工业仿真(simulation)--前端(四)--画布编辑(2)
前端
an__ya__3 小时前
Vue数据响应式reactive
前端·javascript·vue.js
苦逼的搬砖工3 小时前
Flutter UI Components:闲来无事,设计整理了这几年来使用的UI组件库
前端·flutter
想买Rolex和Supra的凯美瑞车主3 小时前
Taro + Vite 开发中 fs.allow 配置问题分析与解决
前端
ruanCat3 小时前
使用 vite 的 base 命令行参数来解决项目部署在 github page 的路径问题
前端·github