electron+vite+vue3 快速入门教程

文章目录

  • 前言
  • 一、electron是什么?
  • 二、electron 进程模型
    • 1.主进程
    • 2.渲染进程
    • 3.预加载脚本
    • 4.进程通信
      • 4.1 send+on(单向)
      • 4.2 invoke+handle (双向)
      • 4.3 主进程向渲染进程发送事件
  • 三、窗口创建与应用事件
  • 四、技术栈和构建工具
  • 五、electron-vite安装
    • 1.环境要求
    • 2.安装
    • 3.快速安装
    • 4、目录结构
    • 5、公共资源和引用
      • 主进程引用公共资源
    • 6、vue-router、pinia、scss、axios安装
      • vue-router安装
      • pinia安装
      • scss安装
      • axios安装
  • 六、打包
    • 1.应用名称修改
    • 2.应用图标更换
    • 3.打包
    • 4.应用签名
  • 七. Electron API
  • 八. 总结


前言

本文将介绍electron基本使用和构建electron+vite+vue3脚手架开发项目,带你快速入门。


一、electron是什么?

Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用的框架。 通过将 Chromium 和 Node.js 嵌入到其二进制文件中,Electron 允许你维护一个 JavaScript 代码库并创建可在 Windows、macOS 和 Linux 上运行的跨平台应用 — 无需原生开发经验。


二、electron 进程模型

1.主进程

每个 Electron 应用都有一个主进程,充当应用的入口点。 主进程在 Node.js 环境中运行,这意味着它能够使用 所有 Node.js API。主进程管理应用窗口,处理窗口事件,与操作系统进行交互控制原生桌面功能,例如菜单、对话框、托盘图标、发送桌面通知,但不进行页面渲染。简单讲主进程主要做桌面原生功能开发,可以调用node或者electron api进行开发。

2.渲染进程

Electron 为每个应用窗口生成一个单独的渲染器进程,负责渲染窗口页面内容,渲染进程页面开发几乎跟web项目开发一样。在渲染进程无法使用Node.js API。简单讲渲染进程就是主要做web页面开发,无法使用node或者electron api。

3.预加载脚本

预加载脚本就是渲染进程和主进程通信桥梁,2端依靠预加载脚本进行通信。预加载脚本在网页加载到渲染器之前注入,类似于 Chrome 扩展的 内容脚本。使用场景例如在渲染进程web页面上需要调用原生桌面功能就得通过预加载脚本通知主进程进行功能实现。

4.进程通信

4.1 send+on(单向)

渲染进程向主进程发送事件

例如实现下面场景:
渲染进程向主进程发送事件,调用原生功能发起桌面通知

预加载脚本通过 contextBridge API 定义 全局(window)对象属性electronApi供渲染进程调用(window.electronApi.notice())

preload.js(预加载脚本)

const { contextBridge,ipcRenderer  } = require('electron')contextBridge.exposeInMainWorld('electronApi', {//notification事件名称在主进程注册监听,content:传递值notice:content=>ipcRenderer.send("notification",content)
})

渲染进程调用
index.html

//发送事件给主进程window.electronApi.notice("你好")

主进程监听事件
main.js

