Web 前端框架选型:React、Vue 和 Angular 的对比与实践

Web 前端框架选型:React、Vue 和 Angular 的对比与实践

选择前端框架就像选择一个长期合作伙伴。错误的选择可能会让你的项目在未来几年内背负沉重的技术债务,而正确的选择则能让开发效率飞速提升。

经过多年的项目实践,我发现很多新人在框架选型时过于关注表面的语法差异,却忽略了更深层的架构思想和生态系统成熟度。今天我们就来深入分析 React、Vue 和 Angular 这三大主流框架的核心差异,以及在不同场景下的最佳选择。

框架核心理念对比

React:函数式编程思想

React 的核心思想是"一切皆组件",倡导函数式编程范式:

// React 组件示例
import React, { useState, useEffect } from 'react';function UserProfile({ userId }) {const [user, setUser] = useState(null);const [loading, setLoading] = useState(true);useEffect(() => {async function fetchUser() {try {const response = await fetch(`/api/users/${userId}`);const userData = await response.json();setUser(userData);} catch (error) {console.error('获取用户信息失败:', error);} finally {setLoading(false);}}fetchUser();}, [userId]);if (loading) return <div>加载中...</div>;if (!user) return <div>用户不存在</div>;return (<div className="user-profile"><img src={user.avatar} alt={user.name} /><h2>{user.name}</h2><p>{user.email}</p></div>);
}// 高阶组件模式
function withLoading(WrappedComponent) {return function LoadingComponent(props) {const [loading, setLoading] = useState(false);return (<div>{loading && <div>加载中...</div>}<WrappedComponent {...props} setLoading={setLoading} /></div>);};
}// 自定义 Hook
function useApi(url) {const [data, setData] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => {async function fetchData() {try {setLoading(true);const response = await fetch(url);const result = await response.json();setData(result);} catch (err) {setError(err);} finally {setLoading(false);}}fetchData();}, [url]);return { data, loading, error };
}

Vue:渐进式框架

Vue 强调渐进式增强,提供了多种开发模式:

// Vue 3 Composition API
<template><div class="user-profile"><div v-if="loading">加载中...</div><div v-else-if="error">{{ error.message }}</div><div v-else-if="user"><img :src="user.avatar" :alt="user.name" /><h2>{{ user.name }}</h2><p>{{ user.email }}</p></div></div>
</template><script>
import { ref, computed, watch, onMounted } from 'vue';export default {props: {userId: {type: String,required: true}},setup(props) {const user = ref(null);const loading = ref(true);const error = ref(null);// 计算属性const displayName = computed(() => {return user.value ? `${user.value.name} (${user.value.email})` : '';});// 监听器watch(() => props.userId, async (newId) => {await fetchUser(newId);}, { immediate: true });// 方法async function fetchUser(id) {try {loading.value = true;error.value = null;const response = await fetch(`/api/users/${id}`);user.value = await response.json();} catch (err) {error.value = err;} finally {loading.value = false;}}return {user,loading,error,displayName};}
};
</script>// 可组合函数 (Composables)
function useUser(userId) {const user = ref(null);const loading = ref(false);const error = ref(null);async function fetchUser() {loading.value = true;try {const response = await fetch(`/api/users/${userId.value}`);user.value = await response.json();} catch (err) {error.value = err;} finally {loading.value = false;}}watch(userId, fetchUser, { immediate: true });return { user, loading, error, fetchUser };
}

Angular:企业级应用架构

Angular 提供了完整的企业级解决方案:

// Angular 组件
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { takeUntil, catchError } from 'rxjs/operators';
import { UserService } from './user.service';@Component({selector: 'app-user-profile',template: `<div class="user-profile"><div *ngIf="loading">加载中...</div><div *ngIf="error">{{ error }}</div><div *ngIf="user && !loading"><img [src]="user.avatar" [alt]="user.name" /><h2>{{ user.name }}</h2><p>{{ user.email }}</p></div></div>`,styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent implements OnInit, OnDestroy {@Input() userId!: string;user: User | null = null;loading = false;error: string | null = null;private destroy$ = new Subject<void>();constructor(private userService: UserService) {}ngOnInit() {this.loadUser();}ngOnDestroy() {this.destroy$.next();this.destroy$.complete();}private loadUser() {this.loading = true;this.userService.getUser(this.userId).pipe(takeUntil(this.destroy$),catchError(error => {this.error = error.message;return [];})).subscribe(user => {this.user = user;this.loading = false;});}
}// Angular 服务
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';@Injectable({providedIn: 'root'
})
export class UserService {constructor(private http: HttpClient) {}getUser(id: string): Observable<User> {return this.http.get<User>(`/api/users/${id}`);}
}// 接口定义
interface User {id: string;name: string;email: string;avatar: string;
}

学习曲线与开发体验

React:灵活但需要生态选择

// React 项目结构示例
src/
├── components/
│   ├── common/
│   │   ├── Button/
│   │   │   ├── Button.jsx
│   │   │   ├── Button.test.js
│   │   │   └── Button.module.css
│   │   └── Modal/
│   └── features/
│       ├── auth/
│       └── dashboard/
├── hooks/
│   ├── useAuth.js
│   ├── useApi.js
│   └── useLocalStorage.js
├── services/
│   ├── api.js
│   └── auth.js
├── store/
│   ├── slices/
│   │   ├── authSlice.js
│   │   └── userSlice.js
│   └── index.js
└── utils/├── helpers.js└── constants.js// 状态管理选择 - Redux Toolkit
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';export const fetchUser = createAsyncThunk('user/fetchUser',async (userId, { rejectWithValue }) => {try {const response = await fetch(`/api/users/${userId}`);return await response.json();} catch (error) {return rejectWithValue(error.message);}}
);const userSlice = createSlice({name: 'user',initialState: {data: null,loading: false,error: null},reducers: {clearUser: (state) => {state.data = null;state.error = null;}},extraReducers: (builder) => {builder.addCase(fetchUser.pending, (state) => {state.loading = true;state.error = null;}).addCase(fetchUser.fulfilled, (state, action) => {state.loading = false;state.data = action.payload;}).addCase(fetchUser.rejected, (state, action) => {state.loading = false;state.error = action.payload;});}
});export const { clearUser } = userSlice.actions;
export default userSlice.reducer;

