react+ts【项目实战一】配置项目/路由/redux

news2025/2/1 1:45:45

文章目录

  • 1、项目搭建
    • 1、创建项目
    • 1.2 配置项目
      • 1.2.1 更换icon
      • 1.2.2 更换项目名称
      • 1.2.1 配置项目别名
    • 1.3 代码规范
      • 1.3.1 集成editorconfig配置
      • 1.3.2 使用prettier工具
    • 1.4 项目结构
    • 1.5 对css进行重置
    • 1.6 注入router
    • 1.7 定义TS组件的规范
    • 1.8 创建代码片段
    • 1.9 二级路由和懒加载
    • 1.10 redux-reduxtk
    • 1.10 axios的封装
  • 1.11 类组件和TS的结合
    • 1.12 redux和ts的结合

1、项目搭建

1、创建项目

  • 1、该项目使用的是ts创建的 所以需要加上--template typescript
    • create-react-app kiki_ts_react_music --template typescript
  • 2、整理项目结构 删除一些自己用不到的文件
  • 在这里插入图片描述
    在这里插入图片描述

1.2 配置项目

1.2.1 更换icon

在这里插入图片描述

1.2.2 更换项目名称

在index.html文件里面

在这里插入图片描述

1.2.1 配置项目别名

  • 1、npm i -D @craco/craco
  • 2、在根文件创建 craco.config.ts
const path = require("path");
const CracoLessPlugin = require("craco-less");

// path.resolve返回当前文件的绝对路径 拼接+dir
const resolve = (dir) => path.resolve(__dirname, dir);
module.exports = {
 plugins: [{ plugin: CracoLessPlugin }],
 webpack: {
   alias: {
     "@": resolve("src"),
   },
 },
};
  • 3、修改tsconfig.json
    在这里插入图片描述
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  • 4、修改 package.json
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

1.3 代码规范

1.3.1 集成editorconfig配置

EditorConfig 有助于为不同 IDE 编辑器上处理同一项目的多个开发人员维护一致的编码风格。

  • 1、在根目录下创建.editorconfig文件
# http://editorconfig.org

root = true

[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行尾的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行

[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false

**同时需要安装插件 **EditorConfig for VS Code

在这里插入图片描述

1.3.2 使用prettier工具

Prettier 是一款强大的代码格式化工具,支持 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等语言,基本上前端能用到的文件格式它都可以搞定,是当下最流行的代码格式化工具。

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

在这里插入图片描述

  • 1.安装prettier

    npm install prettier -D

  • 2、配置.prettierrc文件:在根目录下创建该文件
    在这里插入图片描述

{
  "useTabs": false,
  "tabWidth": 2,
  "printWidth": 80,
  "singleQuote": true,
  "trailingComma": "none",
  "semi": false
}

  • 3、创建.prettierignore忽略文件 在根目录下
/dist/*
.local
.output.js
/node_modules/**

**/*.svg
**/*.sh

/public/*

  • 4、在package.json中配置一个scripts:
    "prettier": "prettier --write ."

执行 npm run prettier就会将项目全部按照prettier的配置进行格式化

1.4 项目结构

在这里插入图片描述

1.5 对css进行重置

  • 1、下载normalize.css
    cnpm install normalize.css
    在index.tsx里面引入import 'normalize.css'

  • 2、使用less
    cnpm install craco-less

const path = require('path')
const CracoLessPlugin = require('craco-less')

const resolve = (dir) => path.resolve(__dirname, dir)
module.exports = {
 plugins: [{ plugin: CracoLessPlugin }],
 webpack: {
   alias: {
     '@': resolve('src')
   }
 }
}

在这里插入图片描述

  • 3、配置自定义的css
    在这里插入图片描述
    最后都在index.jsx中引入
import 'normalize.css'
import '@/assets/css/index.less'

1.6 注入router

npm install react-router-dom

  • 在tsx中 使用到dom的页面都需要引入import React from 'react'

  • router/index.tsx

import React from 'react'
import type { RouteObject } from 'react-router-dom'
import Discover from '@/views/discover'
import Mime from '@/views/mime'

const routes: RouteObject[] = [
  { path: '/', element: <Mime /> },
  { path: '/discover', element: <Discover /> }
]

export default routes

  • index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from '@/App'
import { BrowserRouter } from 'react-router-dom'
import 'normalize.css'
import '@/assets/css/index.less'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

  • index.tsx
import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routes from './router'

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1>hahah</h1>
        <Link to="/discover">发现音乐</Link>
        <Suspense fallback="正在加载">{useRoutes(routes)}</Suspense>
      </header>
    </div>
  )
}

export default App

1.7 定义TS组件的规范

import React, { memo } from 'react'
import type { ReactNode } from 'react'

// 定义传进来的props类型
interface IProps {
  // 在之前的版本props默认会有children是插槽 在后来取消了得自己写
  children?: ReactNode
  name?: string
  age?: number
}

const Download: React.FC<IProps> = (props) => {
  return (
    <div>
      {props.children}
      <h1>{props.age}</h1>
      <h1>{props.name}</h1>
    </div>
  )
}

export default memo(Download)

import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routes from './router'
import Download from './views/download'

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1>hahah</h1>
        <Link to="/discover">发现音乐</Link>

        <Download name="kiki">
          <h1>我是downLoad的插槽</h1>
        </Download>

        <Suspense fallback="正在加载">{useRoutes(routes)}</Suspense>
      </header>
    </div>
  )
}

export default App

1.8 创建代码片段

首选项=>设置代码片段=>react-ts
在这里插入图片描述

生成代码片段的网站
https://snippet-generator.app/?description=&tabtrigger=&snippet=&mode=vscode
在这里插入图片描述

import React, { memo } from 'react'
import type { FC, ReactNode } from 'react'

interface IProps {
  children?: ReactNode
}

const Template: FC<IProps> = () => {
  return <div>Template</div>
}

export default memo(Template)

1.9 二级路由和懒加载

  • discover页面
import React, { memo, Suspense } from 'react'
import type { FC, ReactNode } from 'react'
import { Outlet, Link } from 'react-router-dom'

interface IProps {
  children?: ReactNode
}

const Discover: FC<IProps> = () => {
  return (
    <div>
      <div>
        <Link to="/discover/recommend">推荐</Link>
        <Link to="/discover/ranking">排行榜</Link>
        <Link to="/discover/songs">歌单</Link>
        <Link to="/discover/djradio">主播电台</Link>
        <Link to="/discover/artist">歌手</Link>
        <Link to="/discover/album">新碟上架</Link>
      </div>
      {/* 二级路由也可以用suspense */}
      <Suspense fallback="正在加载">
        <Outlet />
      </Suspense>
    </div>
  )
}

