当前位置: 首页 > news >正文

【Vue3源码解析】应用实例创建及页面渲染

下载源码

git clone https://github.com/vuejs/core.git

写该文章时的Vue版本为:

"version": "3.5.13",

这里要注意 pnpm 的版本不能太低,我此时的版本为 9.15.4。更新 pnpm 版本:

npm install -g pnpm

然后安装依赖:

pnpm i 

然后打包开发环境:

pnpm run dev

之后就可以编写自己的测试程序,debugger 调试代码。

Vue3 整体架构

image-20250213104157644

image-20250213104310536

在打包后的文件夹内创建一个自己用来测试的 demo 文件夹,我这里叫做 heo 文件夹

file_1739416744668_221

编写测试代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div id="app"><h1>计数器案例</h1><h2>当前计数: {{counter}}</h2><button @click="increment">+1</button><button @click="decrement">-1</button>
</div>
<script src="../dist/vue.global.js"></script>
<script>const {ref, createApp} = Vue// 根组件const App = {setup() {const counter = ref(0)function increment() {counter.value++}function decrement() {counter.value--}return {counter,increment,decrement}}}// 创建全局 app对象,调用 mount 方法挂载到页面上const app = createApp(App)app.mount('#app')
</script>
</body>
</html>

然后再使用内置插件自带的服务器预览当前页面:

image-20250213111951443

createApp 的创建过程

找到创建 app 实例的 createApp 函数:

image-20250213154607136

从创建 app 对象到创建 渲染器的过程:

image-20250213160930449

/*** 创建一个 Vue 应用实例(入口)。** @param {...any} args - 传递给内部创建应用方法的参数。* @returns {CreateAppFunction<Element>} 返回一个带有自定义 `mount` 方法的应用实例对象 app。*/
export const createApp = ((...args) => {// 调用确保渲染器存在并创建应用实例 app// ensureRenderer() 实例化一个渲染器 渲染器就是把 Vue 代码(组件)渲染到DOM 上// ensureRenderer() 最终的返回值 是一个对象// {//   render, // 核心函数 负责将 VNode 渲染成真实 DOM//   hydrate, // SSR 的函数//   createApp: createAppAPI(render, hydrate),// }const app = ensureRenderer().createApp(...args)// 在开发模式下注入原生标签检查和编译选项检查if (__DEV__) {injectNativeTagCheck(app)injectCompilerOptionsCheck(app)}// 获取原始的 mount 方法const { mount } = app// 自定义(重写) mount 方法,接受DOM或选择器作为参数 当我们调用mount时 本质上在调用重写的 mount 方法// 装饰器模式 不改变原有实现 对 mount 进行增强app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {// 将传入的选择器或元素转换为实际的 DOM 元素 也就是我们传入的要挂载的 DOM// normalizeContainer 转换DOM 比如将 "#app" 转为 querySelector 函数拿到DOMconst container = normalizeContainer(containerOrSelector)if (!container) return // 如果DOM不存在,直接返回const component = app._component // 获取应用的根组件// 如果根组件没有 render 函数或 template 属性,则从容器(#app)内的HTML作为组件的模版if (!isFunction(component) && !component.render && !component.template) {// __UNSAFE__// 原因:潜在的执行在 DOM 内的模板中的 JS 表达式。// 用户必须确保该模板是可信的。如果由服务器渲染,则模板不应包含任何用户数据。component.template = container.innerHTML// 2.x 兼容性检查if (__COMPAT__ && __DEV__ && container.nodeType === 1) {for (let i = 0; i < (container as Element).attributes.length; i++) {const attr = (container as Element).attributes[i]// 检查是否有 v- 或 : 或 @ 开头的属性,提示用户使用新的挂载方式if (attr.name !== 'v-cloak' && /^(v-|:|@)/.test(attr.name)) {compatUtils.warnDeprecation(DeprecationTypes.GLOBAL_MOUNT_CONTAINER,null,)break}}}}// 在挂载前清除容器的内容if (container.nodeType === 1) {container.textContent = ''}// 调用原始的 mount 方法进行挂载,并返回代理实例const proxy = mount(container, false, resolveRootNamespace(container))// 如果容器是一个元素,移除 v-cloak 属性并添加 data-v-app 属性if (container instanceof Element) {container.removeAttribute('v-cloak')container.setAttribute('data-v-app', '')}return proxy}return app
}) as CreateAppFunction<Element>