Vue:渐进式学习路径

// Vue 项目结构
src/
├── components/
│   ├── base/
│   │   ├── BaseButton.vue
│   │   └── BaseModal.vue
│   └── features/
├── composables/
│   ├── useAuth.js
│   ├── useApi.js
│   └── useStorage.js
├── stores/
│   ├── auth.js
│   └── user.js
├── router/
│   └── index.js
└── views/├── Home.vue└── Profile.vue// Pinia 状态管理
import { defineStore } from 'pinia';export const useUserStore = defineStore('user', {state: () => ({user: null,loading: false,error: null}),getters: {isLoggedIn: (state) => !!state.user,displayName: (state) => state.user?.name || 'Guest'},actions: {async fetchUser(userId) {this.loading = true;this.error = null;try {const response = await fetch(`/api/users/${userId}`);this.user = await response.json();} catch (error) {this.error = error.message;} finally {this.loading = false;}},clearUser() {this.user = null;this.error = null;}}
});// 在组件中使用
<template><div><div v-if="userStore.loading">加载中...</div><div v-else-if="userStore.error">{{ userStore.error }}</div><div v-else><h1>欢迎, {{ userStore.displayName }}!</h1></div></div>
</template><script setup>
import { useUserStore } from '@/stores/user';const userStore = useUserStore();
</script>

Angular:完整的开发工具链