const { ipcMain,Notification } = require('electron')ipcMain.on('notification', (event,content)=>{//收到事件发送桌面通知,title为传递过来的值new Notification({title:"来着渲染层消息",body:content}).show()})

运行结果:

在这里插入图片描述

4.2 invoke+handle (双向)

除了用ipcRenderer.send +ipcMain.on进行通信外还可用ipcRenderer.invoke+ipcMain.handle,区别在与send+on是单向消息无回调,invoke+handle是双向通信在主进程处理完一些异步操作后可以给渲染层返回回调,两者用法基本类似

例如实现下面场景:
渲染进程通知主进程打开原生选择文件功能并返回文件路径

preload.js(预加载脚本)

const { contextBridge,ipcRenderer  } = require('electron')contextBridge.exposeInMainWorld('electronApi', {//dialogOpenFile事件名称在主进程注册监听openFile:()=>ipcRenderer.invoke("dialogOpenFile")
})

渲染进程调用
index.html

//发送事件给主进程进行文件选择,返回选择后文件路径const filePath=await window.electronApi.openFile()console.log(filePath,"文件路径")

主进程监听事件
main.js

const { ipcMain,dialog} = require('electron')ipcMain.handle('dialogOpenFile', ()=>{const { canceled, filePaths } = await dialog.showOpenDialog()if (!canceled) {//返回文件路径return filePaths[0]}})

4.3 主进程向渲染进程发送事件

当从主进程向渲染器进程发送消息时,需要指定哪个渲染器正在接收该消息。 消息需要通过渲染器进程的 WebContents 实例发送到渲染器进程。 此 WebContents 实例包含一个 send 方法,其使用方式与 ipcRenderer.send 相同可看成逆过程。

main.js

import { BrowserWindow } from 'electron'
const mainWindow=  new BrowserWindow()//创建一个窗口
mainWindow.webContents.send("set-title","你好")

preload.js

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('electronApi', {setTitle: (callback) => ipcRenderer.on('set-title', (event, value) => callback(value)),})

index.html

window.electronAPI.setTitle((title) => {console.log(title)//你好
})

三、窗口创建与应用事件

应用窗口是web页面载体,类似浏览器标签一个窗口一个标签页,需要打开多个标签就要创建多个窗口,像vue脚手架属于单应用项目就只需要一个窗口,应用事件指的是一些生命周期或者窗口事件,比如应用退出事件,窗口关闭事件等都有相应的回调。

创建一个窗口示例:

const {  BrowserWindow } = require('electron')
const path = require('node:path')
//创建一个窗口
const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600,autoHideMenuBar: true,//是否隐藏菜单栏webPreferences:{//网页功能设置preload: path.join(__dirname, 'preload.js')//设置预加载脚本},//.....更多配置})//加载窗口html文件win.loadFile('index.html')
}

在这里插入图片描述

  • 通过new BrowserWindow(options)创建一个新窗口
  • 通过loadFile(url)设置窗口对应html文件进行页面渲染,其中url可以是本地html文件也可以是网址连接
  • 通过webPreferences-preload属性设置预加载脚本路径,使窗口初始化时候运行预加载脚本

在 Electron 中,浏览器窗口只能在 app 模块的 ready 事件被触发后创建。 你可以使用 app.whenReady() API 等待此事件

完整代码:

const { app, BrowserWindow } = require('electron')//只能在ready事件触发后创建窗口
app.whenReady().then(() => {createWindow()
})
//创建窗口
const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600})win.loadFile('index.html')
}

更多窗口配置可查看窗口配置属性

在这里插入图片描述

应用/窗口事件可以通过app.on(‘eventName’)注册监听,app是electron内置模块可通过import { app } from 'electron’引入

例如:

//所有窗口关闭发出
app.on('window-all-closed', () => {})//当 Electron 完成初始化时发出一次
app.on('ready', () => {})//当应用被激活时发出
app.on('activate', () => {
})//在应用开始关闭其窗口之前发出
app.on('before-quit', () => {})

还有非常多的事件,具体可查看app模块


四、技术栈和构建工具

上述介绍完electron核心概念和基础用法后,下面将介绍electron结合web技术通过脚手架来开发项目

electron可以和任意web前端技术搭配使用,react或者vue2、vue3或者原生等。构建工具可以选择webpack或者vite。可以手动自由组合从零搭建或者使用一些网上分享的开发模板,传统搭建方式都比较繁琐。这里推荐一个新构建工具electron-vite,它简化了配置过程,支持主进程、渲染进程代码快速热更新,能自主选择前端框架来搭建脚手架项目,提供了更快、更简单的开发体验。


五、electron-vite安装

1.环境要求

需要安装node 18+版本

2.安装

npm切换新淘宝源防止下载过程卡住

npm config set registry https://registry.npmmirror.com/

初始化项目

npm create @quick-start/electron

出现如下一些配置选项按需选择:

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

  • Project name:项目名称自定义输入

  • Select a framework:选择框架,内置vanilla,vue,react,svelte,solid可选择,演示这里我们选择vue

  • Add TypeScript:是否添加TypeScript,演示这里我们选择no

  • Add Electron updater plugin:是否添加Electron更新插件,yes

  • Enable Electron download mirror proxy:镜像下载代理,国内网络建议开启,yes

进入项目目录

cd electron-app

安装依赖

npm install    

修改支持主进程热更新

默认只开启了渲染进程热更新,需要在运行命令后添加参数才能开启主进程热更新, 打开package.json 文件,scripts-dev 命令后面添加 ‘--watch’

在这里插入图片描述

启动项目

npm run dev

桌面出现如下应用窗口,项目启动成功!

在这里插入图片描述
ps:vue内置框架默认为vue3

3.快速安装

你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如,要构建一个 Electron + Vue 项目,运行:

# npm 6.x
npm create @quick-start/electron eletron-app --template vue# npm 7+, extra double-dash is needed:
npm create @quick-start/electron electron-app -- --template vue

目前支持的模板预设如下:

JavaScriptTypeScript
vuevanilla-ts
reactreact-ts
sveltesvelte-ts
solidsolid-ts

4、目录结构

├── build                    // 编译过程输出文件目录
├── dist                    // 打包后输出目录
├── node_modules            // 依赖模块
├── out                     //编译过程输出文件目录
├── resources                // 公共资源文件,主进程使用
│       └── icon.png         //默认图标
├──src                     
│   ├── main               // 主进程开发目录
│   │  └── index.js       //主进程入口文件      
│   ├── preload           // 预加载脚本开发目录
│   │   └── index.js        // 预加载默认脚本
│   └── renderer          // 渲染进程开发目录,类似纯web项目根目录
│              ├── src
│              │    ├── assets  //资源文件目录
│              │    ├── components  //组件目录
│              │    ├── App.vue        // 入口页面
│              │    └── main.js        // 入口文件
│              └── index.js.html        // 默认html文件
├── .editorconfig                    
├── .eslintignore                //eslint代码检查忽略配置文件
├── .eslintrc.cjs                 //eslint代码检查配置文件
├── .gitignore                   //git忽略配置文件
├── .npmrc                       // npm源配置文件
├── .prettierignore               //prettier代码格式化忽略配置文件
├── .prettierrc.yaml              //prettier代码格式化配置文件
├── dev-app-update.yml           
├── electron-builder.yml           //打包配置文件
├──electron.vite.config.mjs       //electron-vite配置文件
├── package-lock.json     
├── package.json              
└──README.md            //项目说明

我们需要重点关注的是src/main ,src/renderer两个目录,基本都在这2个目录内开发代码,main为主进程开发目录放置主进程相关文件,renderer为渲染进程开发目录,放置渲染进程相关文件,renderer目录其实可以当成纯web脚手架生成项目开发,使用除了多了跟主进程通信功能外其他和web脚手架项目一模一样,包括目录结构,第三方UI库安装(elmentui-plus等)、路由vue-router、vuex、pina等。

src/preload 为预加载脚本开发目录,如无特殊需求我们可以不用管,打开src/preload/index.js 查看源码:

import { contextBridge } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'// Custom APIs for renderer
const api = {}// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {try {contextBridge.exposeInMainWorld('electron', electronAPI)contextBridge.exposeInMainWorld('api', api)} catch (error) {console.error(error)}
} else {window.electron = electronAPIwindow.api = api
}