export default memo(Discover)

  • App.jsx
import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routes from './router'
import Download from './views/download'

function App() {
  return (
    <div className="App">
      <div className="nav">
        <Link to="/discover">发现音乐</Link>
        <Link to="/mine">我的音乐</Link>
        <Link to="/focus">关注</Link>
        <Link to="/download">下载客户端</Link>
      </div>
      <Suspense fallback="正在加载">{useRoutes(routes)}</Suspense>
      <div className="main"></div>
    </div>
  )
}

export default App

在这里插入图片描述

1.10 redux-reduxtk

cnpm install @reduxjs/toolkit react-redux

  • index.tsx 提供Provide
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from '@/App'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import 'normalize.css'
import '@/assets/css/index.less'
import store from './store'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>
)

  • store/index.ts
import { configureStore } from '@reduxjs/toolkit'
import { useSelector, useDispatch, TypedUseSelectorHook } from 'react-redux'
import counterReducer from './modules/counter'

const store = configureStore({
  reducer: {
    counter: counterReducer
  }
})

// 获取函数的返回类型
type GetStateFnType = typeof store.getState
// 获取函数返回类型的类型
type IRootState = ReturnType<GetStateFnType>
type DispatchType = typeof store.dispatch

export const useAppSelector: TypedUseSelectorHook<IRootState> = useSelector
export const useAppDisPatch: () => DispatchType = useDispatch

export default store


  • store/count.ts
import { createSlice } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    count: 1,
    message: 'hello'
  },
  reducers: {
    changeMessageAction(state, { payload }) {
      state.message = payload
    }
  }
})

export const { changeMessageAction } = counterSlice.actions
export default counterSlice.reducer

  • 使用的页面
import React, { memo, Suspense } from 'react'
import type { FC, ReactNode } from 'react'
import { Outlet, Link } from 'react-router-dom'
import { useAppDisPatch, useAppSelector } from '@/store'
import { shallowEqual } from 'react-redux'
import { changeMessageAction } from '@/store/modules/counter'

interface IProps {
  children?: ReactNode
}