// Angular 项目结构
src/
├── app/
│   ├── core/
│   │   ├── services/
│   │   ├── guards/
│   │   └── interceptors/
│   ├── shared/
│   │   ├── components/
│   │   ├── directives/
│   │   └── pipes/
│   ├── features/
│   │   ├── auth/
│   │   └── dashboard/
│   ├── app-routing.module.ts
│   └── app.module.ts
├── assets/
└── environments/// NgRx 状态管理
import { createAction, createReducer, createSelector, props } from '@ngrx/store';// Actions
export const loadUser = createAction('[User] Load User',props<{ userId: string }>()
);export const loadUserSuccess = createAction('[User] Load User Success',props<{ user: User }>()
);export const loadUserFailure = createAction('[User] Load User Failure',props<{ error: string }>()
);// Reducer
const initialState = {user: null,loading: false,error: null
};export const userReducer = createReducer(initialState,on(loadUser, (state) => ({...state,loading: true,error: null})),on(loadUserSuccess, (state, { user }) => ({...state,user,loading: false})),on(loadUserFailure, (state, { error }) => ({...state,error,loading: false}))
);// Effects
@Injectable()
export class UserEffects {loadUser$ = createEffect(() =>this.actions$.pipe(ofType(loadUser),switchMap(({ userId }) =>this.userService.getUser(userId).pipe(map(user => loadUserSuccess({ user })),catchError(error => of(loadUserFailure({ error: error.message })))))));constructor(private actions$: Actions,private userService: UserService) {}
}// Selectors
export const selectUserState = (state: AppState) => state.user;
export const selectUser = createSelector(selectUserState, state => state.user);
export const selectUserLoading = createSelector(selectUserState, state => state.loading);

性能对比分析

运行时性能测试

// 性能测试工具
class PerformanceBenchmark {constructor() {this.results = {react: {},vue: {},angular: {}};}// 组件渲染性能测试async testComponentRender(framework, componentCount) {const startTime = performance.now();switch (framework) {case 'react':await this.renderReactComponents(componentCount);break;case 'vue':await this.renderVueComponents(componentCount);break;case 'angular':await this.renderAngularComponents(componentCount);break;}const endTime = performance.now();return endTime - startTime;}// 大列表渲染测试async testLargeListRender(framework, itemCount) {const items = Array.from({ length: itemCount }, (_, i) => ({id: i,name: `Item ${i}`,value: Math.random()}));const startTime = performance.now();switch (framework) {case 'react':await this.renderReactList(items);break;case 'vue':await this.renderVueList(items);break;case 'angular':await this.renderAngularList(items);break;}const endTime = performance.now();return endTime - startTime;}// 状态更新性能测试async testStateUpdate(framework, updateCount) {const startTime = performance.now();for (let i = 0; i < updateCount; i++) {switch (framework) {case 'react':await this.updateReactState();break;case 'vue':await this.updateVueState();break;case 'angular':await this.updateAngularState();break;}}const endTime = performance.now();return endTime - startTime;}// 内存使用测试measureMemoryUsage() {if (performance.memory) {return {used: performance.memory.usedJSHeapSize,total: performance.memory.totalJSHeapSize,limit: performance.memory.jsHeapSizeLimit};}return null;}// 生成性能报告generateReport() {return {summary: this.results,recommendations: this.getRecommendations()};}getRecommendations() {const recommendations = [];// 基于测试结果生成建议if (this.results.react.renderTime < this.results.vue.renderTime) {recommendations.push('对于复杂UI,React的虚拟DOM优化更好');}if (this.results.vue.bundleSize < this.results.angular.bundleSize) {recommendations.push('Vue的包体积更小,适合移动端');}return recommendations;}
}// 使用示例
const benchmark = new PerformanceBenchmark();async function runBenchmarks() {console.log('开始性能测试...');// 测试组件渲染const reactRenderTime = await benchmark.testComponentRender('react', 1000);const vueRenderTime = await benchmark.testComponentRender('vue', 1000);const angularRenderTime = await benchmark.testComponentRender('angular', 1000);console.log('组件渲染性能 (1000个组件):');console.log(`React: ${reactRenderTime}ms`);console.log(`Vue: ${vueRenderTime}ms`);console.log(`Angular: ${angularRenderTime}ms`);// 测试大列表渲染const reactListTime = await benchmark.testLargeListRender('react', 10000);const vueListTime = await benchmark.testLargeListRender('vue', 10000);const angularListTime = await benchmark.testLargeListRender('angular', 10000);console.log('大列表渲染性能 (10000项):');console.log(`React: ${reactListTime}ms`);console.log(`Vue: ${vueListTime}ms`);console.log(`Angular: ${angularListTime}ms`);
}

包体积对比

