この記事は初の公開アカウント「Front-end Dashie」です。フォローしてサプライズをゲットしてください~
最新のフロントエンド面接では、vue と React は基本的に面接プロセス中に質問する必要があるテクノロジー スタックです。Vue の応答性のトピックについて話すときは、watch和computed
watch
と computed
はどちらもデータの変更を監視するために使用されますが、実装原則、使用シナリオ、動作に大きな違いがあります。この記事では、 watch
と computed
の原則と違いを詳しく説明し、面接プロセス中にいくつかの提案を提供します。
まず Vue 3 の応答性を理解する
Vue 3 は、基礎となるリアクティブ実装としてプロキシを使用して、オブジェクト プロパティの変更を監視し、対応する更新をトリガーします。データにアクセスすると、Vue は依存関係を確立し、データが変更されたときに関連する依存関係に通知して、ビューを更新します。これに関連して、基盤となるソース コードと watch
と computed
の使用法の違いを詳しく調査します。
時計
watch
オプションを使用すると、データの変更を監視し、カスタム操作を実行できます。通常、特定のデータの変更を監視し、非同期リクエスト、ログの印刷、アニメーションのトリガーなどの副作用を実行するために使用されます。 watch
プロパティを作成すると、Vue は watch
プロパティを監視するデータに関連付けるリアクティブな依存関係を確立します。監視対象のデータが変化すると、Vue は関連する watch
プロパティに通知し、そのコールバック関数をトリガーします。このコールバック関数は新しい値と古い値をパラメータとして受け取り、必要な操作を実行できます。
ソースコード分析
相关文件:vue/src/runtime-core/apiWatch.ts
和vue/src/reactivity/src/effect.ts
。
Vue 3 のソース コードでは、watch
の実装は主に createWatcher
関数と Watcher
クラスに依存します。 。
createWatcher
関数は、Watcher
インスタンスを作成Watcher
クラスはwatch
のコアであり、監視データへの依存関係を確立し、データが変更されたときにコールバック関数をトリガーします。- 内部
Watcher
では、依存関係の追跡とコールバックのトリガーは Vue のリアクティブ システムを通じて実装されています。監視対象のデータが変更されると、Vue は依存関係を検出し、Watcher
のコールバックをトリガーします。
解釈
1. vue/src/runtime-core/apiWatch.ts
では、watch
関数は次のように Watcher
インスタンスを作成します。あ>
export function watch(
source: WatchSource,
cb: WatchCallback,
options?: WatchOptions
): WatchStopHandle {
// 创建一个watcher实例
const watcher = new Watcher(vm, source, cb, {
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;
}
}
// ...
}
このコードは、データを取得して依存関係の追跡をトリガーするための メソッドや、< a i= など、Watcher
の重要な部分を示しています。 3> メソッドと メソッドは、コールバック関数をトリガーするために使用されます。 get
update
run
時計の使用
<template>
<div>
<p>Count: {
{ count }}</p>
<p>Doubled Count: {
{ doubledCount }}</p>
<button @click="incrementCount">Increment Count</button>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
const doubledCount = ref(0);
const incrementCount = () => {
count.value++;
};
watch(count, (newVal, oldVal) => {
// 监听 count 的变化
doubledCount.value = newVal * 2;
});
</script>
</template>
この例では、<script setup>
を使用して ref
と watch
をインポートし、 のリアクティブ変数を作成します。 count
と doubledCount
。次に、 watch
を使用して count
の変更をリッスンし、 count
が変更された場合に doubledCount
を更新します。価値。
計算された
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<T>(
getter: ComputedGetter<T>,
options?: ComputedOptions
): ComputedRef<T> {
// 创建一个computed实例
const c = new ComputedRefImpl(getter, options);
// ...
return c;
}
このコードは ComputedRefImpl
インスタンスを作成します。getter
は計算関数で、options
にはいくつかのオプションが含まれます。
2、ComputedRefImpl
の中心的な役割は、依存関係を追跡し、計算結果をキャッシュすることです。簡略化した例を次に示します。
class ComputedRefImpl<T> {
// ...
get value() {
// 如果依赖项发生变化,或者值尚未计算
if (this.dirty) {
// 清除之前的依赖项
cleanup(this);
// 设置当前的computed属性为活动属性
track(this);
// 执行计算函数,获取新值
this.value = this.effect();
// 标记computed属性为已计算
this.dirty = false;
// 清理并设置新的依赖项
stop(this);
}
// 返回缓存的值
return this.value;
}
// ...
}
このコードはComputedRefImpl
のコア ワークフローを示しています。
computed
プロパティまたは関連する依存関係が初めて変更されると、computed
プロパティは「ダーティ」(未計算)としてマークされます。- が属性値を取得すると、
value
のgetter
関数がトリガーされます。 - プロパティ値を取得するとき、Vue は以前の依存関係をクリアし、新しい依存関係を再追跡します。
- 計算関数 (
effect
) が実行されて新しい値が取得されます。 - 新しい値はキャッシュされ、
dirty
フラグがfalse
に設定され、計算されたことを示します。 - 新しい依存関係がクリーンアップされ、新しい依存関係が追跡されます。
このキャッシュ メカニズムによりcomputed
、関連する依存関係が変更された場合にのみ属性の値が再計算されるようになり、パフォーマンスが向上し、不必要な計算が削減されます。
計算された使用
<template>
<div>
<p>Count: {
{ count }}</p>
<p>Doubled Count: {
{ doubledCount }}</p>
<button @click="incrementCount">Increment Count</button>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const doubledCount = computed(() => {
// 计算属性,依赖于 count
return count.value * 2;
});
const incrementCount = () => {
count.value++;
};
</script>
</template>
この例では、<script setup>
を使用して ref
と computed
をインポートし、 リアクティブ変数を作成します。 >count
と doubledCount
。次に、 computed
を使用して、 の値に依存する計算プロパティ doubledCount
を作成します。 count
違いと使用シナリオ
上記 2 つの原理と使用法を紹介しました。watch
と computed
の主な違いと、それらが使用するシーンをまとめてみましょう。使用済み。
違い
- 响应方式:
watch
データの変更を監視するために使用され、副作用を実行できるようになります。computed
依存関係の変更に基づいて値が変化する新しい計算プロパティを導出するために使用されます。
- 缓存:
watch
結果はキャッシュされず、データが変更されるたびにコールバックがトリガーされます。computed
計算結果はキャッシュされ、依存関係が変更された場合にのみ再計算されます。
使用するシーン
-
時計の使用シナリオ:
- 非同期操作: ネットワーク要求の送信など、データ変更時に非同期操作を実行する必要がある場合。
- 副作用: ログ記録やアニメーションのトリガーなど、データ変更に関連する一部の操作を実行します。
- 複数のデータ変更を監視し、さまざまな操作を実行します。
-
計算された使用シナリオ:
- 派生プロパティ: テンプレートで使用するために既存のデータから新しいプロパティを派生する必要がある場合。
- 二重計算を避ける: 計算に負荷がかかるが、その依存関係が頻繁に変更されない場合は、
computed
を使用して不必要な計算を回避します。
面接のアドバイス
面接官は、Vue のリアクティブ システムについての理解を理解するために、watch
と computed
に関する質問をすることがよくあります。ここでは、皆様のお役に立つヒントをいくつか紹介します。
- 原則を理解する:
watch
とcomputed
がどのように機能するか、またそれらが Vue のリアクティブとどのように関連するかを必ず理解してください。システム関係。 - 使用例:
watch
とcomputed
をいつどのように使用するかについて明確な例を提供できるようにします。 - 違いと使用シナリオ:
watch
とcomputed
の違いと、どちらを選択すべきかを強調します。使用シナリオは 1 つです。 - パフォーマンスに関する考慮事項: パフォーマンスに関する質問に答えるときは、不必要な計算を回避してパフォーマンスを向上させるのにどのように役立つかを説明できるようにしてください
computed
。 - デモ体験: 実際のプロジェクトで
watch
とcomputed
を使用した経験と成功事例を共有してください。面接官はあなたの実際のスキルをよりよく理解できます。
学習教材の共有
この記事はmdnice複数のプラットフォームで公開されています。