React 和 Vue 的核心设计理念

 首先我们要知道,react,和vue的设计理念,区分框架的基本,

          react的核心思想是“单向数据流”,

          vue的核心是双向绑定,了解单向和双向,非常容易,

        react单向字面上来讲,指的是,数据是单向,且不可回,就想水流一样,在代码中,大        到组件传参,小到变量声明,比如 

      变量

               在javascript 当中 定义变量 有 let const var

                在react hooks  创建变量 ,是由  const [data,setData]=useState()

               data 是我们创建的变量, setData 是我们修改变量的方法函数,这里注意 setData就是一个函数

               react 要求状态更新必须通过 setData 完成,直接修改 data(如 data.push(...))不会                 触发渲染。

           这样就好比如 我想直接 通过 data=*** 这种 调用修改的方式 是不存在的,不同于 vue 在v2              中 可以this.data=****

            这里其实也牵扯到 渲染原理,触发机制,监听,就好比与你修改了变量,那视图更不更                   新,

    vue通过 this.data=**** 因为是双向绑定 ,你变化了 就更新试图 

react 就不会 ,react 必须要通过 hooks setData的形式 才可以 这也是react要求的 

再到组件层次 ,

  • React
    • 子组件绝对不能直接修改父组件传递的props,必须通过回调函数(如父组件传递的setState函数)来通知父组件更新状态。
    • 这种设计强制单向数据流,确保数据变化可预测,避免副作用。
  • Vue
    • 双向同步能力:通过v-model.sync修饰符实现父组件与子组件的双向绑定。子组件可通过$emit触发事件通知父组件更新数据,同时父组件数据变化自动同步到子组件。
    • 反模式警告:虽然技术上子组件可直接修改props(如Vue 2的this.prop = newValue),但Vue官方强烈反对,因其破坏单向数据流。Vue 3通过响应式系统检测props修改并发出警告,推荐使用emitcomputed属性

这不也牵扯到了项目类型,开发效率,优化等从0到1:一名前端程序员的项目沉思录-CSDN博客,

虚拟dom

              react,vue 都是 通过真实dom构建虚拟dom,页面修改变量,函数,不会去直接去修改真实dom,而是去改变虚拟dom,然后虚拟dom 和真实dom 之间通过 diff 算法,来对比差异. 这就像 去写协同编辑,在线编辑,对比差异 ,差异算法,

  • React(Fiber架构 + 单向递归)
    • 分层比较:仅对比同层级节点,不跨层级移动节点(如节点从A层移到B层会销毁重建)。
    • Key机制:依赖唯一key标识列表元素,通过key匹配节点以优化移动、添加或删除操作。无key时按索引顺序比较,可能导致列表头部插入时后续节点全部重建。
    • Fiber架构:将Diff过程分解为多个阶段(如协调、提交),支持异步渲染和优先级调度,适合处理复杂UI和频繁更新(如动画、高频交互)。
  • Vue(双端比较 + 静态优化)
    • 双端指针法:从新旧节点的头尾同时开始比较(头头、尾尾、头尾、尾头),优先复用两端相同的节点,减少中间部分的更新。
    • 静态标记(Patch Flags):编译时标记静态节点(如无绑定的纯文本),跳过运行时Diff,减少对比开销。
    • 最长递增子序列(LIS):在列表操作中(如移动、插入)通过LIS算法确定最小移动路径,减少DOM操作次数(例如列表反转仅需1次移动)

 React Hooks 全面解析

// 基础hooks
import React, { useState, useEffect, useContext } from 'react';
// useState - 状态管理
function Counter() {
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: '', age: 0 });
// 函数式更新
const increment = () => setCount(prev => prev + 1);
return ;
}
// useEffect - 副作用处理
function DataFetcher({ id }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let isMounted = true;
const fetchData = async () => {
try {
const response = await fetch(`/api/data/${id}`);
const result = await response.json();
if (isMounted) {
setData(result);
setLoading(false);
}
} catch (error) {
if (isMounted) setLoading(false);
}
};
fetchData();
// 清理函数
return () => {
isMounted = false;
// 取消请求或其他清理操作
};
}, [id]); // 依赖数组
return loading ? Loading... : {data};
}
// useContext - 跨组件数据传递
const ThemeContext = React.createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return ;
}

高级 hooks
import React, { useReducer, useCallback, useMemo, useRef, useImperativeHandle } from 'react';
// useReducer - 复杂状态逻辑
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
case 'reset':
return { count: 0 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
Count: {state.count}
);
}
// useCallback - 记忆函数
function Parent() {
const [count, setCount] = useState(0);
// 只有count变化时才会重新创建
const handleClick = useCallback(() => {
console.log('Count:', count);
}, [count]);
return ;
}
// useMemo - 记忆计算结果
function ExpensiveComponent({ list }) {
const sortedList = useMemo(() => {
return list.sort((a, b) => a.value - b.value);
}, [list]); // 只有list变化时重新计算
return {sortedList.map(item => {item.value})};
}
// useRef - DOM引用和可变值
function TextInput() {
const inputRef = useRef(null);
const intervalRef = useRef();
useEffect(() => {
// 存储定时器ID
intervalRef.current = setInterval(() => {
// 执行某些操作
}, 1000);
return () => clearInterval(intervalRef.current);
}, []);
const focusInput = () => {
inputRef.current.focus();
};
return (
<>
);
}
// useImperativeHandle - 暴露子组件方法
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
scrollIntoView: () => {
inputRef.current.scrollIntoView();
}
}));
return ;
}
FancyInput = React.forwardRef(FancyInput);

React 高级特性

/ 创建Context
const UserContext = React.createContext({
user: null,
login: () => {},
logout: () => {}
});
// Provider组件
function UserProvider({ children }) {
const [user, setUser] = useState(null);
const login = async (credentials) => {
const userData = await loginAPI(credentials);
setUser(userData);
};
const logout = () => {
logoutAPI();
setUser(null);
};
return (
{children}
);
}
// 消费Context
function UserProfile() {
const { user, logout } = useContext(UserContext);
return (
Welcome, {user.name}
);
}
Refs转发和DOM操作
// Refs转发
const CustomInput = React.forwardRef((props, ref) => {
return ;
});
// 在父组件中使用
function Parent() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return ;
}

Vue 3 Composition API

        模板语法糖
Visible
Not Visible
{{ item.name }}
Header
Main content
组件通信

export default {
props: {
title: String
},
emits: ['update-title'],
methods: {
updateTitle(newTitle) {
this.$emit('update-title', newTitle);
}
}
};
// 祖先组件
export default {
provide() {
return {
theme: 'dark',
user: reactive({ name: 'John' })
};
}
};
// 后代组件
export default {
inject: ['theme', 'user']
};
自定义指令
// 全局指令
app.directive('focus', {
mounted(el) {
el.focus();
}
});
// 局部指令
export default {
directives: {
highlight: {
mounted(el, binding) {
el.style.backgroundColor = binding.value || 'yellow';
},
updated(el, binding) {
el.style.backgroundColor = binding.value;
}
}
}
};
// 使用

特性

React

Vue

​设计理念​

函数式编程

渐进式框架

​学习曲线​

相对陡峭

相对平缓

​模板系统​

JSX

模板语法

​状态管理​

不可变状态

可变状态

​样式方案​

CSS-in-JS/CSS Modules

Scoped CSS/CSS Modules

posted on 2025-09-25 12:38  ycfenxi  阅读(16)  评论(0)    收藏  举报