Vite + Vue3 + Electron 创建打包桌面程序、实现进程通信

news2024/9/24 7:18:00

目录

1. Electron 介绍

2. 使用 Vite 构建 Electron 项目

2.1 创建 Vite 应用,安装 Electron 依赖

2.2 在 vite.config.ts 中,配置 Electron 入口文件

2.3 编写 electron / index.ts

2.3.1 app、BrowserWindow

2.3.2 使用 win.loadURL 加载窗口 / Vite 环境变量

2.3.3 使用 app.whenReady() 初始化app

2.3.4 整理 electron / index.ts

2.4 配置 package json,运行项目

2.4.1 运行项目后,出现的两个报错

2.4.2 开发环境运行效果

3. 打包 Electron 桌面程序

3.1 安装打包依赖,调整打包命令

3.2 修改 electron / index.ts,判断当前环境

3.3 修改 package.json

3.3.1 增加 electron-builder 相关配置

3.3.2 nsis(桌面应用程序安装过程)配置一览

3.4 执行打包,安装应用

3.5 解决 Electron 启动后白屏、在控制台中输出乱码

3.5.1 Electron 启动后白屏

3.5.2 主进程接收渲染进程消息时,在控制台输出乱码

4. 实现 渲染进程 / 主进程 通信(IPC)

4.1 让 Vite 支持 ipcRenderer

4.2 渲染进程发送消息,主进程接收消息

4.3 主进程发送消息,渲染进程接收消息

5. 参考视频


1. Electron 介绍

Build cross-platform desktop apps with JavaScript, HTML, and CSS | ElectronBuild cross-platform desktop apps with JavaScript, HTML, and CSShttps://www.electronjs.org/

Electron 内置了 Chromium 和 Node.js:

  • Chromium 是渲染进程,用于渲染、解析 HTML
  • Node.js 是主进程
  • 渲染进程 / 主进程,使用 IPC 进行通信

VsCode 是 Electron 开发的桌面程序

2. 使用 Vite 构建 Electron 项目

2.1 创建 Vite 应用,安装 Electron 依赖

创建一个 Vite 项目

npm init vite@latest

 

安装 Electron 相关依赖

npm install electron -D
npm install vite-plugin-electron -D 

温馨提示:vite 中支持 Electron 的插件也改为 vite-electron-plugin,就是第二条安装命令

vite-electron-plugin - npmFast, Electron plugin for Vite. Latest version: 0.5.2, last published: 20 days ago. Start using vite-electron-plugin in your project by running `npm i vite-electron-plugin`. There are no other projects in the npm registry using vite-electron-plugin.https://www.npmjs.com/package/vite-electron-plugin

2.2 在 vite.config.ts 中,配置 Electron 入口文件

 

根据上方官网提示,创建 electron / index.ts,与 src 目录同级

配置 Electron 入口文件 —— 打开 vite.config.ts,引入 electron / index.ts

这么配置,就启动一个 Vite 应用就行,就不需要启动 Electron + Vite 了

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import electron from 'vite-plugin-electron'

export default defineConfig({
  plugins: [vue(), electron({
    main: {
      // 配置 Electron 入口文件
      entry: "electron/index.ts"
    }
  })]
})

 

注意:vite-plugin-electron 0.10.4 中,使用 main 会报错,得这么写

electron({
    // main: {
    //   entry: "electron/index.ts"
    // }
    entry: "electron/index.ts"
})

2.3 编写 electron / index.ts

2.3.1 app、BrowserWindow

在 electron 依赖中,可以引入 app、BrowserWindow:

  • app 控制应用程序的事件生命周期(相当于应用程序)
  • BrowserWindow 创建并控制浏览器窗口(相当于打开桌面弹框)

 

实例化 BrowserWindow 对象,创建一个窗口,在内部通过 nodeIntegration、contextIsolation 集成网页和 Node.js(也就是在渲染进程中,可以调用 Node.js 方法)

2.3.2 使用 win.loadURL 加载窗口 / Vite 环境变量