可以看这句 contextBridge.exposeInMainWorld(‘electron’, electronAPI)
默认已经向渲染进程全局注入了“electron”属性,在渲染进程打印下该属性

console.log(window.electron,'electronAPI' )

在这里插入图片描述
发现注入了3个对象属性ipcRenderer,process,webFrame,有了ipcRenderer意味着我们可以直接在渲染进程发送事件给主进程

App.vue

//给主进程发送事件
window.electron.ipcRenderer.send("notice","hello ,来着app.vue页面消息")

main/index.js

import {  ipcMain } from 'electron'
ipcMain.on('notice',(event,msg)=>{console.log(msg)//hello ,来着app.vue页面消息
})

综上所述,我们可以不用编写预加载脚本,直接在web页面通过暴露的electron.ipcRenderer进行通信


5、公共资源和引用

公共目录默认为 根目录/resources,专用于主进程和预加载脚本。例如图标、可执行程序、wasm 文件 等资源,可以将它们放在这个目录中。
默认情况渲染进程公共资源单独管理,在src/renderer新建public文件夹单独存放使用。这跟web脚手架项目公共文件结构和使用一致。

主进程引用公共资源

在主进程中,可以使用 ?asset 后缀将资源作为文件路径导入

import { Tray, nativeImage } from 'electron'
import appIcon from '../../build/icon.ico?asset'let tray = new Tray(nativeImage.createFromPath(appIcon))