我们自己开发的时候根组件都是 template 属性,而如果没有template 或者 render ,则从容器(#app)内的HTML作为组件的模版,例如:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--将该 div 作为 作为组件的模版-->
<div id="app"><h1>计数器案例</h1><h2>当前计数: {{counter}}</h2><button @click="increment">+1</button><button @click="decrement">-1</button>
</div>
<script src="../dist/vue.global.js"></script>
<script>const {ref, createApp} = Vue// 根组件const App = {setup() {const counter = ref(0)function increment() {counter.value++}function decrement() {counter.value--}return {counter,increment,decrement}}}// 创建全局 app对象,调用 mount 方法挂载到页面上const app = createApp(App)app.mount('#app')
</script>
</body>
</html>

创建渲染器和 mount 的执行

从创建虚拟节点到渲染页面的过程:

image-20250213160951570

// nodeOps 节点操作(比如insert/remove/createComment创建注释元素 等)和 patchProp 属性操作(比如 class/style/@click 等)
const rendererOptions = /*@__PURE__*/ extend({ patchProp }, nodeOps)// lazy create the renderer - this makes core renderer logic tree-shakable
// in case the user only imports reactivity utilities from Vue.
let renderer: Renderer<Element | ShadowRoot> | HydrationRenderer/*** 确保渲染器已被创建** 此函数用于检查全局变量 `renderer` 是否已存在,如果不存在,则使用给定的 `rendererOptions`* 创建一个新的渲染器并赋值给 `renderer`,以确保渲染器的单例模式* 这种方法保证了在整个应用中只有一个渲染器实例,从而优化性能 如果有多个渲染器实例可能导致状态管理和渲染更新的冲突和重复** rendererOptions - 定制化 针对不同平台(移动端/SSR)的渲染器配置** @returns {Renderer} 已存在的渲染器或新创建的渲染器实例*/
function ensureRenderer() {return (renderer ||(renderer = createRenderer<Node, Element | ShadowRoot>(rendererOptions)))
}
/*** The createRenderer function accepts two generic arguments:* HostNode and HostElement, corresponding to Node and Element types in the* host environment. For example, for runtime-dom, HostNode would be the DOM* `Node` interface and HostElement would be the DOM `Element` interface.** Custom renderers can pass in the platform specific types like this:** ```js* const { render, createApp } = createRenderer<Node, Element>({*   patchProp,*   ...nodeOps* })* ```*/
export function createRenderer<HostNode = RendererNode,HostElement = RendererElement,
>(options: RendererOptions<HostNode, HostElement>): Renderer<HostElement> {return baseCreateRenderer<HostNode, HostElement>(options)
}

因此 createRenderer 才是创建渲染器的代码实现(有2000行代码,这里不再粘代码)。它的返回值很重要是:

{render, // 核心函数 负责将 VNode 渲染成真实 DOMhydrate, // SSR 的函数createApp: createAppAPI(render, hydrate),
}
export function createAppAPI<HostElement>(render: RootRenderFunction<HostElement>,hydrate?: RootHydrateFunction,
): CreateAppFunction<HostElement> {// 返回的函数 也就是我们调用createApp()函数创建的真实app(这里使用函数柯里化传递了render和hydrate)return function createApp(rootComponent, rootProps = null) {// 如果不是函数组件 转化为对象的形式if (!isFunction(rootComponent)) {rootComponent = extend({}, rootComponent)}// rootProps 如果不是对象则警告if (rootProps != null && !isObject(rootProps)) {__DEV__ && warn(`root props passed to app.mount() must be an object.`)rootProps = null}// 创建app上下文实例 存储 app配置信息const context = createAppContext()// 安装 plugins 使用set防止重复安装const installedPlugins = new WeakSet()const pluginCleanupFns: Array<() => any> = []// 目前刚刚创建app实例 没有挂载到dom上let isMounted = false// app 实例对象 函数的最后返回 该app实例对象const app: App = (context.app = {_uid: uid++,_component: rootComponent as ConcreteComponent,_props: rootProps,_container: null,_context: context,_instance: null,version,//...use(plugin: Plugin, ...options: any[]) {if (installedPlugins.has(plugin)) {__DEV__ && warn(`Plugin has already been applied to target app.`)} else if (plugin && isFunction(plugin.install)) {installedPlugins.add(plugin)plugin.install(app, ...options)} else if (isFunction(plugin)) {installedPlugins.add(plugin)plugin(app, ...options)} else if (__DEV__) {warn(`A plugin must either be a function or an object with an "install" ` +`function.`,)}return app},//...mount(rootContainer: HostElement,isHydrate?: boolean,namespace?: boolean | ElementNamespace,): any {if (!isMounted) {// #5571if (__DEV__ && (rootContainer as any).__vue_app__) {warn(`There is already an app instance mounted on the host container.\n` +` If you want to mount another app on the same host container,` +` you need to unmount the previous app by calling \`app.unmount()\` first.`,)}// 根据传入的根组件和属性 创建对应的 VNodeconst vnode = app._ceVNode || createVNode(rootComponent, rootProps)// store app context on the root VNode.// this will be set on the root instance on initial mount.// 在 vnode 存储上下文vnode.appContext = context//...if (isHydrate && hydrate) {hydrate(vnode as VNode<Node, Element>, rootContainer as any)} else {// 非ssr 则将上面的虚拟节点渲染到dom上render(vnode, rootContainer, namespace)}// 设置已经挂载的标记isMounted = trueapp._container = rootContainer// for devtools and telemetry;(rootContainer as any).__vue_app__ = appif (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {app._instance = vnode.componentdevtoolsInitApp(app, version)}return getComponentPublicInstance(vnode.component!)} else if (__DEV__) {warn(`App has already been mounted.\n` +`If you want to remount the same app, move your app creation logic ` +`into a factory function and create fresh app instances for each ` +`mount - e.g. \`const createMyApp = () => createApp(App)\``,)}},//...return app}
}

patch 代码执行过程:

image-20250213161012947

patch 组件的 children 过程:

image-20250213161306436

组件内部 effect 处理过程:

image-20250213161222976

createVNode 的过程(h 函数的本质)

image-20250213161448205

packages/runtime-core/src/h.ts

/*** 创建一个虚拟节点(VNode),基于提供的类型、属性和子节点。* 对外暴露为 h 函数,内部使用 createVNode 函数来创建虚拟节点。** @param type VNode的组件类型,通常是一个表示DOM元素或组件函数的字符串。* @param propsOrChildren VNode的属性或子节点,取决于上下文。* @param children VNode的子节点,可以是单个VNode或VNode数组。* @returns 返回创建的VNode。*/
export function h(type: any, propsOrChildren?: any, children?: any): VNode {// 获取参数的数量,以确定如何处理它们。const l = arguments.length// 如果只提供了两个参数,则进一步根据第二个参数的类型进行区分。if (l === 2) {// 判断第二个参数是否为对象且不是数组,以决定它是属性还是子节点。if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {// 单个VNode且没有属性if (isVNode(propsOrChildren)) {return createVNode(type, null, [propsOrChildren])}// 有属性但没有子节点return createVNode(type, propsOrChildren)} else {// 省略属性return createVNode(type, null, propsOrChildren)}} else {// 处理超过三个参数的情况,将第二个参数之后的所有参数转换为子节点数组。if (l > 3) {children = Array.prototype.slice.call(arguments, 2)} else if (l === 3 && isVNode(children)) {// 如果正好提供了三个参数且第三个参数是单个VNode,则将其封装到数组中。children = [children]}// 最后,使用属性和子节点创建VNode。return createVNode(type, propsOrChildren, children)}
}
(type, propsOrChildren)} else {// 省略属性return createVNode(type, null, propsOrChildren)}} else {// 处理超过三个参数的情况,将第二个参数之后的所有参数转换为子节点数组。if (l > 3) {children = Array.prototype.slice.call(arguments, 2)} else if (l === 3 && isVNode(children)) {// 如果正好提供了三个参数且第三个参数是单个VNode,则将其封装到数组中。children = [children]}// 最后,使用属性和子节点创建VNode。return createVNode(type, propsOrChildren, children)}
}