使用 win.loadURL 加载窗口,接收的网址是指:Vite 启动后,会在本地运行一个服务,把这个服务网址丢进去就行

  • 使用 Vite 自带的环境变量 VITE_DEV_SERVER_HOST
  • 如果是 undefined,就换成 VITE_DEV_SERVER_HOSTNAME(现在应该采用这个了)
  • ps:在 Vite 3.2.41中,使用 VITE_DEV_SERVER_URL 表示 Vite 服务器本地路径

 Vite | 下一代的前端工具链下一代前端工具链https://cn.vitejs.dev/

 

关于 Vite 环境变量,可以去终端看下

 

2.3.3 使用 app.whenReady() 初始化app

最后,使用 app.whenReady() 初始化app(在 Electron 完成初始化时触发)

初始化完成后,再挂载上面创建的 桌面应用程序窗口

2.3.4 整理 electron / index.ts

在 electron / index.ts 中,写入下方代码

// app 控制应用程序的事件生命周期(相当于应用程序)
// BrowserWindow 创建并控制浏览器窗口(相当于打开桌面弹框)
import { app, BrowserWindow } from 'electron'
import path from 'path'

// 定义全局变量,获取窗口实例
let win: BrowserWindow | null;

/**
 * 创建一个窗口
 */
const createWindow = () => {
  win = new BrowserWindow({
    webPreferences: {
      devTools: true,
      // 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
      nodeIntegration: true,
      contextIsolation: false,
    }
  })
    // 集成网页和 Node.js 后,需要加载
    // 这里接收的网址是指:Vite 启动后,会在本地运行一个服务,把这个服务网址丢进去就行
    // 使用 Vite 自带的环境变量 VITE_DEV_SERVER_HOST
    // 如果是 undefined,就换成 VITE_DEV_SERVER_HOSTNAME
    
win.loadURL(`http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}`)
}

// 初始化app(在 Electron 完成初始化时触发),挂载上面创建的 桌面应用程序窗口
app.whenReady().then(createWindow)

2.4 配置 package json,运行项目

2.4.1 运行项目后,出现的两个报错

启动项目后,出现下面两个报错

综上所述,需要在 package.json 中,增加 main 字段,去掉 type 字段

{
  "name": "electron-vite",
  "private": true,
  "version": "0.0.0",
  "main": "dist/electron/index.js",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build  &&  electron-builder",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.2.37"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^3.0.0",
    "electron": "^19.0.10",
    "electron-builder": "^23.1.0",
    "typescript": "^4.6.4",
    "vite": "^3.0.0",
    "vite-plugin-electron": "^0.8.3",
    "vue-tsc": "^0.38.4"
  }
}

2.4.2 开发环境运行效果

运行项目 npm run dev

 

3. 打包 Electron 桌面程序

3.1 安装打包依赖,调整打包命令

安装打包依赖 electron-builder

npm install electron-builder -D 

 

安装完成后,在 package json 中,配置 build 命令

"build": "vue-tsc --noEmit && vite build && electron-builder", 

3.2 修改 electron / index.ts,判断当前环境

打完包之后,还需要修改下 electron / index.ts,因为:

  • 开发环境下,我们访问的是 Vite 本地服务
  • 打包之后,我们访问的是 dist 静态文件

所以要修改 win.loadURL 中的路径参数,判断下当前是生产环境,还是开发环境

修改后的 electron / index.ts 如下

// app 控制应用程序的事件生命周期(相当于应用程序)
// BrowserWindow 创建并控制浏览器窗口(相当于打开桌面弹框)
import { app, BrowserWindow } from 'electron'
import path from 'path'

// 定义全局变量,获取窗口实例
let win: BrowserWindow | null;

/**
 * 创建一个窗口
 */