// 构建分析工具
class BundleAnalyzer {constructor() {this.frameworks = {react: {core: 42.2, // KB (gzipped)router: 10.1,stateManagement: 8.5, // Redux Toolkittotal: 60.8},vue: {core: 34.8,router: 12.4,stateManagement: 7.2, // Piniatotal: 54.4},angular: {core: 130.0,router: 15.6,stateManagement: 22.4, // NgRxtotal: 168.0}};}compareFrameworks() {const comparison = {};Object.keys(this.frameworks).forEach(framework => {const data = this.frameworks[framework];comparison[framework] = {...data,efficiency: this.calculateEfficiency(data.total),recommendation: this.getRecommendation(framework, data.total)};});return comparison;}calculateEfficiency(bundleSize) {// 基于功能完整性和包体积计算效率const baseline = 50; // KBreturn Math.max(0, 100 - ((bundleSize - baseline) / baseline) * 100);}getRecommendation(framework, size) {if (size < 60) {return '适合移动端和性能敏感应用';} else if (size < 100) {return '适合中等规模应用';} else {return '适合大型企业应用';}}// 生成优化建议getOptimizationTips(framework) {const tips = {react: ['使用 React.lazy 进行代码分割','使用 React.memo 优化组件渲染','考虑使用 Preact 替代 React','使用 Tree Shaking 移除未使用代码'],vue: ['使用异步组件进行懒加载','启用 Vue 3 的 Tree Shaking','使用 defineAsyncComponent','优化第三方库的导入'],angular: ['使用 Angular CLI 的构建优化','启用 AOT 编译','使用懒加载模块','移除未使用的 Angular 模块']};return tips[framework] || [];}
}const analyzer = new BundleAnalyzer();
console.table(analyzer.compareFrameworks());

实际项目选型决策

项目评估框架

// 项目评估工具
class ProjectEvaluator {constructor() {this.criteria = {projectSize: { weight: 0.2 },teamExperience: { weight: 0.25 },performanceRequirements: { weight: 0.2 },developmentSpeed: { weight: 0.15 },longTermMaintenance: { weight: 0.2 }};}evaluateProject(projectData) {const scores = {react: this.scoreReact(projectData),vue: this.scoreVue(projectData),angular: this.scoreAngular(projectData)};return this.calculateFinalScores(scores);}scoreReact(project) {let score = 0;// 项目规模评分if (project.size === 'large') score += 8;else if (project.size === 'medium') score += 9;else score += 7;// 团队经验评分if (project.team.reactExperience >= 3) score += 9;else if (project.team.reactExperience >= 1) score += 7;else score += 5;// 性能要求评分if (project.performance === 'high') score += 9;else if (project.performance === 'medium') score += 8;else score += 7;// 开发速度评分if (project.timeline === 'tight') score += 7;else if (project.timeline === 'normal') score += 8;else score += 9;// 长期维护评分score += 8; // React 生态成熟return score;}scoreVue(project) {let score = 0;// 项目规模评分if (project.size === 'large') score += 7;else if (project.size === 'medium') score += 9;else score += 10;// 团队经验评分if (project.team.vueExperience >= 3) score += 9;else if (project.team.vueExperience >= 1) score += 8;else score += 9; // Vue 学习曲线平缓// 性能要求评分if (project.performance === 'high') score += 8;else if (project.performance === 'medium') score += 9;else score += 9;// 开发速度评分if (project.timeline === 'tight') score += 9;else if (project.timeline === 'normal') score += 9;else score += 8;// 长期维护评分score += 8;return score;}scoreAngular(project) {let score = 0;// 项目规模评分if (project.size === 'large') score += 10;else if (project.size === 'medium') score += 8;else score += 6;// 团队经验评分if (project.team.angularExperience >= 3) score += 9;else if (project.team.angularExperience >= 1) score += 7;else score += 4; // Angular 学习曲线陡峭// 性能要求评分if (project.performance === 'high') score += 8;else if (project.performance === 'medium') score += 8;else score += 7;// 开发速度评分if (project.timeline === 'tight') score += 6;else if (project.timeline === 'normal') score += 7;else score += 9;// 长期维护评分score += 9; // Angular 企业级支持return score;}calculateFinalScores(scores) {const final = {};Object.keys(scores).forEach(framework => {final[framework] = {score: scores[framework],percentage: Math.round((scores[framework] / 50) * 100),recommendation: this.getRecommendation(scores[framework])};});return final;}getRecommendation(score) {if (score >= 40) return '强烈推荐';else if (score >= 35) return '推荐';else if (score >= 30) return '可以考虑';else return '不推荐';}// 生成详细分析报告generateReport(projectData) {const evaluation = this.evaluateProject(projectData);const winner = Object.keys(evaluation).reduce((a, b) => evaluation[a].score > evaluation[b].score ? a : b);return {projectInfo: projectData,evaluation,recommendation: {primary: winner,reasoning: this.getReasoningForChoice(winner, projectData),alternatives: this.getAlternatives(winner, evaluation)}};}getReasoningForChoice(framework, project) {const reasons = {react: ['庞大的生态系统和社区支持','灵活的架构选择','优秀的性能表现','丰富的第三方库'],vue: ['渐进式学习曲线','优秀的开发体验','较小的包体积','良好的性能表现'],angular: ['完整的企业级解决方案','强大的 TypeScript 支持','丰富的内置功能','良好的长期维护性']};return reasons[framework] || [];}getAlternatives(primary, evaluation) {const sorted = Object.entries(evaluation).sort(([,a], [,b]) => b.score - a.score).filter(([framework]) => framework !== primary);return sorted.slice(0, 2).map(([framework, data]) => ({framework,score: data.score,reason: `备选方案,得分 ${data.score}`}));}
}// 使用示例
const evaluator = new ProjectEvaluator();const projectData = {size: 'medium', // small, medium, largeteam: {size: 5,reactExperience: 2,vueExperience: 1,angularExperience: 0},performance: 'high', // low, medium, hightimeline: 'normal', // tight, normal, relaxedbudget: 'medium',requirements: {seo: true,mobile: true,pwa: false,ssr: true}
};const report = evaluator.generateReport(projectData);
console.log('项目评估报告:', report);

最佳实践建议

选型决策树

// 框架选型决策树
class FrameworkDecisionTree {constructor() {this.decisionTree = {root: {question: '项目规模如何?',options: {small: 'teamSize',medium: 'performance',large: 'enterprise'}},teamSize: {question: '团队规模多大?',options: {'1-3': 'vue','4-8': 'experience','9+': 'performance'}},performance: {question: '性能要求如何?',options: {high: 'react',medium: 'complexity',low: 'vue'}},enterprise: {question: '是否需要企业级特性?',options: {yes: 'angular',no: 'react'}},experience: {question: '团队前端经验如何?',options: {beginner: 'vue',intermediate: 'react',expert: 'angular'}},complexity: {question: '项目复杂度如何?',options: {simple: 'vue',complex: 'react'}}};}makeDecision(answers) {let current = this.decisionTree.root;let path = ['root'];for (const answer of answers) {if (current.options && current.options[answer]) {const next = current.options[answer];path.push(next);if (this.isFramework(next)) {return {recommendation: next,path: path,confidence: this.calculateConfidence(path)};}current = this.decisionTree[next];} else {throw new Error(`无效的答案: ${answer}`);}}return null;}isFramework(value) {return ['react', 'vue', 'angular'].includes(value);}calculateConfidence(path) {// 基于决策路径长度计算置信度const maxDepth = 4;const depth = path.length;return Math.round((depth / maxDepth) * 100);}getQuestionFlow() {return Object.keys(this.decisionTree).map(key => ({id: key,question: this.decisionTree[key].question,options: Object.keys(this.decisionTree[key].options || {})}));}
}// 使用示例
const decisionTree = new FrameworkDecisionTree();// 模拟用户回答
const userAnswers = ['medium', 'high']; // 中等项目规模,高性能要求
const result = decisionTree.makeDecision(userAnswers);console.log('推荐框架:', result.recommendation);
console.log('决策路径:', result.path);
console.log('置信度:', result.confidence + '%');

总结

选择前端框架需要综合考虑多个因素:

关键决策因素:

  1. 项目规模 - 小项目选 Vue,大项目选 Angular,中等项目选 React
  2. 团队经验 - 新手友好度:Vue > React > Angular
  3. 性能要求 - 高性能场景:React ≥ Vue > Angular
  4. 开发效率 - 快速开发:Vue > React > Angular
  5. 生态系统 - 丰富程度:React > Angular > Vue

实用建议:

  • 创业公司/小团队:优先考虑 Vue,学习成本低,开发效率高
  • 中大型互联网公司:React 是主流选择,生态丰富,人才充足
  • 传统企业/大型项目:Angular 提供完整解决方案,适合长期维护

避免的误区:

  • 不要只看语法差异,要考虑整体生态
  • 不要盲目追求新技术,稳定性同样重要
  • 不要忽视团队学习成本和招聘难度

记住,没有最好的框架,只有最适合的框架。正确的选择能让项目事半功倍,错误的选择则可能让你在技术债务中苦苦挣扎。

你的项目适合哪个框架?欢迎分享你的选型经验和踩坑故事。

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

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

相关文章

C# 值拷贝、引用拷贝、浅拷贝、深拷贝

值拷贝定义&#xff1a;直接复制变量的值&#xff0c;适用于基本数据类型&#xff08;如int, float, char等&#xff09;。在 C# 中&#xff0c;值类型&#xff08;基本数据类型和结构体&#xff09;默认使用值拷贝。特点&#xff1a;创建原始值的完全独立副本&#xff0c;修改…

深度学习图像分类数据集—百种鸟类识别分类

该数据集为图像分类数据集&#xff0c;适用于ResNet、VGG等卷积神经网络&#xff0c;SENet、CBAM等注意力机制相关算法&#xff0c;Vision Transformer等Transformer相关算法。 数据集信息介绍&#xff1a;525种鸟类识别分类 训练数据集总共有84635张图片&#xff0c;每个文件夹…

零基础 “入坑” Java--- 八、类和对象(一)

文章目录一、初识面向对象二、类的定义和使用1.认识类2.类的定义格式三、类的实例化四、this引用五、对象的构造及初始化1.有关初始化2.构造方法3.就地初始化一、初识面向对象 Java是一门纯面向对象的语言&#xff08;OOP&#xff09;&#xff0c;在面向对象的世界里&#xff…

数字孪生技术引领UI前端设计新篇章:智能物联网的深度集成

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;数字孪生与物联网的共生革命在智能设备爆发式增长的今天&#xff0c;传统…

代码审计-shiro漏洞分析

一、关于shiro介绍 简单讲&#xff0c;shiro是apache旗下的一个Java安全框架&#xff0c;轻量级简单易上手&#xff0c;框架提供很多功能接口&#xff0c;常见的身份认证 、权限认证、会话管理、Remember 记住功能、加密等等。 二、漏洞分析 1.CVE-2019-12422-shiro550 漏洞原理…

EF提高性能(查询禁用追踪)(关闭延迟加载)

EF默认是支持延迟加载的&#xff0c;在加载一个表的数据时&#xff0c;会把关联表的数据一并加载&#xff0c;这样会影响性能。 一般建议关闭延迟加载可以提高EF加载的性能。还有其他方法提高性能&#xff08;查询禁用追踪&#xff09; 如果要实现延迟加载&#xff0c;必须满足…

Leetcode+JAVA+贪心III

134.加油站在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。给定两个整数数组 gas 和 …

Qt信号与槽机制及动态调用

Qt信号与槽机制及动态调用一、信号与槽1、Qt信号与槽机制概述2、信号与槽的基本使用3、信号与槽的特性4、使用Lambda表达式作为槽5、信号与槽的参数传递6、注意事项二、动态调用机制1、基本用法2、示例代码3、带参数的调用4、返回值处理5、信号与槽的动态连接6、动态方法调用7、…

K8s系列之:Kubernetes 的 OLM

K8s系列之:Kubernetes 的 OLM 什么是 Kubernetes 的 OLM什么是Kubernetes中的OperatorOLM 的功能OLM 的核心组件OLM优势OLM 的工作原理OLM 与 OperatorHub 的关系OLM示例场景什么是CRDoperator 和 CRD的关系为什么需要 CRD 和 OperatorCRD定义资源类型DebeziumServer如何使用d…

前端-HTML-day2

目录 1、无序列表 2、有序列表 3、定义列表 4、表格-基本使用 5、表格-结构标签 6、表格-合并单元格 7、表单-input基本使用 8、表单-input占位文本 9、表单-单选框 10、表单-上传多个文件 11、表单-多选框 12、表单-下拉菜单 13、表单-文本域 14、表单-label标签…

两种方式清除已经保存的git账号密码

方式一随便选择一个文件夹&#xff0c;然后鼠标右键-》TortoiseGit ->设置选择已保存的数据-》认证数据-》清除-》点击确定方式二 控制面板\用户帐户\凭据管理器-》windows凭据普通凭据-》找到git信息-》选择删除

Using Spring for Apache Pulsar:Message Production

1. Pulsar Template在Pulsar生产者端&#xff0c;Spring Boot自动配置提供了一个用于发布记录的PulsarTemplate。该模板实现了一个名为PulsarOperations的接口&#xff0c;并提供了通过其合约发布记录的方法。这些send API方法有两类&#xff1a;send和sendAsync。send方法通过…

CSS揭秘:10.平行四边形

前置知识&#xff1a;基本的css变形一、平行四边形 要实现一个平行四边形&#xff0c;可以使用CSS的skew变形属性来倾斜元素。 transform: skewX(-45deg);图-1显示容器和内容都出现了倾斜&#xff0c;该如何解决这个问题&#xff1f; 二、嵌套方案 我们通过将内容嵌套 div 并使…

深度学习 必然用到的 线性代数知识

把标量到张量、点积到范数全串起来&#xff0c;帮你从 0 → 1 搭建 AI 数学底座 &#x1f680; 1 标量&#xff1a;深度学习的最小单元 标量 就是一维空间里的“点”&#xff0c;只有大小没有方向。例如温度 52 F、学习率 0.001。 记号&#xff1a;普通小写 x&#xff1b;域&am…

OpenGL ES 纹理以及纹理的映射

文章目录开启纹理创建纹理绑定纹理生成纹理纹理坐标图像配置线性插值重复效果限制拉伸完整代码在 Android OpenGL ES 中使用纹理&#xff08;Texture&#xff09;可以显著提升图形渲染的质量和效率。以下是使用纹理的主要好处&#xff1a; 增强视觉真实感 纹理可以将复杂的图像…

从金字塔到个性化路径:AI 正在重新定义学习方式

几十年来&#xff0c;我们的教育系统始终遵循着一条熟悉的路线&#xff1a; 从小学、初中、高中&#xff0c;再到大学和研究生。这条标准化的路径&#xff08;K-12 到研究所&#xff09;结构清晰&#xff0c;却也缓慢。但在当今这个信息爆炸、知识快速更新、个性化需求高涨的时…

产品经理岗位职责拆解

以下是产品经理岗位职责的详细分解表&#xff0c;涵盖工作内容、核心动作及输出成果&#xff1a;岗位职责具体工作内容输出成果1. 日常版本迭代管理需求分析及PRD产出协调资源推动产品上线- 收集业务/用户需求&#xff0c;分析可行性及优先级- 撰写PRD文档&#xff0c;明确功能…

后端微服务基础架构Spring Cloud

版本关系 版本发布说明-阿里云Spring Cloud Alibaba官网 选择 创建项目 创建父项目 什么都不动&#xff0c;创建即可 1) 删掉没用的文件 保留 2) pom中加入 打包方式 <packaging>pom</packaging> 3) 删掉src 4) pom.xml中删除没用的 5)更改pom.xml中 spring…

数据分析框架和方法

一、核心分析框架 (The Big Picture Frameworks)​​描述性分析 (What Happened?)​​​​目的&#xff1a;​​ 了解过去发生了什么&#xff0c;描述现状&#xff0c;监控业务健康。​​核心工作&#xff1a;​​ 汇总、聚合、计算基础指标 (KPI)&#xff0c;生成报表和仪表盘…

电路研究9.3.10——合宙Air780EP中的AT开发指南:阿里云应用指南

这个好像也用不到&#xff0c;不过可以先贴出来。简单看了一下也没深入分析&#xff0c;直接扒过来了&#xff0c;感觉涉及到了上位机的学习了。我这下位机的可能用不到&#xff0c;就是贴过来好了。 应用概述 使用 AT 方式连接阿里云分为一机一密和一型一密&#xff0c;其中一…