在此示例中,appIcon 将解析为:

const path = require("path");
const appIcon = path.join(__dirname, "./chunks/icon-4363016c.ico");

在主进程中文件路径可以用node.js path模块来拼接

  • __dirname:表示当前文件所属目录的绝对路径
  • path.join:将所有参数拼接成一个完整的路径字符串
  • path.resolve:将一些的 路径/路径段 解析为绝对路径,类似cmd的cd命令功能,某些情况下跟path.join效果一样,不加参数表示项目根目录绝对路径
  • process.cwd():node.js进程的当前工作目录,也即项目根目录等价path.resolve()

举例使用:
假设resources公共资源目录有个test.txt文件
在这里插入图片描述
在主进程/src/main/index.js读取它

const path=require('path')
const filePath=path.join(process.resolve(),'/resources/test.txt')//文件路径

const filePath=path.join(process.cwd(),'/resources/test.txt')//文件路径

const  filePath=path.join(__dirname,'../../resources/test.txt')//文件路径

const filePath=path.resolve(__dirname,'../../resources/test.txt')//文件路径

6、vue-router、pinia、scss、axios安装

从目录结构看vite-electron只是生成一个最基础的vue项目,vue全家桶都没安装,为了方便开发我们需要手动安装下,如果对这部份安装很熟可以跳过。

vue-router安装

npm install vue-router -S

renderer/src目录下新建router文件夹,router文件夹内新建一个index.js文件写入:

import { createRouter, createWebHashHistory } from 'vue-router'const router = createRouter({history: createWebHashHistory(),routes: [{ path: '/', redirect: '/home' },{ path: '/home', component: () => import('../views/home/index.vue') }],
})export default router

renderer/src/main.js 引入

import router from './router'const app= createApp(App);
app.use(router);
app.mount('#app')

renderer/src目录下新建views文件夹,views文件夹内新建home文件夹,home文件夹内新建一个index.vue文件写入:

<template>home
</template>
<script setup></script scoped>
<style></style>

App.vue删掉原来代码写入

<template><router-view></router-view>
</template><script setup></script><style></style>

pinia安装

npm install pinia -S

renderer/src目录下新建stores文件夹,stores文件夹内新建一个index.js文件写入:

import { defineStore } from 'pinia'
export const useIndexStore = defineStore('index', {state:()=> {return {}}, getters: {},actions: {},//persist: true,//是否开启持久化存储
})

main.js引入

import { createPinia } from 'pinia' 
const pinia =createPinia();
app.use(pinia);

scss安装

vite-electron默认已安装了less,如果习惯用less可以不安装scss

npm install sass -S

axios安装

npm install axios -S

renderer/src目录下新建utils文件夹,utils文件夹内新建一个request.js文件写入:

import axios from 'axios';
const baseURL = '/'
const http= axios.create({baseURL,timeout: 100000
})
// 请求拦截
http.interceptors.request.use(config=>{return config
},error=>{console.log(error);
})
// 响应拦截
http.interceptors.response.use((res)=>{return res.data
})export default http