相关文章:

【Vue3源码解析】应用实例创建及页面渲染

下载源码 git clone https://github.com/vuejs/core.git写该文章时的Vue版本为&#xff1a; "version": "3.5.13",这里要注意 pnpm 的版本不能太低&#xff0c;我此时的版本为 9.15.4。更新 pnpm 版本&#xff1a; npm install -g pnpm然后安装依赖&…...

云原生AI Agent应用安全防护方案最佳实践(上)

当下&#xff0c;AI Agent代理是一种全新的构建动态和复杂业务场景工作流的方式&#xff0c;利用大语言模型&#xff08;LLM&#xff09;作为推理引擎。这些Agent代理应用能够将复杂的自然语言查询任务分解为多个可执行步骤&#xff0c;并结合迭代反馈循环和自省机制&#xff0…...

人工智能 - 主动视觉可能就是你所需要的:在双臂机器人操作中探索主动视觉

AV-ALOHA 系统使用用于 AV 的 VR 耳机实现直观的数据收集&#xff0c;并且 用于作的 VR 控制器或引线臂。这有助于捕捉全身和头部 远程作我们的真实和模拟系统的运动&#xff0c;记录来自 6 个的视频 不同的摄像头&#xff0c;并为我们的 AV 仿制学习策略提供训练数据。 加州大…...