const Discover: FC<IProps> = () => {
  const { count, message } = useAppSelector(
    (state) => ({
      count: state.counter.count,
      message: state.counter.message
    }),
    shallowEqual
  )

  const dispatch = useAppDisPatch()

  const changeMessage = (message: string) => {
    dispatch(changeMessageAction(message))
  }
  return (
    <div>
      <div>
        {count}=={message}
        <button onClick={() => changeMessage('修改message')}>
          修改message
        </button>
        <Link to="/discover/recommend">推荐</Link>
        <Link to="/discover/ranking">排行榜</Link>
        <Link to="/discover/songs">歌单</Link>
        <Link to="/discover/djradio">主播电台</Link>
        <Link to="/discover/artist">歌手</Link>
        <Link to="/discover/album">新碟上架</Link>
      </div>
      {/* 二级路由也可以用suspense */}
      <Suspense fallback="正在加载">
        <Outlet />
      </Suspense>
    </div>
  )
}

export default memo(Discover)

1.10 axios的封装

在这里插入图片描述

  • request/index.ts
import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { HYRequestConfig } from './type'

// 拦截器: 蒙版Loading/token/修改配置

/**
 * 两个难点:
 *  1.拦截器进行精细控制
 *    > 全局拦截器
 *    > 实例拦截器
 *    > 单次请求拦截器
 *
 *  2.响应结果的类型处理(泛型)
 */

class HYRequest {
  instance: AxiosInstance

  // request实例 => axios的实例
  constructor(config: any) {
    this.instance = axios.create(config)

    // 每个instance实例都添加拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // loading/token
        return config
      },
      (err) => {
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        return res.data
      },
      (err) => {
        return err
      }
    )

    // 针对特定的hyRequest实例添加拦截器
    this.instance.interceptors.request.use(
      config.interceptors?.requestSuccessFn,
      config.interceptors?.requestFailureFn
    )
    this.instance.interceptors.response.use(
      config.interceptors?.responseSuccessFn,
      config.interceptors?.responseFailureFn
    )
  }

  // 封装网络请求的方法
  // T => IHomeData
  request<T = any>(config: HYRequestConfig<T>) {
    // 单次请求的成功拦截处理
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(config)
    }

    // 返回Promise
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 单词响应的成功拦截处理
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors.responseSuccessFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  get<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'GET' })
  }
  post<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'POST' })
  }
  delete<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'DELETE' })
  }
  patch<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'PATCH' })
  }
}

export default HYRequest

  • request/type.ts
import type { AxiosRequestConfig, AxiosResponse } from 'axios'

// 针对AxiosRequestConfig配置进行扩展
export interface HYInterceptors<T = AxiosResponse> {
  requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestFailureFn?: (err: any) => any
  responseSuccessFn?: (res: T) => T
  responseFailureFn?: (err: any) => any
}

export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: HYInterceptors<T>
}

  • config/index.ts
import type { AxiosRequestConfig, AxiosResponse } from 'axios'

// 针对AxiosRequestConfig配置进行扩展
export interface HYInterceptors<T = AxiosResponse> {
  requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestFailureFn?: (err: any) => any
  responseSuccessFn?: (res: T) => T
  responseFailureFn?: (err: any) => any
}

export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: HYInterceptors<T>
}

环境变量也可以通过配置文件 但是前面需要加上REACT_APP_…

在这里插入图片描述

  • service/index.ts
import { BASE_URL, TIME_OUT } from './config'
import HYRequest from './request'

const hyRequest = new HYRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  interceptors: {
    requestSuccessFn: (config: any) => {
      return config
    }
  }
})

export default hyRequest

在这里插入图片描述

  • 使用的页面
import React, { memo, useEffect, useState } from 'react'
import type { FC, ReactNode } from 'react'
import hyRequest from '@/service'

interface IProps {
  children?: ReactNode
}

export interface IBannerData {
  imageUrl: string
  targetId: number
  targetType: number
  titleColor: string
  typeTitle: string
  url: string
  exclusive: boolean
  scm: string
  bannerBizType: string
}

const Recommend: FC<IProps> = () => {
  const [banners, setBanners] = useState<IBannerData[]>([])

  // 测试网络请求
  useEffect(() => {
    hyRequest
      .get({
        url: '/banner'
      })
      .then((res) => {
        setBanners(res.banners)
      })
  }, [])

  return (
    <div>
      {banners.map((item, index) => {
        return <div key={index}>{item.imageUrl}</div>
      })}
    </div>
  )
}

export default memo(Recommend)

  • 可以在这个页面自动生成类型定义
    https://transform.tools/json-to-typescript