const createWindow = () => {
  win = new BrowserWindow({
    webPreferences: {
      devTools: true,
      // 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
      nodeIntegration: true,
      contextIsolation: false,
      //允许html页面上的javascipt代码访问nodejs 环境api代码的能力(与node集成的意思)
    }
  })

  // 生产环境、开发环境,访问的路径不同
  // 开发环境下,我们访问的是 Vite 本地服务
  // 打包之后,我们访问的是 dist 静态文件
  // 所以这里要加个判断
  if (app.isPackaged) {
      win.loadFile(path.join(__dirname, "../index.html"));
  } else {
    // 集成网页和 Node.js 后,需要加载
    // 这里接收的网址是指:Vite 启动后,会在本地运行一个服务,把这个服务网址丢进去就行
    // 使用 Vite 自带的环境变量 VITE_DEV_SERVER_HOST
    // 如果是 undefined,就换成 VITE_DEV_SERVER_HOSTNAME
    win.loadURL(`http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}`)
  }
}

// 初始化app(在 Electron 完成初始化时触发)
app.whenReady().then(createWindow)

// isPackage 无效,可以换下面的
// 注意:这个环境变量,需要安装 cross-env,在 package.json 中指定下,在 3.5 中写了
// if (process.env.NODE_ENV != 'development') {
     // win.loadFile(path.join(__dirname, "../index.html"));
// } else {
     // win.loadURL(`http://${process.env['VITE_DEV_SERVER_HOSTNAME']}:${process.env['VITE_DEV_SE//RVER_PORT']}`)
// }

注意:这里有坑啊,isPackage 在 Electron 中判断 生产环境 / 开发环境,是会出现 bug 的,具体参考下面的 3.5 有解释

3.3 修改 package.json

3.3.1 增加 electron-builder 相关配置

appId、productName... —— 应用基本信息信息

win、mac —— 不同类型设备配置

nsis —— 桌面应用程序安装过程的配置

  "build": {
    "appId": "com.electron.desktop",
    "productName": "electron",
    "asar": true,
    "copyright": "Copyright © 2022 electron",
    // 输出路径
    "directories": {
      "output": "release/"
    },
    "files": [
      "dist"
    ],
    // mac 配置
    "mac": {
      "artifactName": "${productName}_${version}.${ext}",
      "target": [
        "dmg"
      ]
    },
    // windows 配置
    "win": {
      "target": [
        {
          "target": "nsis",
          "arch": [
            "x64"
          ]
        }
      ],
      "artifactName": "${productName}_${version}.${ext}"
    },
    // 应用程序的安装过程配置
    "nsis": {
      // 关闭了一键集成,因此会走 下一步、下一步、下一步... 进行安装
      "oneClick": false,
      "perMachine": false,
      "allowToChangeInstallationDirectory": true,
      "deleteAppDataOnUninstall": false
    },
    "publish": [
      {
        "provider": "generic",
        "url": "http://127.0.0.1:8080"
      }
    ],
    "releaseInfo": {
      "releaseNotes": "版本更新的具体内容"
    }
  }

 

3.3.2 nsis(桌面应用程序安装过程)配置一览

{ 
  // 一键安装程序、或者辅助安装程序(默认是一键安装)
  "oneClick": false,
  // 是否允许请求提升,如果为 false,则用户必须使用提升的权限重新启动安装程序(仅作用于辅助安装程序)
  "allowElevation": true, 
  // 是否允许修改安装目录(仅作用于辅助安装程序)
  "allowToChangeInstallationDirectory": true,
  // 安装程序图标的路径
  "installerIcon": "public/timg.ico",
  // 卸载程序图标的路径
  "uninstallerIcon": "public/timg.ico",
  // 安装时头部图片路径(仅作用于辅助安装程序)
  "installerHeader": "public/timg.ico",
  // 安装时标题图标(进度条上方)的路径(仅作用于一键安装程序)
  "installerHeaderIcon": "public/timg.ico",
  // 安装完毕界面图片的路径,图片后缀.bmp,尺寸 164*314(仅作用于辅助安装程序)
  "installerSidebar": "public/installerSiddebar.bmp",
  // 开始卸载界面图片的路径,图片后缀.bmp,尺寸 164*314(仅作用于辅助安装程序)
  "uninstallerSidebar": "public/uninstallerSiddebar.bmp",
  // 控制面板中的卸载程序显示名称
  "uninstallDisplayName": "${productName}${version}",
  // 是否创建桌面快捷方式
  "createDesktopShortcut": true,
  // 是否创建开始菜单快捷方式
  "createStartMenuShortcut": true,
  // 用于快捷方式的名称,默认为应用程序名称
  "shortcutName": "TestApp",
  // NSIS 包含定制安装程序脚本的路径,安装过程中自行调用 (可用于写入注册表 开机自启动等操作)
  "include": "script/installer.nsi",
  // 用于自定义安装程序的 NSIS 脚本的路径
  "script": "script/installer.nsi",
  // 是否在卸载时删除应用程序数据(仅作用于一键安装程序)
  "deleteAppDataOnUninstall": false,
  // 完成后是否运行已安装的应用程序(对于辅助安装程序,应删除相应的复选框)
  "runAfterFinish": true,
  // 是否为开始菜单快捷方式和程序文件目录创建子菜单,如果为 true,则使用公司名称
  "menuCategory": false,
}