Ubuntu 下 systemd 介绍

系列文章目录 Linux内核学习 Linux 知识&#xff08;1&#xff09; Linux 知识&#xff08;2&#xff09; WSL Ubuntu QEMU 虚拟机 Linux 调试视频 PCIe 与 USB 的补充知识 vscode 使用说明 树莓派 4B 指南 设备驱动畅想 Linux内核子系统 Linux 文件系统挂载 QEMU 通过网络实现…...

两个实用且热门的 Python 爬虫案例,结合动态/静态网页抓取和反爬策略,附带详细代码和实现说明

在这个瞬息万变的世界里&#xff0c;保持一颗探索的心&#xff0c;永远怀揣梦想前行。即使有时会迷失方向&#xff0c;也不要忘记内心深处那盏指引你前进的明灯。它代表着你的希望、你的信念以及对未来的无限憧憬。每一个不曾起舞的日子&#xff0c;都是对生命的辜负&#xff1…...

Softing线上研讨会 | 自研还是购买——用于自动化产品的工业以太网

| 线上研讨会时间&#xff1a;2025年1月27日 16:00~16:30 / 23:00~23:30 基于以太网的通信在工业自动化网络中的重要性日益增加。设备制造商正面临着一大挑战——如何快速、有效且经济地将工业以太网协议集成到其产品中。其中的关键问题包括&#xff1a;是否只需集成单一的工…...

Jetson Agx Orin平台preferred_stride调试记录--1924x720图像异常

1.问题描述 硬件: AGX Orin 在Jetpack 5.0.1和Jetpack 5.0.2上测试验证 图像分辨率在1920x720和1024x1920下图像采集正常 但是当采集图像分辨率为1924x720视频时,图像输出异常 像素格式:yuv_uyvy16 gstreamer命令如下 gst-launch-1.0 v4l2src device=/dev/video0 ! …...

从2025年起:数字化建站PHP 8.1应成为建站开发的基准线

在数字化浪潮席卷全球的今天,PHP语言仍然保持着Web开发领域的核心地位。根据W3Techs最新统计,PHP驱动着全球78.9%的已知服务端网站。当时间指向2025年,这个拥有28年历史的编程语言将迎来新的发展里程碑——PHP 8.1版本应成为网站开发的最低基准要求,这不仅是技术迭代的必然…...

电动汽车电池监测平台系统设计(论文+源码+图纸)