1.11 类组件和TS的结合

import React, { PureComponent } from 'react'
/**
 * state:
 * props:
 */

interface IProps {
  name: string
  age?: number
}

interface IState {
  message: string
  counter: number
}

class Demo02 extends PureComponent<IProps, IState> {
  name = 'aaaa'
  state = {
    message: 'Hello World',
    counter: 99
  }

  // getSnapshotBeforeUpdate() {
  //   return { address: '庐山' }
  // }

  // componentDidUpdate(
  //   prevProps: Readonly<IProps>,
  //   prevState: Readonly<IState>,
  //   snapshot?: ISnapshot | undefined
  // ): void {}

  // constructor(props: IProps) {
  //   super(props)

  //   // this.state = {
  //   //   message: 'Hello World',
  //   //   counter: 100
  //   // }
  // }

  render(): React.ReactNode {
    return (
      <div>
        name: {this.props.name}
        age: {this.props.age}
        message: {this.state.message}
        counter: {this.state.counter}
      </div>
    )
  }
}

export default Demo02


1.12 redux和ts的结合

import { createSlice, PayloadAction } from '@reduxjs/toolkit'

interface IState {
  count: number
  message: string
  address: string
  height: number
  direction: 'left' | 'right' | 'up' | 'down'
  names: string[]
}

const initialState: IState = {
  count: 100,
  message: 'Hello Redux',
  address: '广州市',
  height: 1.88,
  direction: 'left',
  names: []
}

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    changeMessageAction(state, { payload }: PayloadAction<string>) {
      state.message = payload
    }
  }
})

export const { changeMessageAction } = counterSlice.actions
export default counterSlice.reducer

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

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

相关文章

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月17日,星期六

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月17日 星期六 农历正月初八 1、 中疾控&#xff1a;我国自主研发的猴痘mRNA疫苗即将进入临床试验。 2、 2024年度总票房破100亿元&#xff0c;其中春节档已突破70亿元。 3、 国产大飞机首次国外亮相&#xff0c;C919已抵…

5年前端老司机:浅谈web前端开发技术点

有部分同学和朋友问到过我相关问题。利用周末我就浅浅地谈谈我对web前端开发的理解和体会&#xff0c;仅仅能浅浅谈谈&#xff0c;高手请自己主动跳过本篇文章。 毕竟我如今经验并非非常足&#xff0c;连project师都算不上&#xff0c;更不用说大牛了。今天也不谈技术。技术非…

2.14日学习打卡----初学Zookeeper(一)

2.14日学习打卡 目录: 2.14日学习打卡Zookeeper概念一. 集中式到分布式单机架构集群架构什么是分布式三者区别 二. CAP定理分区容错性一致性可用性一致性和可用性的矛盾一致性和可用性如何选择 三. 什么是Zookeeper分布式架构Zookeeper从何而来Zookeeper介绍 四. 应用场景数据发…

Android 车载应用开发之SystemUI 详解

一、SystemUI SystemUI全称System User Interface,直译过来就是系统级用户交互界面,在 Android 系统中由SystemUI负责统一管理整个系统层的 UI,它是一个系统级应用程序(APK),源码在/frameworks/base/packages/目录下,而不是在/packages/目录下,这也说明了SystemUI这个…

集群聊天项目

