阅读视图

发现新文章,点击刷新页面。

vue与react(自定义)中计算属性对比

一、核心概念对比

特性 Vue (Computed) React (useMemo/useCallback)
定义方式 声明式(基于依赖自动缓存) 命令式(手动声明依赖数组)
缓存机制 自动缓存(依赖不变则复用) 手动控制(依赖数组变化时重新计算)
响应式触发 依赖变更自动触发 需严格定义依赖数组
语法复杂度 低(模板中直接使用) 中(需配合Hooks使用)
适用场景 模板渲染优化、派生状态 性能优化、复杂计算避免重复执行

二、原理剖析

1. Vue Computed 原理

实现方式‌:基于响应式系统的依赖追踪

// Vue 3 源码简化版
function computed(getter) {
  let value;
  let dirty = true; // 标记是否需要重新计算

  const runner = effect(getter, {
    lazy: true,
    scheduler() {
      dirty = true; // 依赖变化时标记为脏数据
    }
  });

  return {
    get value() {
      if (dirty) {
        value = runner(); // 重新计算
        dirty = false;
      }
      return value;
    }
  };
}

关键点‌:

  • 依赖变更时通过scheduler标记数据为dirty
  • 下次访问时按需重新计算(惰性求值)

2. React useMemo 原理

实现方式‌:依赖数组的浅比较(Object.is)

// React 源码简化逻辑
function useMemo(factory, deps) {
  const hook = getCurrentHook();
  const nextDeps = deps || [];

  if (hook.memoizedState) {
    const [prevValue, prevDeps] = hook.memoizedState;
    if (areHookInputsEqual(nextDeps, prevDeps)) {
      return prevValue; // 依赖未变化时返回缓存值
    }
  }

  const newValue = factory();
  hook.memoizedState = [newValue, nextDeps];
  return newValue;
}

关键点‌:

  • 每次渲染时对比依赖数组
  • 依赖变化时重新执行工厂函数

三、代码实战对比

场景1:基础计算属性

Vue 实现

<template>
  <div>
    FullName: {{ fullName }} <!-- 自动缓存 -->
  </div>
</template>

<script>
export default {
  data() {
    return { firstName: '张', lastName: '三' };
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName; 
    }
  }
};
</script>

React 实现

function UserCard({ firstName, lastName }) {
  const fullName = useMemo(
    () => `${firstName} ${lastName}`,
    [firstName, lastName] // 需手动声明依赖
  );

  return <div>FullName: {fullName}</div>;
}

场景2:复杂数据过滤

Vue 实现

<template>
  <ul>
    <li v-for="user in activeUsers" :key="user.id">
      {{ user.name }}
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      users: [
        { id: 1, name: 'Alice', isActive: true },
        { id: 2, name: 'Bob', isActive: false }
      ]
    };
  },
  computed: {
    activeUsers() {
      return this.users.filter(u => u.isActive); // 自动缓存结果
    }
  }
};
</script>

React 实现

function UserList({ users }) {
  const activeUsers = useMemo(
    () => users.filter(u => u.isActive),
    [users] // 注意:如果users引用不变但内容变化,需深度比较
  );

  return (
    <ul>
      {activeUsers.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

四、复杂场景处理

场景1:依赖动态变化

Vue 的自动依赖追踪

vueCopy Code
<script>
export default {
  data() {
    return { a: 1, b: 2, useA: true };
  },
  computed: {
    result() {
      return this.useA ? this.a : this.b; // 自动识别依赖切换
    }
  }
};
</script>

React 的显式依赖管理

function Calculator({ a, b, useA }) {
  const result = useMemo(
    () => (useA ? a : b),
    [useA, useA ? a : b] // 必须明确所有可能依赖
  );
  return <div>Result: {result}</div>;
}

场景2:计算属性链式调用

Vue 的链式计算

<script>
export default {
  data() {
    return { price: 100, taxRate: 0.1 };
  },
  computed: {
    tax() {
      return this.price * this.taxRate;
    },
    total() { // 可依赖其他计算属性
      return this.price + this.tax;
    }
  }
};
</script>

React 的逐层缓存

function Invoice({ price, taxRate }) {
  const tax = useMemo(() => price * taxRate, [price, taxRate]);
  const total = useMemo(() => price + tax, [price, tax]); // 需手动传递依赖

  return <div>Total: {total}</div>;
}

五、性能优化对比

Vue 的优势

  1. 自动缓存‌:无需手动维护依赖,适合模板中的派生数据
  2. 细粒度更新‌:依赖变更时精准触发相关组件更新

React 的优势

  1. 灵活控制‌:可结合useCallback缓存函数,避免子组件无效渲染
  2. 跨组件复用‌:通过自定义Hook共享计算逻辑
// React 自定义Hook复用
function useTotal(price, taxRate) {
  return useMemo(() => {
    const tax = price * taxRate;
    return price + tax;
  }, [price, taxRate]);
}

// 多个组件共享同一逻辑
function Cart() {
  const total = useTotal(100, 0.1);
  return <div>Total: {total}</div>;
}

六、使用场景推荐

框架 推荐场景
Vue 1. 模板中的复杂表达式优化 2. 需要自动追踪依赖的派生数据 3. 表单联动计算
React 1. 需要手动控制缓存时机 2. 跨组件共享计算逻辑 3. 结合Context的复杂状态派生

  • Vue Computed‌:适合声明式UI场景,‌ "省心" ‌但灵活性较低
  • React useMemo‌:适合精细控制,‌ "强大" ‌但需手动维护依赖
  • 终极选择‌:Vue适合快速开发,React适合大型应用状态管理

UniApp金融理财产品项目简单介绍

一、项目目录架构设计 二、核心模块实现详解 1. 产品展示模块 ‌业务流程图: ‌ ‌关键实现代码: ‌ ‌优化点: ‌ 实现分页加载和虚拟滚动‌ 产品卡片使用骨架屏优化体验‌ 收益率数字动画效果‌

设计模式之------策略模式

一、什么是策略模式? ‌策略模式(Strategy Pattern) ‌ 是一种通过定义一系列可互换的算法,并将其封装成独立对象的设计模式。在前端开发中,它允许我们‌动态切换业务逻辑‌,避免复杂的条件

设计模式之------命令模式

‌一、命令模式定义与核心思想‌ ‌命令模式(Command Pattern) ‌ 是一种行为型设计模式,其核心是将‌请求‌或‌操作‌封装为独立对象,实现调用者(发送请求)与接收者(执行操作)的解耦。通
❌