1总体设计 本次基于单片机的电池监测平台系统设计&#xff0c;其整个系统架构如图2.1所示&#xff0c;其采用STC89C52单片机作为控制器&#xff0c;结合ACS712电流传感器、TLC1543模数转换器、LCD液晶、DS18B20温度传感器构成整个系统&#xff0c;在功能上可以实现电压、电流、…...

20240914 天翼物联 笔试

文章目录 1、行测知识1.11.21.31.41.51.61.71.81.91.101.111.121.131.141.152、专业知识2.12.22.32.42.52.62.72.82.92.102.112.122.132.142.153、编程题3.13.2岗位:嵌入式开发工程师(上海) 题型:15 道行测知识,15 道专业知识,2 道编程题 注意:本文章暂无解析,谨慎分…...

前端高级面试题

以下是一些前端高级面试可能涉及到的内容: 一、前端工程化 如何构建一个适合大型团队的前端代码规范和构建流程? 答案: 代码规范方面: 使用ESLint结合Prettier来统一JavaScript和CSS(包括预处理器如Sass或Less)的语法风格。例如,规定变量命名采用驼峰命名法,函数名要有…...

【nvidia】NCCL禁用P2P后果权衡

通信bound还是计算bound&#xff1f; 计算bound场景&#xff1a; 模型参数量较小&#xff08;如参数量未超出单卡显存容量&#xff0c;使用纯数据并行&#xff09;或计算密度极高&#xff08;如大batch size下的矩阵运算&#xff09;时&#xff0c;A100的计算能力&#xff08…...

哈希表(C语言版)

文章目录 哈希表原理实现(无自动扩容功能)代码运行结果 分析应用 哈希表 如何统计一段文本中&#xff0c;小写字母出现的次数? 显然&#xff0c;我们可以用数组 int table[26] 来存储每个小写字母出现的次数&#xff0c;而且这样处理&#xff0c;效率奇高。假如我们想知道字…...

unity学习46:反向动力学IK

目录 1 正向动力学和反向动力学 1.1 正向动力学 1.2 反向动力学 1.3 实现目标 2 实现反向动力 2.1 先定义一个目标 2.2 动画层layer&#xff0c;需要加 IK pass 2.3 增加头部朝向代码 2.3.1 专门的IK方法 OnAnimatorIK(int layerIndex){} 2.3.2 增加朝向代码 2.4 …...

夜莺监控发布 v8.beta5 版本,优化 UI,新增接口认证方式便于鉴权

以防读者不了解夜莺&#xff0c;开头先做个介绍&#xff1a; 夜莺监控&#xff0c;英文名字 Nightingale&#xff0c;是一款侧重告警的监控类开源项目。类似 Grafana 的数据源集成方式&#xff0c;夜莺也是对接多种既有的数据源&#xff0c;不过 Grafana 侧重在可视化&#xff…...

asio的使用

1、下载 性能测试&#xff1a;https://github.com/huyuguang/asio_benchmark 2、基本使用 2.1 TCP 1、客户端&#xff1a; 2、服务端&#xff1a; 2.2 UDP单揪 boost的asio接收单路大数据量udp包的方法 1、发送&#xff1a; 2、接收&#xff1a; #include "Circled…...

PHP语法完全入门指南:从零开始掌握动态网页

本文专为零基础新手设计,通过5000字详细讲解带你系统学习PHP语法。包含环境搭建、基础语法、实战案例,并附20+代码示例。阅读后你将能独立开发简单动态网页! 一、PHP开发环境搭建(新手必看) 1.1 为什么需要搭建环境? PHP是服务器端脚本语言,需要运行在服务器环境中。推…...

WPF快速创建DeepSeek本地自己的客户端-基础思路版本

开发工具&#xff1a;VS 2015 开发环境&#xff1a;.Net 4.0 使用技术&#xff1a;WPF 本篇文章内容&#xff1a; 本地部署DeepSeek以后一般使用网页工具&#xff08;如Chatbox&#xff09;或者DOS窗口与其对话。本篇文章使用WPF创建一个基础版的对话工具。 一、搭建本地DeepS…...