不懂的一些东西 (const TcpConnectionPtr&&#xff09;作为形参啥意思&#xff1a;接收一个常量引用&#xff0c;函数内部不允许修改该指针所指向的对象。 优势 1.网络层与业务层分离&#xff1a;通过网络层传来的id&#xff0c;设计一个map存储id以及对印的业务处理器&…

文件上传漏洞--Upload-labs--Pass01--前端绕过

一、前端绕过原理 通俗解释&#xff0c;我们将写有恶意代码的php后缀文件上传到网页&#xff0c;网页中的javascript代码会先对文件的后缀名进行检测&#xff0c;若检测到上传文件的后缀名为非法&#xff0c;则会进行alert警告。若想上传php后缀的文件&#xff0c;就要想办法对…

windows一开机一直循环:No Boot Device Found. Press any key to reboot the machine解决方法

一、长按F12 二、选择Settiings/General/Boot Sequence 三、选择UEFI模式&#xff0c; 四、选择下方APPLY 五、退出&#xff1a;

【Spring面试题】

目录 前言 1.Spring框架中的单例bean是线程安全的吗? 2.什么是AOP? 3.你们项目中有没有使用到AOP&#xff1f; 4.Spring中的事务是如何实现的&#xff1f; 5.Spring中事务失效的场景有哪些&#xff1f; 6.Spring的bean的生命周期。 7.Spring中的循环引用 8.构造方法…

Linux下解压tar.xz文件的命令

tar -c: 建立压缩档案-x&#xff1a;解压-t&#xff1a;查看内容-r&#xff1a;向压缩归档文件末尾追加文件-u&#xff1a;更新原压缩包中的文件 ------------------------------------------ 这五个是独立的命令&#xff0c;压缩解压都要用到其中一个&#xff0c;可以和别的…

机器学习入门--循环神经网络原理与实践

循环神经网络 循环神经网络&#xff08;RNN&#xff09;是一种在序列数据上表现出色的人工神经网络。相比于传统前馈神经网络&#xff0c;RNN更加适合处理时间序列数据&#xff0c;如音频信号、自然语言和股票价格等。本文将介绍RNN的基本数学原理、使用PyTorch和Scikit-Learn…

上位机图像处理和嵌入式模块部署(图像项目处理过程)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于一般的图像项目来说&#xff0c;图像处理只是工作当中的一部分。在整个项目处理的过程中有很多的内容需要处理&#xff0c;比如说了解需求、评…

信息安全技术基础知识

一、考点分布 信息安全基础&#xff08;※※&#xff09;信息加密解密技术&#xff08;※※※&#xff09;密钥管理技术&#xff08;※※&#xff09;访问控制及数字签名技术&#xff08;※※※&#xff09;信息安全的保障体系 二、信息安全基础 信息安全包括5个基本要素&#…

【COMP337 LEC3】

LEC 3 Mathematical Preliminaries Common Discrete Probability Distributions 1. Bernoulli distribution : 伯努利分布 models binary outcomes (coin flip). 模型二进制结果 P ( X head ) p and P ( X tail ) 1 − p 2. Generalised Bernoulli distribution…

牛客网SQL进阶123:高难度试卷的得分的截断平均值

官网链接&#xff1a; SQL类别高难度试卷得分的截断平均值_牛客题霸_牛客网牛客的运营同学想要查看大家在SQL类别中高难度试卷的得分情况。 请你帮她从exam_。题目来自【牛客题霸】https://www.nowcoder.com/practice/a690f76a718242fd80757115d305be45?tpId240&tqId2180…

《PCI Express体系结构导读》随记 —— 第II篇 第13章 PCI总线与虚拟化技术(6)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第13章 PCI总线与虚拟化技术&#xff08;5&#xff09; 13.2 ATS&#xff08;Address Translation Services&#xff09; 单纯使用IOMMU并不能充分发挥处理器系统的效率&#xff0c;从图13-2中可以发现&…

WordPress站点如何实现发布文章即主动推送到百度快速收录和普通收录?

我们在WordPress后台成功发布文章之后&#xff0c;如果靠搜索引擎来抓取的话&#xff0c;可能会比较慢&#xff0c;所以十分有必要将我们成功发布的文章马上提交到百度、必应等搜索引擎中。下面boke112百科就跟大家说一说WordPress站点如何实现发布文章即主动推送到百度快速收录…

基于SpringBoot的教学管理app的开发65449-计算机毕业设计项目选题推荐(附源码)

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对教学管理等问题&#xff0c;对其进行研究分…

Electron实战之进程间通信

进程间通信&#xff08;IPC&#xff09;并非仅限于 Electron&#xff0c;而是源自甚至早于 Unix 诞生的概念。尽管“进程间通信”这个术语的确创造于何时并不清楚&#xff0c;但将数据传递给另一个程序或进程的理念可以追溯至 1964 年&#xff0c;当时 Douglas McIlroy 在 Unix…

centos中docker操作+安装配置django+mysql5.7并使用simpleui美化管理后台

一、安装docker 确保系统是CentOS 7并且内核版本高于3.10,可以通过uname -r命令查看内核版本。 更新系统软件包到最新版本,可以使用命令yum update -y。 安装必要的软件包,包括yum-utils、device-mapper-persistent-data和lvm2。使用命令yum install -y yum-utils devic…

【51单片机】如何【手搓】定时器寄存器配置【低8位TL0(low)】和【高8位TH0(high)】

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 本文是【【51单片机】从零开始手把手带你【查手册】配置定时器&#xff0c;并完成小项目&#xff08;定时器&#xff06;中断的应用&#xff09;】博…