ps:拦截逻辑根据实际情况修改写入,可以在renderer/src新建api文件夹统一维护接口

六、打包

1.应用名称修改


修改electron-builder.yml 文件内字段productName
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.应用图标更换

打包的应用图标默认路径在build文件夹下icon.ico,必须是ico格式不能是png等其他格式,如果你的图片格式是ico可以直接替换,打包生效,如果是其他格式需要转换

安装electron-icon-builder插件
electron-icon-builde能 把图片转换为ico格式

npm install electron-icon-builder -D

修改package.json,scripts新增命令行

"electron:generate-icons": "electron-icon-builder --input=./resources/icon.png --output=build --flatten"

在这里插入图片描述
把新图片icon.png放置resources文件夹

执行

npm run electron:generate-icons

可以看到在build目录下生成了一个icons文件夹里面有ico格式图片

在这里插入图片描述
可以直接复制icon.ico图片到build目录下替换,每次都要复制很麻烦我们修改下打包默认的图标路径:
打开electron-builder.yml
在nsis下添加

installerIcon: 'build/icons/icon.ico'

在这里插入图片描述
installerIcon属性定义了打包图标的位置,重新打包生效。
在这里插入图片描述

3.打包

打包过程会去github上下载打包工具,国内网络大概率会卡住导致打包失败,需要手动下载放入指定位置才能顺利打包,具体看下面说明

执行打包命令:

window:

npm run build:win

mac:

npm run build:mac

linux:

npm run build:linux

接下来以打包window演示说明报错解决方法:

1.winCodeSign报错
在这里插入图片描述
把截图上url后面的下载地址复制到浏览器下载,如果浏览器仍然下载不了,
用下面国内源地址下载:

https://cdn.npm.taobao.org/dist/electron-builder-binaries/winCodeSign-2.6.0/winCodeSign-2.6.0.7z

注意下载版本号和报错提示的版本号要一样,不一样的自己修改下载连接:

https://cdn.npm.taobao.org/dist/electron-builder-binaries/ + 版本号 + 文件名

下载后解压到:

C:\Users\Administrator\AppData\Local\electron-builder\Cache\winCodeSign

在这里插入图片描述
ps:AppData是个隐藏文件,文件选项设置需要打开显示隐藏文件功能才能找到目录

2.nsis报错

在这里插入图片描述
同样复制下载地址或者用国内源到浏览器下载
国内源:

https://cdn.npm.taobao.org/dist/electron-builder-binaries/nsis-3.0.4.1/nsis-3.0.4.1.7z

如果版本号不同一样方法修改,下载解压到:

C:\Users\Administrator\AppData\Local\electron-builder\Cache\nsis

在这里插入图片描述

3.nsis-resources报错
在这里插入图片描述

同样复制下载地址或者用国内源到浏览器下载
国内源:

https://cdn.npm.taobao.org/dist/electron-builder-binaries/nsis-resources-3.4.1/nsis-resources-3.4.1.7z

下载解压到

C:\Users\Administrator\AppData\Local\electron-builder\Cache\nsis

在这里插入图片描述

最终打包完成后会在dist文件夹下生成exe安装包

在这里插入图片描述

4.应用签名

通过上面打包出来安装包安装会发现被安全软件报有风险,想绕过风险检测应用必须签名,签名只影响安全检查不影响功能使用 ,签名教程请移步官网查看:https://www.electronjs.org/zh/docs/latest/tutorial/code-signing

在这里插入图片描述


七. Electron API

原生桌面功能需要调用 Electron API,更多 Electron API请查阅官网:https://electron.nodejs.cn/docs/latest/api/app


八. 总结

electron框架对web开发人员来说非常友好,无须了解原生开发技能,就能通过web技术进行桌面应用开发,大大减少学习成本,一套代码能快速构建生成多端应用,也大幅减少了开发成本。
简言之,electron开发可以看成是桌面功能开发+纯web页面开发,桌面功能开发在主进程调用Electron API,而web页面开发就是html,css,js技术栈。

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

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