3.4 执行打包,安装应用

npm run build

打包成功后,生成的文件都放到了 release 目录下(之前在 package.json 里是这么配置的)

双击 exe 结尾的文件,就能运行桌面应用程序了

安装应用

3.5 解决 Electron 启动后白屏、在控制台中输出乱码

3.5.1 Electron 启动后白屏

启动后,发现应用白屏,可以下载 Debugtron 进行调试

发现输出的当前环境是 非生产环境

app. Ispackaged is also false after it is packaged by electronic builder · Issue #35153 · electron/electron · GitHubPreflight Checklist I have read the Contributing Guidelines for this project. I agree to follow the Code of Conduct that this project adheres to. I have searched the issue tracker for a bug report that matches the one I want to file, wit...https://github.com/electron/electron/issues/35153

后面这个问题没有后续了,所以还是先别用 isPackage 那个变量了,可以换种思路:

  • 安装 cross-env,这个包用来设置环境变量
  • 修改 package.json,"dev" : "cross-env NODE_ENV=development vite", 这样就指定了开发时的环境变量,那只要不是开发时,就是生产时
  • 修改 electron / index.ts,process.env.NODE_ENV != 'development' 这么判断生产环境

3.5.2 主进程接收渲染进程消息时,在控制台输出乱码

加上 chcp 65001 输出中文

加上 cross-env NODE_ENV=development 实现自定义开发时的环境变量

 

最终 dev 命令如下:

"dev": "chcp 65001 && cross-env NODE_ENV=development vite",

4. 实现 渲染进程 / 主进程 通信(IPC)

4.1 让 Vite 支持 ipcRenderer

使用 ipcRenderer 进行通信

默认情况下,Vite 不支持 ipcRenderer,得安装插件 vite-plugin-electron-renderer 让他支持

安装 vite-plugin-electron 的时候,就已经同时安装了 vite-plugin-electron-renderer,所以不用重复安装他,直接引入就行

修改 vite.config.ts,不改会报错:Error: Module "path" has been externalized for browser compatibility. Cannot

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import electron from 'vite-plugin-electron'
// 安装 vite-plugin-electron 的时候,就同时安装了 vite-plugin-electron-renderer
import electronRender from 'vite-plugin-electron-renderer'

export default defineConfig({
  plugins: [vue(), electron({
    main: {
      entry: "electron/index.ts"
    }
  }), electronRender()],
  build:{
    emptyOutDir: false,
  }
})

这样,就实现了让 Vite 支持 ipcRenderer

4.2 渲染进程发送消息,主进程接收消息

渲染进程使用 ipcRenderer.send() 发送消息

在 vue 文件中,添加一个按钮,点击后通过 ipcRenderer 给主进程发消息

import { ipcRenderer } from 'electron'
 
const open = () => {
 ipcRenderer.send('openFlyCar')
}

主进程使用 ipcMain.on() 接收消息

在 electron / index.ts 文件中,引入 ipcMain,监听 .vue 文件发出的消息