Win7本地化部署deepseek-r1等大模型详解

参考链接 在Windows 7操作系统&#xff0c;基于llama.cpp本地化部署 deepseek-r1模型的方法 2025-02-08 2G内存Windows7运行deepseek-r1:1.5b 这两个链接写的可能不够详细&#xff0c;有同学私信问实现过程&#xff0c;这里进一步解释一下。 一、准备 需要准备的大模型、工具…...

分享一个解梦 Chrome 扩展 —— 周公 AI 解梦

一、插件简介 周公 AI 解梦是一款基于 Chrome 扩展的智能解梦工具&#xff0c;由灵机 AI 提供技术支持。它能运用先进的 AI 技术解析梦境含义&#xff0c;为用户提供便捷、智能的解梦服务。无论你是对梦境充满好奇&#xff0c;还是想从梦境中获取一些启示&#xff0c;这款插件都…...

国产Linux OS:网络性能调优关键内核参数

国产Linux OS&#xff1a;网络性能调优关键内核参数 参数列表 这些参数是Linux系统中用于网络性能调优的关键内核参数&#xff0c;它们控制了网络接口和TCP协议栈的行为。合理调整这些参数可以根据具体的应用场景和网络条件优化系统的网络性能。 sysctl net.core.rmem_max sy…...

DeepSeek接口联调(postman版)

第一步&#xff1a;获取API key 获取APIkeys链接https://platform.deepseek.com/api_keys 点击创建 API key 即可免费生成一个key值&#xff0c;别忘记保存。 第二步&#xff1a;找到deepseek官方接口文档 文档地址&#xff1a;https://api-docs.deepseek.com/zh-cn/ 第三步…...

算法19(力扣244)反转字符串

1、问题 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 2、示例 &#xff08;1&#xff09; 示例 1&a…...

Svelte 最新中文文档翻译(10)—— use: 与 Actions

前言 Svelte&#xff0c;一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初&#xff0c;就备受开发者的喜爱&#xff0c;根据统计&#xff0c;从 2019 年到 2024 年&#xff0c;连续 6 年一直是开发者最感兴趣的前端框架 No.1&#xff1a; Svelte 以其独特的编…...

iptables网络安全服务详细使用

iptables防火墙概念说明 开源的基于数据包过滤的网络安全策略控制工具。 centos6.9 --- 默认防火墙工具软件iptables centos7 --- 默认防火墙工具软件firewalld&#xff08;zone&#xff09; iptables主要工作在OSI七层的二、三、四层&#xff0c;如果重新编译内核&…...

node.js + html调用ChatGPTApi实现Ai网站demo(带源码)

文章目录 前言一、demo演示二、node.js 使用步骤1.引入库2.引入包 前端HTML调用接口和UI所有文件总结 前言 关注博主&#xff0c;学习每天一个小demo 今天是Ai对话网站 又到了每天一个小demo的时候咯&#xff0c;前面我写了多人实时对话demo、和视频转换demo&#xff0c;今天…...

Vue 3最新组件解析与实践指南:提升开发效率的利器

目录 引言 一、Vue 3核心组件特性解析 1. Composition API与组件逻辑复用 2. 内置组件与生命周期优化 3. 新一代UI组件库推荐 二、高级组件开发技巧 1. 插件化架构设计 2. 跨层级组件通信 三、性能优化实战 1. 惰性计算与缓存策略 2. 虚拟滚动与列表优化 3. Tree S…...

DeepSeek 助力 Vue 开发:打造丝滑的日期选择器(Date Picker),未使用第三方插件

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

kubernetes源码分析 kubelet

简介 从官方的架构图中很容易就能找到 kubelet 执行 kubelet -h 看到 kubelet 的功能介绍&#xff1a; kubelet 是每个 Node 节点上都运行的主要“节点代理”。使用如下的一个向 apiserver 注册 Node 节点&#xff1a;主机的 hostname&#xff1b;覆盖 host 的参数&#xff1…...