相关文章

如何实现指定列值排序? ------ MySQL中的field()函数 [让排序更简单]

想自定义排序规则就用field&#xff08;&#xff09; filed(“列名”&#xff0c;“值1”,“值2”…) 案例&#xff1a;要求 STATUS 列 按 N&#xff0c;Y&#xff0c;E&#xff0c; 排序。 select * from 表名 ORDER BY field(STATUS,N,"Y","E") 效果…

C++核心编程之通过类和对象的思想对文件进行操作

目录 ​​​​​​​一、文件操作 1. 文件类型分类&#xff1a; 2. 操作文件的三大类 二、文本文件 1.写文件 2.读文件 三、二进制文件 1.写二进制文件 2.读二进制文件 一、文件操作 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放 通过文件可以将…

Spring 中 HttpServletRequest 作为成员变量是安全的吗?

在使用spring框架开发的时候&#xff0c;经常会在controller类中看到 HttpServletRequest 对象参数&#xff0c;一般我们都是直接使用&#xff0c;但是它是何时、怎么注入到 spring 容器的呢 &#xff1f;另外以成员变量注入的 request 是线程安全的吗 ? Controller public c…

react umi/max 封装页签组件

1. models/tabs // 全局共享数据示例 import { useState } from react;const useUser () > {const [items, setItems] useState<any[]>([]); // 页签的全局Item数据const [key, setKey] useState<string>(/home); // 页签的高亮Keyreturn {items,setItems…

Unity3D和three.js的比较

一、Unity3D和three.js简介 Unity3D是一款跨平台的游戏引擎,可以用于开发2D和3D游戏。它提供了一个可视化的开发环境,包含了强大的编辑器和工具,使开发者可以方便地创建游戏场景、添加物体、设置物理效果、编写脚本等。Unity3D支持多种平台,包括PC、移动设备、主机等,可以…

解析exe文件

概述&#xff1a;上次用java生成exe文件。那如何解析exe文件呢&#xff1f;0.0 首先我们要了解exe文件里面有什么。用360压缩解压一下。 .data&#xff1a; 存储程序中的初始化的全局和静态变量。在程序运行之前&#xff0c;这些变量会被赋予特定的初始值。 .pdata (Procedu…

销售方法用得好,业绩蹭蹭蹭!

新零售模式是随着科技的发展而崭露头角的零售业态&#xff0c;它融合了传统零售与先进技术&#xff0c;为消费者带来了更便捷、智能的购物体验。 其中&#xff0c;自动售货机作为新零售的一种代表形式&#xff0c;通过高度自动化和数字化的手段&#xff0c;为消费者提供更加便利…

【RT-DETR有效改进】移动设备网络ShuffleNetV1(超轻量化网络主干)

前言 大家好&#xff0c;这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进&#xff0c;内容持续更新&#xff0c;每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本&#xff0c;同时修改内容也支持ResNet32、ResNet101和PP…

计算机网络-计算机网络的概念 功能 发展阶段 组成 分类

文章目录 计算机网络的概念 功能 发展阶段总览计算机网络的概念计算机网络的功能计算机网络的发展计算机网络的发展-第一阶段计算机网络的发展-第二阶段-第三阶段计算机网络的发展-第三阶段-多层次ISP结构 小结 计算机网络的组成与分类计算机网络的组成计算机网络的分类小结 计…

【史上最全】前端页面深入浅出浏览器渲染原理

前言 浏览器的核心组件&#xff0c;即通常所说的浏览器内核&#xff0c;是支撑整个浏览器运行的关键性底层软件架构&#xff0c;它由两个关键组成部分构成&#xff1a;一个是负责网页内容解析和渲染的渲染引擎&#xff0c;另一个则是用于执行JavaScript代码的JS引擎。各浏览器厂…

双向搜索的理解和板子