import { app, BrowserWindow, ipcMain } from 'electron'

// 这段代码在 createWindow 创建窗口函数内执行
ipcMain.on('openFlyCar', () => {
    console.log('收到')
})

 

 

4.3 主进程发送消息,渲染进程接收消息

主进程使用 win.webContents.send() 通知渲染进程消息

const win = new BrowserWindow(xxxxx)
win!.webContents.send('load', { message: "electron初始化了" })

 

渲染进程通过 ipcRenderer.on() 接收主进程发来的消息,会在控制台输出

ipcRenderer.on('load', (_, data) => {
  console.log(data)
})

5. 参考视频

讲的非常非常详细,各种坑都讲到了 

小满Vue3(第三十九章 electron桌面程序)_哔哩哔哩_bilibili小满Vue3(第三十九章 electron桌面程序)是Vue3 + vite + Ts + pinia + 实战 + 源码 +electron的第51集视频,该合集共计110集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bilibili.com/video/BV1dS4y1y7vd?p=51&vd_source=8bc01635b95dbe8ecd349b2c23b03a10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/79056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Autosar MCAL-GTM之TOM

文章目录前言定时器输出模块(TOM)TOM产生PWM的原理TOM中断中断使能中断模式中断映射CFG中TOM通道配置TOM Channel EnableTomChDisableOnTgcTriggerTOM Channel EnableTOM Channel OutputTomChOutputDisableOnTgcTrigTomChannelOutputControlTomChannelOu…

【项目_05】tabcontrol的搭建及回显、使用keep-alive缓存页面、移动端适配 | 基于Vue3全家桶

💭💭 ✨:tabcontrol的搭建及回显、使用keep-alive缓存页面   💟:东非不开森的主页   💜: 总不能还没努力就向生活妥协吧💜💜   🌸: 如有错误或不足之处,希…

【双向ConvLSTM Network:遥感融合】