PostgreSQL的学习心得和知识总结(一百六十八)|深入理解PostgreSQL数据库之PostgreSQL 规划器开发与调试(翻译)

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…...

React创建项目实用教程

✍请将整篇文章阅读完再开始使用create-react-app react-project创建项目 检查node版本 node -v // node版本&#xff1a;v22.10.0使用nvm降版本修改到了node V20.11.1之后再进行一系列操作的 react脚手架安装&#xff1a; npm install -g create-react-app// node版本&…...

STM32 外部中断和NVIC嵌套中断向量控制器

目录 背景 外部中断/事件控制器(EXTI) 主要特性 功能说明 外部中断线 嵌套向量中断控制器 特性 ‌中断线&#xff08;Interrupt Line&#xff09; 中断线的定义和作用 STM32中断线的分类和数量 优先级分组 抢占优先级&#xff08;Preemption Priority&#xff09; …...

讯飞唤醒+VOSK语音识别+DEEPSEEK大模型+讯飞离线合成实现纯离线大模型智能语音问答。

在信息爆炸的时代&#xff0c;智能语音问答系统正以前所未有的速度融入我们的日常生活。然而&#xff0c;随着数据泄露事件的频发&#xff0c;用户对于隐私保护的需求日益增强。想象一下&#xff0c;一个无需联网、即可响应你所有问题的智能助手——这就是纯离线大模型智能语音…...

【MediaTek】 T750 openwrt-23.05编 cannot find dependency libexpat for libmesode

MediaTek T750 T750 采用先进的 7nm 制程,高度集成 5G 调制解调器和四核 Arm CPU,提供较强的功能和配置,设备制造商得以打造精巧的高性能 CPE 产品,如固定无线接入(FWA)路由器和移动热点。 MediaTek T750 平台是一款综合的芯片组,集成了 5G SoC MT6890、12nm 制程…...

如何通过 prometheus-operator 实现服务发现

在之前的章节中,我们讲解了如何编写一个自定义的 Exporter,以便将指标暴露给 Prometheus 进行抓取。现在,我们将进一步扩展这个内容,介绍如何使用 prometheus-operator 在 Kubernetes 集群中自动发现并监控这些暴露的指标。 部署应用 在 Kubernetes 集群中部署我们的自定…...

VBA学习:将文本中的\n替换为换行符

目录 一、问题描述 二、解决方法 三、代码 四、注意事项 五、总结 一、问题描述 一个字符串&#xff0c;包含多个\n&#xff0c;现在利用VBA写一段程序&#xff0c;把\n替换为换行符。 二、解决方法 1、Replace函数&#xff1a;直接替换换行符 在Word 中 使用vbCrLf或者…...

(8/100)每日小游戏平台系列

项目地址位于&#xff1a;小游戏导航 新增一个打地鼠游戏&#xff01; 打地鼠&#xff08;Whack-a-Mole&#xff09;是一款经典的休闲游戏&#xff0c;玩家需要点击随机出现的地鼠&#xff0c;以获取分数。游戏时间有限&#xff0c;玩家需要在规定时间内尽可能多地击中地鼠&am…...

【设计模式】 建造者模式和原型模式

建造者模式&#xff08;Builder Pattern&#xff09; 概述 建造者模式是一种创建型设计模式&#xff0c;它允许逐步构建复杂对象。通过将构造过程与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。这种模式非常适合用于创建那些具有很多属性的对象&#xff0c;尤…...

【Python 学习 / 4】基本数据结构之 字符串 与 集合

文章目录 1. 字符串概念1.1 字符串的创建1.2 字符串的访问和操作1.2.1 下标访问1.2.2 切片操作1.2.3 字符串的拼接和重复1.2.4 字符串的长度 1.3 字符串的方法1.4 字符串的查找和替换1.5 字符串格式化1.5.1 使用 % 运算符1.5.2 使用 str.format()1.5.3 使用 f-string&#xff0…...

Spring框架中都用到了哪些设计模式?

大家好&#xff0c;我是锋哥。今天分享关于【Spring框架中都用到了哪些设计模式&#xff1f;】面试题。希望对大家有帮助&#xff1b; Spring框架中都用到了哪些设计模式&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring框架中使用了大量的设计模…...

