2024年Web前端最全前端面试怎么总问watch和computed区别,前端面试项目中的难点

最后

今天的文章可谓是积蓄了我这几年来的应聘和面试经历总结出来的经验,干货满满呀!如果你能够一直坚持看到这儿,那么首先我还是十分佩服你的毅力的。不过光是看完而不去付出行动,或者直接进入你的收藏夹里吃灰,那么我写这篇文章就没多大意义了。所以看完之后,还是多多行动起来吧!

可以非常负责地说,如果你能够坚持把我上面列举的内容都一个不拉地看完并且全部消化为自己的知识的话,那么你就至少已经达到了中级开发工程师以上的水平,进入大厂技术这块是基本没有什么问题的了。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

deep: options && options.deep,
    flush: options && options.flush,
    onTrack: options && options.onTrack,
    onTrigger: options && options.onTrigger,
  });
  // …
}


这段代码创建了一个`Watcher`实例,其中`vm`是Vue实例,`source`是要监视的数据,`cb`是回调函数,以及其他选项。


2、Watcher`的核心工作在`vue/src/reactivity/src/effect.ts`中,其中包含了依赖项追踪和回调触发的逻辑。下面是一个简化的示例:



class Watcher {
  // …

get() {
    // 设置当前的watcher为活动watcher
    pushTarget(this);
    // 执行监视的数据,触发依赖项的收集
    const value = this.getter.call(this.vm, this.vm);
    // 恢复之前的watcher
    popTarget();
    return value;
  }

update() {
    // 触发回调函数,通知数据变化
    this.run();
  }

run() {
    // 执行回调函数
    const value = this.get();
    if (value !== this.value || isObject(value) || this.deep) {
      // 触发回调函数
      this.cb(value, this.value);
      this.value = value;
    }
  }

// …
}


这段代码展示了`Watcher`的关键部分,包括`get`方法用于获取数据和触发依赖项追踪,以及`update`和`run`方法用于触发回调函数。


#### watch使用



Count: {{ count }}

Doubled Count: {{ doubledCount }}


在这个示例中,我们使用 `<script setup>` 来导入 `ref` 和 `watch`,并创建了 `count` 和 `doubledCount` 的响应式变量。然后,我们使用 `watch` 来监听 `count` 的变化,并在 `count` 变化时更新 `doubledCount` 的值。


### Computed


`computed`的工作原理与`watch` 有一些差异。`computed`允许派生出一个新的计算属性,它依赖于其他响应式数据。当你定义一个`computed`属性时,Vue会建立一个依赖关系,将该计算属性关联到其依赖项。计算属性的值仅在其依赖项发生变化时重新计算,并且在多次访问时会返回缓存的结果。这可以减少不必要的计算,提高性能。


#### 源码分析


在Vue 3的源码中,`computed`的实现主要依赖于`createComputed`函数和`ComputedRefImpl`类。相关部分位于`vue/src/reactivity/src/computed.ts`文件中。


* `createComputed`函数负责创建`ComputedRefImpl`实例,接收计算函数和其他选项。
* `ComputedRefImpl`类是`computed`的核心,它包装了计算函数并实现了缓存机制。计算函数的执行和结果的缓存是通过Vue的响应式系统实现的。
* `ComputedRefImpl`实例在内部维护一个缓存,当依赖的数据变化时,它会重新计算并更新缓存。


##### 解读


1、在`vue/src/reactivity/src/computed.ts`中,`computed`函数负责创建`ComputedRefImpl`实例,如下所示:



export function computed(
  getter: ComputedGetter,
  options?: ComputedOptions
): ComputedRef {
  // 创建一个computed实例
  const c = new ComputedRefImpl(getter, options);
  // …
  return c;
}


这段代码创建了一个`ComputedRefImpl`实例,其中`getter`是计算函数,`options`包含一些选项。


2、`ComputedRefImpl`的核心工作是负责追踪依赖项和缓存计算结果。下面是一个简化的示例:



class ComputedRefImpl {
  // …

get value() {
    // 如果依赖项发生变化,或者值尚未计算
    if (this.dirty) {
      // 清除之前的依赖项
      cleanup(this);

// 设置当前的computed属性为活动属性
      track(this);

// 执行计算函数,获取新值
      this.value = this.effect();

// 标记computed属性为已计算
      this.dirty = false;

// 清理并设置新的依赖项
      stop(this);
    }

// 返回缓存的值
    return this.value;
  }

// …
}


这段代码展示了`ComputedRefImpl`的核心工作流程:


1. 当首次访问`computed`属性或相关依赖项发生变化时,`computed`属性会被标记为"dirty"(未计算)。
2. 在获取属性值时,`value`的`getter`函数会被触发。
3. 在获取属性值时,Vue会清除先前的依赖项,然后重新追踪新的依赖项。
4. 计算函数(`effect`)会被执行,以获取新的值。
5. 新的值会被缓存,同时`dirty`标志会被设置为`false`,表示已计算。
6. 新的依赖项会被清理,并新的依赖项会被追踪。


这个缓存机制确保了`computed`属性的值只有在相关依赖项发生变化时才会重新计算,提高了性能并减少不必要的计算。


#### Computed使用



Count: {{ count }}

Doubled Count: {{ doubledCount }}

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值