D2TNet: A ConvLSTM Network With Dual-Direction Transfer for Pan-Sharpening (D2TNet: 双向传输的卷积长短期记忆递归神经网络用于泛锐化) 本文提出了一种高效的具有双向传输的卷积长短期记忆递归神经网络(convolutional long short-ter…

Java Agent 探针技术

Java 中的 Agent 技术可以让我们无侵入性的去进行代理,最常用于程序调试、热部署、性能诊断分析等场景,现如今比较火热的分布式链路追踪项目Skywalking,就是通过探针技术去捕获日志,将数据上报OAP观察分析平台。 Java Agent 技术简…

Socket编程实现TCP、UDP样例

文章目录一.Socket简介二.Socket实现TCPTCP通信简介使用对象及方法简介代码实现服务端代码客户端代码三.Socket实现UDPUDP通信简介UDP程序的使用步骤代码实现服务端代码客户端代码一.Socket简介 socket套接字是通信的基石,是支持TCP/IP协议的路通信的基本操作单元.…

私企招聘:思特威社会招聘

关于我们 思特威(上海)电子科技股份有限公司 SmartSens Technology (股票简称:思特威,股票代码:688213)是一家从事CMOS图像传感器芯片产品研发、设计和销售的高新技术企业,总部设立…

pads logic 生成参考编号带分隔符以及不统计不贴元器件的BOM

1.查看BOM报告 ,这里可以通过下面的方法 Step1:点击文件 Step2: 勾选材料清单,然后点击设置 Step3:在弹出的如下窗口,选择剪切板视图 ,然后选择全选,然后复制,将数据粘贴到excel表格中即可。 2. 参考编号分隔符 …

以前不知道字节面试难在哪,现在体验到了,被虐的很惨

…(这里省略一些不清楚、不知道、忘记了之类的词藻,保留一丝尊严。) 接下来是关于redis哲学三连“是什么?为什么?怎么用?” 我把肚子里仅有的关于Redis的一滴墨水挤成了三滴,仍然没有给出他想要的。继续追问Redis的数据存储方式,操作方法…

微服务框架 SpringCloud微服务架构 微服务保护 30 初识Sentinel 30.1 雪崩问题及解决方案

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护30 初识Sentinel30.1 雪崩问题及解决方案30.1.1 雪崩问题30.1.2 总结30 初识Sentinel 30.1 雪崩问…

类别不平衡Class-imbalance解决方法

类别不平衡是指分类任务中不同类别的训练样例数目差别很大的情况。 1、扩大数据集 2、欠采样 欠采样(under-sampling):对大类的数据样本进行采样来减少该类数据样本的个数,使其与其他类数目接近,然后再进行学习。 随…

第十四届蓝桥杯集训——JavaC组第九篇——位运算符

第十四届蓝桥杯集训——JavaC组第九篇——位运算符 目录 第十四届蓝桥杯集训——JavaC组第九篇——位运算符 值交换 异或值交换 其它位移符号&#xff1a; 这个稍微难度大一些&#xff0c;基础的有【&与、|或、^异或、<<左位移、>>右位移】。 我们一个一个…

游戏开发43课 移动游戏性能优化2

2. 资源优化 病从口入&#xff0c;资源好比是入口&#xff0c;它们若出现问题&#xff0c;会引发一连串性能问题。相反&#xff0c;资源若是优化得好&#xff0c;后面所有章节的性能都可受益。这也是把资源优化的章节提到最前的原因。 2.1 纹理优化 纹理优化的目的是让它们占…

多锦鑫能:低碳化、智能化、无人化矿山运营时代来临

全球气候变暖已经成为人类社会必须面对的重大课题&#xff0c;国际社会在推动节能减排、实现碳中和大目标上也已经达成一致意见。中国作为全球第二大经济体和负责任的大国&#xff0c;也明确向国际社会承诺&#xff0c;将在2030年实现碳达峰、2060年前实现碳中和目标。 围绕这…

[附源码]计算机毕业设计基于Vuejs的中国名茶销售平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

作者推荐 | 【分布式技术专题】「架构设计方案」图解学习法总结集群模式下的各种软负载均衡策略实现及原理分析

背景介绍 在分布式系统中&#xff0c;负载均衡是非常重要的环节&#xff0c;通过负载均衡将请求派发到网络中的一个或多个节点上进行处理。 通常来说&#xff0c;负载均衡分为硬件负载均衡及软件负载均衡。硬件负载均衡&#xff0c;顾名思义&#xff0c;在服务器节点之间安装专…

功能安全软件架构

已剪辑自: https://mp.weixin.qq.com/s/pCenGTqg2Xi_t7b8ebNHMA 1. E-GAS 安全架构思想 汽车功能安全旨在把电子电气系统失效而导致的人身危害风险控制在合理范围内。下图是常见的电子电气系统硬件构成图&#xff0c;一个电子电气系统的构成要素&#xff0c;除了图中可见的硬…

均值坐标参数化(MVC Parameterization)

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 均值坐标定义 均值坐标定义 v0是多边形v1v2v3...vn内的一点v_0是多边形v_1v_2v_3...v_n内的一点v0​是多边形v1​v2​v3​...vn​内的一点 就会存在均值坐标ϕi(v0)ω…

腾讯云服务器CVM快速配置购买教程,新手上云必备!

腾讯云服务器快速配置购买教程是新手必备的上云教程。主机教程网在本文中以腾讯云服务器为例&#xff0c;给大家带来一个完整的、手把手教学的服务器购买流程。助力快速完成服务器的购买、配置、以及网站的搭建&#xff0c;给新手节省宝贵的时间&#xff0c;避免采坑&#xff0…

线程相关学习记录(1)

认识线程 什么是线程 进程&#xff1a; 正常电脑中启动的某个程序应用&#xff0c;并且会获得计算机分配的资源&#xff08;cpu&#xff0c;内存&#xff0c;硬件设备&#xff09; 线程&#xff1a; 进程中为了完成某个功能&#xff0c;内部划分出的不同的资源分配单位。通常…

[附源码]Python计算机毕业设计SSM基于框架的旅游管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…