HBuilderX中uni-app打开页面时,如何用URL传递参数,Query参数传递

HBuilderX中uni-app打开页面时&#xff0c;如何用URL传递参数,Query参数传递&#xff1f; URL是一种描述文件在计算机网络中位置的方式。在web开发中&#xff0c;可以通过query string来传递参数。使用uniapp进行开发&#xff0c;打开不同的页面时&#xff0c;本文介绍给所要打…...

【开源向量数据库】Milvus简介

Milvus 是一个开源、高性能、可扩展的向量数据库&#xff0c;专门用于存储和检索高维向量数据。它支持近似最近邻搜索&#xff08;ANN&#xff09;&#xff0c;适用于图像检索、自然语言处理&#xff08;NLP&#xff09;、推荐系统、异常检测等 AI 应用场景。 官网&#xff1a…...

c/c++蓝桥杯经典编程题100道(19)汉诺塔问题

汉诺塔问题 ->返回c/c蓝桥杯经典编程题100道-目录 目录 汉诺塔问题 一、题型解释 二、例题问题描述 三、C语言实现 解法1&#xff1a;递归法&#xff08;难度★&#xff09; 解法2&#xff1a;迭代法&#xff08;难度★★★&#xff09; 四、C实现 解法1&#xff1…...

CSS盒模

CSS盒模型就像一个快递包裹&#xff0c;网页上的每个元素都可以看成是这样一个包裹&#xff0c;它主要由以下几个部分组成&#xff1a; 内容&#xff08;content&#xff09;&#xff1a;就像包裹里真正装的东西&#xff0c;比如文字、图片等。在CSS里&#xff0c;可用width&a…...

【go语言规范】关于接口设计

抽象应该被发现&#xff0c;而不是被创造。为了避免不必要的复杂性&#xff0c;需要时才创建接口&#xff0c;而不是预见到需要它&#xff0c;或者至少可以证明这种抽象是有价值的。 “The bigger the interface, the weaker the abstraction. 不要用接口进行设计&#xff0c;要…...

计算机视觉+Numpy和OpenCV入门

Day 1&#xff1a;Python基础Numpy和OpenCV入门 Python基础 变量与数据类型、函数与类的定义、列表与字典操作文件读写操作&#xff08;读写图像和数据文件&#xff09; 练习任务&#xff1a;写一个Python脚本&#xff0c;读取一个图像并保存灰度图像。 import cv2 img cv2.im…...

计算机网络之网络层(网络层的功能,异构网络互联,路由与转发,SDN基本概念,拥塞控制)

计算机网络之网络层 网络层&#xff08;Network Layer&#xff09;是计算机网络体系结构中至关重要的一层&#xff0c;它位于数据链路层&#xff08;Data Link Layer&#xff09;和传输层&#xff08;Transport Layer&#xff09;之间&#xff0c;主要负责数据包从源主机到目的…...

利用雪花算法+Redis 自增 ID,生成订单号

在我们的项目中&#xff0c;我们需要定义一些全局唯一的 ID&#xff0c;比如订单号&#xff0c;支付单号等等。 这些ID有以下几个基本要求&#xff1a; 1、不能重复 2、不可被预测 3、能适应分库分表 为了生成一个这样一个全局的订单号&#xff0c;自定义了一个分布式 ID …...

第35次CCF计算机软件能力认证 python 参考代码

题目列表1. 密码2. 字符串变换3. 补丁应用4. 通讯延迟5. 木板切割题目列表 第35次CCF计算机软件能力认证 1. 密码 n = int(input()) for _ in range(n):s =...

【探商宝】:大数据与AI赋能,助力中小企业精准拓客引

引言&#xff1a;在数据洪流中&#xff0c;如何精准锁定商机&#xff1f; 在竞争激烈的商业环境中&#xff0c;中小企业如何从海量信息中快速筛选出高价值客户&#xff1f;如何避免无效沟通&#xff0c;精准触达目标企业&#xff1f; 探商宝——一款基于大数据与AI技术的企业信…...