深入解析 Vue3 响应式系统:原理、性能优化与应用场景
文章目录
- 1. Vue3 响应式系统的基本原理:Proxy 与 Reflect
- 1.1 Proxy 和 Reflect 概述
- 1.1.1 Proxy
- 1.1.2 Reflect
- 1.1.3 Proxy 和 Reflect 的协作
- 1.2 Vue3 响应式系统:如何通过 Proxy 实现数据代理
- 1.3 Vue3 中 Proxy 的核心概念:响应式数据的创建与依赖收集
- 1.4 依赖收集:如何理解 Vue3 的懒代理机制
- 2. Vue2 到 Vue3 的响应式迁移:从 Object.defineProperty 到 Proxy
- 2.1 Vue2 的响应式系统:Object.defineProperty 的局限性
- 2.2 Vue3 的响应式系统:从 `Object.defineProperty` 到`Proxy`
- 3. 如何理解 Vue3 的依赖收集和懒代理机制
- 3.1 依赖收集:什么是依赖收集?
- 3.2 懒代理机制:懒代理如何工作?
- 3.3 Vue3 响应式的依赖收集与更新流程
- 3.4 依赖收集与懒代理的代码实现示例
- 4. 响应式性能瓶颈:如何避免大量的计算和过多的 reactivity
- 4.1 性能瓶颈:过多的计算和不必要的 reactivity
- 4.2 避免不必要的计算:使用 computed 和 watch
- 4.3 使用`shallowReactive` 来减少响应式数据的深度
- 5. 使用 Vue3 响应式系统进行状态管理的最佳实践
- 5.1 为什么使用 Pinia 进行状态管理?
- 5.2 Pinia 状态管理实例
- 6. 性能优化:如何在大型项目中优化 Vue3 响应式的内存和计算开销
- 6.1 使用 `watchEffect` 和 `computed `优化性能
- 6.2 使用 `toRefs` 处理嵌套数据
- 6.3 动态组件的懒加载
- 6.4 使用 v-memo 指令优化模板渲染
- 6.5 使用 Vue3 的 Suspense 和异步组件
- 7. 实际应用:如何在 Vue3 项目中应用响应式技术优化页面性能和体验
- 7.1 使用响应式数据优化数据展示
- 7.2 管理大型项目中的复杂状态
- 7.3 结合懒加载和异步组件提升用户体验
- 总结
1. Vue3 响应式系统的基本原理:Proxy 与 Reflect
1.1 Proxy 和 Reflect 概述
Vue3 中的响应式系统是基于现代 JavaScript 的 Proxy 和 Reflect 实现的。为了理解 Vue3 响应式系统的工作原理,我们需要先了解这两个对象。
1.1.1 Proxy
Proxy是JavaScript ES6中引入的一个新特性,它允许你定义基本操作的自定义行为,比如属性的访问、赋值、枚举和函数调用等。Proxy提供了一个handle对象,其中包含可以拦截和自定义的操作方法(如get、set、deleteProperty等)。在Vue3中,Proxy被用来拦截对象属性的访问,以便自动追踪依赖关系。
1.1.2 Reflect
Reflect是JavaScript另一个ES6引入的内建对象,提供了操作对象的默认方法,例如:Reflect.get()和Reflect.set()。在Vue3中,Reflect被用来作为Proxy的默认行为执行,从而确保能够直接执行底层的默认操作(如获取属性,设置属性等)。
1.1.3 Proxy 和 Reflect 的协作
在Vue3中,Proxy用于拦截对象的访问和修改,而Reflect则提供了这些操作的默认实现。通过将这两个特性结合,Vue3可以更加高效地管理对象的依赖和状态的变化。
1.2 Vue3 响应式系统:如何通过 Proxy 实现数据代理
在Vue3中,响应式数据的代理通过Proxy实现。我们可以使用new Proxy()来创建一个新的对象,这个对象会代理原始对象,拦截对该对象的操作。
下面是一个简单的例子,演示了如何使用 Proxy 来创建一个响应式对象:
const handle = {get(target: any, prop: any) {console.log(`Getting ${prop}`);return prop in target ? target[prop] : undefined;},set(target: any, prop: any, value: any) {console.log(`Setting ${prop} to ${value}`);target[prop] = value;return true;}
}const obj = new Proxy({}, handle); // 创建一个空对象,并使用handle作为代理obj.name = "Vue3"; // Setting name to Vue3
console.log(obj.name); // Getting name
// Vue3
在这个例子中,Proxy 拦截了对对象的 get 和 set 操作。当访问 obj.name 时,get 捕获了该操作并输出相应的信息。同样,修改 obj.name 时,set 捕获了修改并进行了输出。
1.3 Vue3 中 Proxy 的核心概念:响应式数据的创建与依赖收集
在 Vue3 中,响应式数据的创建基于 Proxy的拦截功能。通过reactive()方法,Vue3 会将普通对象转化为响应式对象。每当访问对象的某个属性时,Vue3 会自动追踪该属性的依赖,并在该属性变化时触发视图更新。
以下是如何使用 Proxy 来创建响应式对象的示例:
import { reactive } from 'vue';const state = reactive({count: 0
});state.count++; // 访问 count 时,Vue 会自动依赖追踪
在这个示例中,reactive() 方法将一个普通的对象 { count: 0 } 转换成了响应式对象。每当 count 被访问或修改时,Vue3 会自动追踪对count的依赖。
1.4 依赖收集:如何理解 Vue3 的懒代理机制
Vue3 响应式系统采用了懒代理机制,意味着只有当你实际访问某个属性时,Vue3 才会对该属性进行代理并收集其依赖。这个过程由 Vue3 的 依赖收集(Dependency Collection)机制完成。
懒代理的优势在于,它通过按需代理来减少开销。Vue3 不会在对象创建时立即代理所有的属性,而是等待属性首次访问时才进行代理。
依赖收集与视图更新
Vue3 的响应式系统通过get操作拦截属性访问,并将相关的组件或函数作为依赖进行收集。当属性值发生变化时,所有依赖该属性的组件会被通知并重新渲染。
代码示例:创建响应式对象并追踪依赖
import { reactive, effect } from 'vue';const state = reactive({count: 0
});// 创建副作用函数,自动追踪依赖
effect(() => {console.log(`Count value is: ${state.count}`);
});state.count++; // 修改 count 时,副作用函数将会自动执行
在这个示例中,effect 函数用于创建副作用,它会自动追踪对 state.count 的依赖。当 state.count 改变时,副作用函数会重新执行,并输出新的 count 值。
2. Vue2 到 Vue3 的响应式迁移:从 Object.defineProperty 到 Proxy
2.1 Vue2 的响应式系统:Object.defineProperty 的局限性
在 Vue2 中,响应式系统是基于Object.defineProperty()实现的。每次访问对象的属性时,Vue 会通过 getter和setter来拦截对属性的读取和修改。虽然这种方法能够有效实现响应式,但也有一些限制:
- 性能问题:每次访问都需要执行 getter 和 setter,性能较差。
- 无法监听新增或删除的属性:
Object.defineProperty()只能处理已存在的属性,无法直接响应新增的属性。
2.2 Vue3 的响应式系统:从 Object.defineProperty 到Proxy
在 Vue3 中,Proxy 完全替代了Object.defineProperty(),通过代理整个对象来监听属性的变化。与 Vue2 相比,Vue3 的响应式系统更为高效,能够监听对象的所有操作,包括新增、删除属性等。
通过 Proxy,Vue3 能够提供更细粒度的控制,提升性能,并能更好地支持动态的对象操作。
3. 如何理解 Vue3 的依赖收集和懒代理机制
3.1 依赖收集:什么是依赖收集?
依赖收集(Dependency Collection)是 Vue3 响应式系统的核心功能之一。在响应式系统中,当我们访问某个响应式对象的属性时,Vue3 会 自动追踪 该属性依赖的函数或组件。这些被追踪的函数或组件会在数据发生变化时重新执行。
这种机制保证了只有在数据发生变化时,相关组件才会重新渲染,从而避免了不必要的性能消耗。
Vue3 中的依赖收集和更新机制是基于 Proxy的 get操作进行的。当我们访问一个属性时,Vue3 会触发 get 操作并将当前的函数(如组件渲染函数)添加到该属性的依赖中。这个过程是通过reactive API 和 effect 函数实现的。
3.2 懒代理机制:懒代理如何工作?
在 Vue2 中,响应式属性的访问是即时的,即对象在创建时所有属性都会立刻变为响应式。这样做虽然有效,但当对象的属性很多时,会导致性能问题。Vue3 采用了 懒代理(Lazy Proxy)机制,只有当属性首次被访问时,Vue3 才会为该属性创建代理。
这种方式大大减少了性能开销,避免了对所有属性的无意义代理。在大数据量或复杂数据结构的应用中,懒代理机制能显著提高性能。
3.3 Vue3 响应式的依赖收集与更新流程
Vue3 的依赖收集和更新机制大致分为以下几个步骤:
- 创建响应式对象:
- 使用
reactive()或ref()方法将一个普通对象转化为响应式对象。Vue3 会使用Proxy拦截对对象属性的访问。
- 使用
- 属性访问与依赖收集:
- 当访问一个响应式对象的属性时,
Proxy的get方法会被触发。 - 在
get方法中,Vue3 会记录当前访问该属性的上下文(例如,当前执行的组件或计算属性),并将其加入到该属性的依赖队列中。
- 当访问一个响应式对象的属性时,
- 属性更新与视图更新:
- 当响应式对象的属性值发生变化时,
Proxy的set方法会被触发,Vue3 会检查是否有依赖该属性的组件或函数。 - 如果有依赖,Vue3 会触发这些依赖的重新执行(例如,重新渲染组件)。
- 当响应式对象的属性值发生变化时,
- 懒代理:
- 只有在属性首次被访问时,Vue3 才会为该属性创建代理,而不是在对象创建时就全部代理。这确保了更高的性能。
3.4 依赖收集与懒代理的代码实现示例
下面我们通过代码示例来演示 Vue3 响应式系统的依赖收集与懒代理机制:
import { reactive, effect } from 'vue';// 创建一个响应式对象
const state = reactive({count: 0,name: 'Vue3'
});// 创建副作用函数,自动追踪依赖
effect(() => {console.log(`Count value is: ${state.count}`);
});// 修改 count 值时,副作用函数会重新执行
state.count++; // 输出:Count value is: 1
state.count++; // 输出:Count value is: 2
在这个示例中,effect() 函数会自动追踪对 state.count 的依赖。当 count 值发生变化时,effect() 函数会自动重新执行。
4. 响应式性能瓶颈:如何避免大量的计算和过多的 reactivity
4.1 性能瓶颈:过多的计算和不必要的 reactivity
尽管 Vue3 的响应式系统已经非常高效,但在处理复杂的应用时,仍然可能出现性能瓶颈。例如:
- 过多的计算:在某些情况下,组件可能会依赖多个属性,而每个属性的变化都会导致该组件重新渲染,导致计算过程变得冗长。
- 过多的响应式数据:如果你将大量的数据都变为响应式,可能会导致内存消耗增加,并且每次数据发生变化时都会触发视图更新,造成性能损失。
为了避免这些瓶颈,我们可以采用以下优化策略。
4.2 避免不必要的计算:使用 computed 和 watch
Vue3 提供了 computed 和 watch 来处理计算属性和副作用。计算属性只会在其依赖的响应式数据发生变化时重新计算,而不会在每次访问时都执行。
import { reactive, computed } from 'vue';// 创建响应式数据
const state = reactive({firstName: 'John',lastName: 'Doe'
});// 使用 computed 创建一个计算属性
const fullName = computed(() => {console.log('Computing full name...');return `${state.firstName} ${state.lastName}`;
});// 计算属性只有在依赖的值变化时才会重新计算
console.log(fullName.value); // 计算全名,并打印:Computing full name... John Doe
state.firstName = 'Jane';
console.log(fullName.value); // 再次计算:Computing full name... Jane Doe
在这个示例中,fullName 是一个计算属性,它只会在 state.firstName 或 state.lastName 发生变化时重新计算,避免了不必要的重新计算。
4.3 使用shallowReactive 来减少响应式数据的深度
如果你只需要对对象的第一层属性进行响应式处理,可以使用shallowReactive来避免将整个对象都变为响应式。
import { shallowReactive } from 'vue';// 创建一个浅响应式对象
const state = shallowReactive({user: { name: 'John', age: 30 },active: true
});// 只有第一层属性是响应式的
state.user.name = 'Jane'; // 这会触发视图更新
state.active = false; // 这会触发视图更新
state.user.age = 31; // 不会触发视图更新,因为 `age` 是嵌套在 `user` 中
通过 shallowReactive,我们只对对象的第一层属性进行响应式处理,避免了深层嵌套对象的性能开销。
5. 使用 Vue3 响应式系统进行状态管理的最佳实践
5.1 为什么使用 Pinia 进行状态管理?
Vue3 引入了 Pinia 作为官方推荐的状态管理库,取代了 Vue2 中的 Vuex。Pinia 与 Vue3 的响应式系统紧密集成,支持更加轻量级和模块化的状态管理。
- 模块化管理:Pinia 提供了更加简洁的 API,支持按需加载和模块化管理。
- Composition API 支持:
Pinia与 Vue3 的Composition API完美集成,支持使用reactive()和ref()来管理状态。 - 类型安全:Pinia 提供良好的 TypeScript 支持,确保状态管理更具类型安全性。
5.2 Pinia 状态管理实例
import { defineStore } from 'pinia';// 创建一个 Pinia store
export const useStore = defineStore('main', {state: () => ({counter: 0}),actions: {increment() {this.counter++;}}
});
在这个例子中,我们创建了一个 Pinia store,管理 counter 状态并提供 increment 方法。当我们需要访问或更新 counter 状态时,可以直接使用 Pinia 提供的 API。
6. 性能优化:如何在大型项目中优化 Vue3 响应式的内存和计算开销
6.1 使用 watchEffect 和 computed 优化性能
为了减少不必要的计算和重新渲染,Vue3 提供了 watchEffect 和 computed,这两个 API 可以帮助我们优化性能,确保只有依赖发生变化时,才会触发计算和视图更新。
6.2 使用 toRefs 处理嵌套数据
如果你需要在嵌套对象中使用响应式数据,可以使用 toRefs 将对象转换为单独的响应式引用,以便更加精细地控制数据的更新。
import { reactive, toRefs } from 'vue';const state = reactive({user: {name: 'John',age: 30}
});// 使用 toRefs 将 user 对象的属性单独转换为响应式引用
const { name, age } = toRefs(state.user);console.log(name.value); // 获取 name 属性的值
这样,我们就能避免对整个 user对象进行深层代理,而是直接操作其各个属性的响应式引用。
6.3 动态组件的懒加载
在大型应用中,动态加载组件是提升性能的一个有效手段。Vue3 提供了 异步组件 和 Suspense 组件来实现懒加载,只有在用户需要时才加载相关组件。
优化策略:
- 使用 Vue3 的
异步组件和Suspense来延迟组件的加载,减少首屏加载时间。
// 异步组件懒加载
const LazyComponent = defineAsyncComponent(() => import('./LazyComponent.vue'));// 使用 Suspense 组件包裹异步组件
<Suspense><LazyComponent />
</Suspense>
在这个例子中,LazyComponent 只有在需要时才会加载,这样就可以减少页面的初始加载时间,提高性能。
6.4 使用 v-memo 指令优化模板渲染
Vue3 提供了v-memo指令,允许开发者手动缓存组件的渲染结果,以便在组件依赖的数据没有变化时,不进行重新渲染。使用 v-memo 可以显著减少不必要的渲染。
优化策略:
- 使用
v-memo指令缓存渲染结果,避免不必要的视图更新。
<template><div v-memo="[state.count]"><!-- 只有当 state.count 发生变化时才会重新渲染这个部分 -->Count: {{ state.count }}</div>
</template>
在这个例子中,只有当 state.count 发生变化时,<div> 部分的内容才会重新渲染,这样就避免了不必要的渲染。
6.5 使用 Vue3 的 Suspense 和异步组件
Suspense 和异步组件结合使用是 Vue3 中的一个非常强大的性能优化特性。通过将某些组件延迟加载,Vue 可以先渲染页面的其他部分,直到异步组件加载完成,提升了首屏加载速度。
优化策略:
- 使用 Vue3 的
Suspense组件配合异步组件来延迟加载不必要的组件,提升性能。
<template><Suspense><template #default><LazyComponent /></template><template #fallback><div>Loading...</div></template></Suspense>
</template><script setup>
import { defineAsyncComponent } from 'vue';const LazyComponent = defineAsyncComponent(() => import('./LazyComponent.vue'));
</script>
Suspense 会显示 Loading...,直到 LazyComponent 加载完成再渲染,从而避免页面的卡顿。
7. 实际应用:如何在 Vue3 项目中应用响应式技术优化页面性能和体验
7.1 使用响应式数据优化数据展示
在一个电商网站中,数据展示往往涉及大量的实时数据更新。通过使用 Vue3 响应式系统,可以确保每次数据变化时,页面都能及时更新,并避免不必要的视图渲染。
通过合理使用 computed 和 watch,我们可以确保只在数据变化时才重新渲染界面,避免不必要的性能开销。
7.2 管理大型项目中的复杂状态
在大型项目中,状态管理是一个重要的性能优化点。Vue3 推荐使用 Pinia 来进行状态管理,而不是传统的 Vuex。Pinia 提供了更高效的性能,并与 Vue3 的响应式系统更好地结合,支持按需加载和模块化管理。
import { defineStore } from 'pinia';export const useStore = defineStore('main', {state: () => ({counter: 0}),actions: {increment() {this.counter++;}}
});
通过 Pinia,我们可以更加灵活地管理应用状态,确保只在需要时才触发重新渲染。
7.3 结合懒加载和异步组件提升用户体验
在大型电商平台中,首页通常包含多个模块和广告位。通过懒加载和异步组件,我们可以确保只在用户需要时才加载相应的内容,从而提升页面的首屏加载速度。
const ProductList = defineAsyncComponent(() => import('./ProductList.vue'));
这种方式可以大大减少用户首次访问时的加载时间,提升用户体验。
总结
在本文中,我们详细探讨了如何在 Vue3 中优化响应式系统的性能,特别是在大型项目中的应用。通过合理使用 Proxy、懒代理、computed、watch、Pinia 等技术,我们可以有效减少不必要的计算、优化内存使用,并提升页面的渲染性能。结合 异步组件 和 Suspense 的使用,我们可以显著优化页面的加载速度,从而提供更加流畅的用户体验。
希望本文对你在实际项目中优化 Vue3 响应式系统有所帮助。如果你有其他问题,欢迎在评论区随时提问!
相关文章:
深入解析 Vue3 响应式系统:原理、性能优化与应用场景
文章目录 1. Vue3 响应式系统的基本原理:Proxy 与 Reflect1.1 Proxy 和 Reflect 概述1.1.1 Proxy1.1.2 Reflect1.1.3 Proxy 和 Reflect 的协作 1.2 Vue3 响应式系统:如何通过 Proxy 实现数据代理1.3 Vue3 中 Proxy 的核心概念:响应式数据的创…...
C++11QT复习(二)
文章目录 Day4-4 New 与 delete 表达式(2025.03.20)1. new 表达式的三个步骤2. delete 表达式的两个步骤3. new[] 与 delete[] Day5 类的定义和关键字再探(2025.03.24)1. C 关键字 const、static、extern2. 类的定义:C…...
【数据挖掘】数据预处理——以鸢尾花数据集为例
数据预处理——以鸢尾花数据集为例 一、实验手册(一)实验目的(二)实验原理(三)实验环境(四)实验步骤(五)实验报告要求 二、案例代码(以鸢尾花数据…...
【算法笔记】图论基础(二):最短路、判环、二分图
目录 最短路松弛操作Dijkstra朴素Dijkstra时间复杂度算法过程例题 堆优化Dijkstra时间按复杂度算法过程例题 bellman-ford时间复杂度为什么dijkstra不能处理负权边?dijkstra的三个步骤:反例失效的原因 算法过程例题 spfa时间复杂度算法过程例题spfa求最短…...
HTTP/HTTPS 中 GET 请求和 POST 请求的区别与联系
一、基础概念 HTTP (HyperText Transfer Protocol, 超文本传输协议) 是一种用于浏览器与服务器之间进行数据交互的协议。HTTPS (加密的 HTTP) 则通过 SSL/TLS 协议实现通信加密与数据安全性。 二、GET 和 POST 概述 GET 请求: 用于从服务器获取资源。 POST 请求: 用于将数据…...
Spring、Spring Boot与Spring Cloud深度解析:核心关系与实战应用指南
1. 技术定位 Spring Framework:企业级Java开发的基础框架Spring Boot:快速构建独立运行的Spring应用Spring Cloud:分布式系统开发的微服务全家桶 二、Spring Framework核心解析 1. 关键特性 // 典型Spring MVC控制器示例 Controller Reque…...
EMS小车技术特点与优势:高效灵活的自动化输送解决方案
北成新控伺服技术丨EMS小车调试视频 EMS小车是一种基于单轨运行的电动输送系统,通过电力驱动实现物料的高效搬运和输送,具有高效灵活、节能环保、多功能集成、行业适配性强等特性,广泛应用于汽车制造、工程机械、家电生产、仓储物流等行业自动…...
uniapp运行到支付宝开发者工具
使用uniapp编写专有钉钉和浙政钉出现的样式问题 在支付宝开发者工具中启用2.0构建的时候,在开发工具中页面样式正常 但是在真机调试和线上的时候不正常 页面没问题,所有组件样式丢失 解决 在manifest.json mp-alipay中加入 "styleIsolation&qu…...
C++ 性能优化隐藏陷阱:从系统调用到并发开销的深度反思
作为一名C++技术专家,我深知性能优化不仅是代码层面的艺术,更是理解硬件与语言交互的科学。在现代计算中,C++的抽象为开发者提供了便利,却也隐藏了硬件的复杂性。如何揭开这些“谎言”,让代码与硬件协同工作?本文将以小案例为载体,通过优化前后的对比,深入剖析每个章节…...
Unity 使用 Protobuf(Pb2)二进制数据全流程工具详解
前言 在Unity游戏开发中,高效、快速、安全地读取配置数据是一项重要需求。本文介绍一种完整的解决方案——使用Protobuf二进制格式(Pb2)存储和读取游戏数据,并详细分享实现全流程的Unity工具。 一、技术流程概览 实现Unity读取…...
基于QT(C++)实现绘图程序
绘图程序 1 核心算法 1.1 图元生成 1.1.1 直线 画直线的算法采用了课上讲到的 Bresenhan 算法,采用整数增量运算,精确而有效的光栅设备生成算法。 基本思想是:当直线斜率的绝对值小于 1 时,从左端点开始作为起点&#…...
深入剖析ReLU激活函数:特性、优势与梯度消失问题的解决之道,以及Leaky ReLU 和 Parametric ReLU
深入剖析ReLU激活函数:特性、优势与梯度消失问题的解决之道 在深度学习领域,激活函数的选择直接影响神经网络的训练效果和性能。整流线性单元(Rectified Linear Unit,简称ReLU)因其简单性、高效性以及对梯度消失问题的…...
vscode设置console.log的快捷输出方式
vscode设置console.log的快捷输出方式 编辑器中输入clg回车,可以直接输出console.log,并且同步输出变量的字符串和值 1、打开vscode点击左上角的文件 2、找到首选项 3、点击用户代码配置 4、在顶部输入框种输入javas,选择JavaScript选项 5、…...
服务注册/服务发现-Eureka
目录 1.引言:如果一个父项目中有多个子项目,但是这些子项目如何如何相互调用彼此的业务呢? 2.什么是注册中心 3.CAP理论 4.EureKa 5.服务注册 6.服务发现 7.负载均衡 1.引言:如果一个父项目中有多个子项目,但是…...
【机器学习】什么是随机森林?
什么是随机森林? 随机森林(Random Forest)是一种集成学习方法,它通过组合多个决策树来提高预测的准确性和鲁棒性。可以把随机森林看作是“森林”,而森林中的每棵树就是一个决策树。每棵树独立地做出预测,最…...
【Rust】一文掌握 Rust 的详细用法(Rust 备忘清单)
文章目录 入门配置 vscode 调试Hello_World.rs原始类型格式化打印风格变量注释函数声明宏元变量结构体元组结构体单元结构体 语句与表达式语句表达式 区间表达式 Rust 类型类型别名整数浮点数布尔值字符字符串字面量数组切片元组 Rust 字符串字符串字面量字符串对象.capacity()…...
为什么后端接口返回数字类型1.00前端会取到1?
这得从axios中得默认值说起: Axios 的 transformResponse axios 在接收到服务器的响应后,会通过一系列的转换函数(transformResponse)来处理响应数据,使其适合在应用程序中使用。默认情况下,axios 的 tran…...
单片机串口打印调试信息②
在STM32开发中,使用串口(UART)打印调试信息是调试嵌入式程序的核心手段。以下是基于STM32 HAL库的详细实现步骤和调试策略: 一、硬件准备 硬件连接: STM32开发板:以STM32F4系列为例,选择任意UAR…...
Windows下安装常用软件--MySQL篇
Windows下安装常用软件--MySQL篇 文章说明安装指导安装MySQL脚本 资料下载 文章说明 记录一下Windows下安装zip版的MySQL,采用简洁的方式安装,便于学习使用;作为对该篇文章的修正与完善(MySQL 关于 zip安装) 安装指导 …...
Qt 高效读写JSON文件,玩转QJsonDocument与QJsonObject
一、前言 JSON作为轻量级的数据交换格式,已成为开发者必备技能。Qt框架为JSON处理提供了完整的解决方案,通过QJsonDocument、QJsonObject和QJsonArray三大核心类,轻松实现数据的序列化与反序列化。 JSON vs INI 特性JSONINI数据结构支持嵌…...
计算机网络——数据链路层的功能
目录 物理链路 逻辑链路 封装成帧(组帧) 帧定界 透明传输 SDU 差错控制 可靠传输 流量控制 介质访问控制 主机需要实现第一层到第五层的功能,而路由器这种节点只需要实现第一层到第三层的这些功能 假设左边用户需要给右边用户发送…...
第60天:Web攻防-XSS跨站文件类型功能逻辑SVGPDFSWFPMessageLocalStorage
#知识点 1、Web攻防-XSS跨站-文件类型-html&pdf&swf&svg 2、Web攻防-XSS跨站-功能逻辑-postMessage&localStorage 术语:上传xss->其实就是将有恶意js代码的各类文件(swf,pdf,svg,html.xml等)上传->访问该文件->让浏…...
C/C++都有哪些开源的Web框架?
CppCMS CppCMS是一个采用C语言开发的高性能Web框架,通过模版元编程方式实现了在编译期检查RESTful路由系统,支持传统的MVC模式和多种语言混合开发模式。 CppCMS最厉害的功能是WebSocket,10万连接在内存中长期保存占用的大小不超过600MB&…...
RISC-V AIA学习2---IMSIC
我在学习文档这章时,对技术术语不太理解,所以用比较恰当的比喻来让自己更好的理解。 比较通俗的理解: 将 RISC-V 系统比作一个工厂: hart → 工厂的一条独立生产线IMSIC → 每条生产线配备的「订单接收员」MSI 中断 → 客户通过…...
2024年MathorCup数学建模B题甲骨文智能识别中原始拓片单字自动分割与识别研究解题全过程文档加程序
2024年第十四届MathorCup高校数学建模挑战赛 B题 甲骨文智能识别中原始拓片单字自动分割与识别研究 原题再现: 甲骨文是我国目前已知的最早成熟的文字系统,它是一种刻在龟甲或兽骨上的古老文字。甲骨文具有极其重要的研究价值,不仅对中国文…...
Python----计算机视觉处理(Opencv:霍夫变换)
一、霍夫变换 霍夫变换是图像处理中的一种技术,主要用于检测图像中的直线、圆或其他形状。其基本思想就是将图像空间中的点映射到参数空间中,通过在参数空间中寻找累计最大值来实现对特定形状的检测。 二、 霍夫直线变换 那么对于一个二值化后的图形来说…...
多语言生成语言模型的少样本学习
摘要 大规模生成语言模型,如GPT-3,是极具竞争力的少样本学习模型。尽管这些模型能够共同表示多种语言,但其训练数据以英语为主,这可能限制了它们的跨语言泛化能力。在本研究中,我们在一个涵盖多种语言的语料库上训练了…...
k8s存储介绍(二)Secret
Kubernetes(K8s)提供了一种安全的方式来存储和管理敏感信息,如密码、OAuth 令牌和 SSH 密钥,这就是 Secret。使用 Secret 可以避免将敏感数据硬编码到 Pod 规范或容器镜像中,从而提高安全性和可管理性。 1. Secret 的…...
代理IP与AI的碰撞:网络安全新防线解码
目录 一、代理IP:网络世界的“隐形斗篷” 二、AI加持:代理IP的“智能升级包” 三、协同作战:五大核心应用场景 场景1:智能风控系统 场景2:跨境电商竞品分析 场景3:智能汽车安全测试 场景4:…...
QT开发(4)--各种方式实现HelloWorld
目录 1. 编辑框实现 2. 按钮实现 前面已经写过通过标签实现的了,所以这里就不写了,通过这两个例子,其他的也是同理 1. 编辑框实现 编辑框分为单行编辑框(QLineEdit)双行编辑框(QTextEdit)&am…...