"互相奔赴&#xff0c;各司其职。“ ——双向搜索 双搜的要求&#xff1a; 当我们发现&#xff0c;要从一种状态开始&#xff0c;经过很多次操作&#xff0c;来得到一种给定的状态。 这时候&#xff0c;我们就可以考虑用双向搜索。 从起点和终点开始搜。当二者相遇&…

【React】组件性能优化、高阶组件

文章目录 React性能优化SCUReact更新机制keys的优化render函数被调用shouldComponentUpdatePureComponentshallowEqual方法高阶组件memo 获取DOM方式refs如何使用refref的类型 受控和非受控组件认识受控组件非受控组件 React的高阶组件认识高阶函数高阶组件的定义应用一 – pro…

如何用Python进行数据分析(保姆级教程)

有小伙伴在学Python新手教程的时候说学Python比较复杂的地方就是资料太多了&#xff0c;比较复杂。 很多网上的资料都是从语法教起的&#xff0c;花了很多时间还是云里雾里&#xff0c;摸不清方向。今天就给大家来捋一捋思路&#xff01;帮助大家提高学习效率&#xff01; Pyt…

Markdown 类图绘制详解

✍️作者简介&#xff1a;小北编程&#xff08;专注于HarmonyOS、Android、Java、Web、TCP/IP等技术方向&#xff09; &#x1f433;博客主页&#xff1a; 开源中国、稀土掘金、51cto博客、博客园、知乎、简书、慕课网、CSDN &#x1f514;如果文章对您有一定的帮助请&#x1f…

水电站智能监测泄洪预警系统介绍

一、背景 近年来由于危险河道管理措施不到位&#xff0c;调峰电站泄水风险长期存在&#xff0c;信息通报制度缺失以及民众安全警觉性不高等因素导致的水电站在泄洪时冲走下游河道游客以及人民财产的事故频发。 二、系统介绍 水电站智能监测泄洪预警系统是一种集成了物联网、云…

ElasticSearch的常用增删改查DSL和代码

es增删改查常用语法 我们日常开发中&#xff0c;操作数据库写sql倒是不可能忘记&#xff0c;但是操作es的dsl语句有时候很容易忘记&#xff0c;特地记录一下方便查找。 DSL语句 1、创建索引 -- 创建索引 PUT /my_index {"mappings": {"properties": {&…

GEE中Landsat、Sentinel、Modis主要数据集区别

一、Landsat 1. Collection 1/2 的区别 Collection 2 是Landsat Level 1 数据的又一次重大再处理&#xff0c;显著提高了绝对地理定位精度。 Collection1Collection2时间跨度1972~2021底1972~至今数据等级level 1level1&#xff1a;1972~2021底 level2&#xff1a;1982~至今 …

路由器初始化配置、功能配置

实验环境 拓扑图 Ip规划表&#xff08;各组使用自己的IP规划表&#xff09; 部门 主机数量 网络地址 子网掩码 网关 可用ip Vlan 市场部 38 192.168.131.0 255.255.255.0 192.168.131.1 2-254 11 研发部 53 192.168.132.0 255.255.255.0 192.168.132.1 2-2…

Oracle21C + PLSQL Developer 15 + Oracle客户端21安装配置完整图文版

一、Oracle21C PLSQL Developer 15 Oracle客户端文件下载 1、Oracl21C下载地址&#xff1a;Database Software Downloads | Oracle 中国 2、 PLSQL Developer 15下载地址&#xff1a;Registered download PL/SQL Developer - Allround Automations 3、 Oracle 客户端下载地址…

全球光伏知名企业-晶科能源联合泛微采知连,建立文控管理平台

晶科能源股份有限公司&#xff08;简称“晶科能源”&#xff09;是一家全球知名、极具创新力的太阳能科技企业。 &#xff08;图片素材来自晶科能源官网&#xff09; 公司战略性布局光伏产业链核心环节&#xff0c;聚焦光伏产品一体化研发制造和清洁能源整体解决方案提供&…