untracked
描述
用法与 batch 相似,在给定的 untracker 函数内部永远不会被依赖收集
签名
ts
interface untracked<T extends () => any> {
(untracker?: T): ReturnType<T>
}用例
<script setup lang="ts">
import { autorun, observable, untracked } from '@formily/reactive'
import { onBeforeUnmount, ref } from 'vue'
import { pushLog } from '../observable/shared'
const obs = observable({
aa: 11,
})
const normalRuns = ref(0)
const untrackedRuns = ref(0)
const normalValue = ref(obs.aa)
const untrackedValue = ref(obs.aa)
const rawValue = ref(obs.aa)
const logs = ref<string[]>([])
const disposeNormal = autorun(() => {
normalRuns.value += 1
normalValue.value = obs.aa
pushLog(logs, `normal autorun #${normalRuns.value}: aa = ${obs.aa}`)
})
const disposeUntracked = autorun(() => {
untrackedRuns.value += 1
untrackedValue.value = untracked(() => obs.aa)
pushLog(logs, `untracked autorun #${untrackedRuns.value}: aa = ${untrackedValue.value}`)
})
function increment() {
obs.aa += 1
rawValue.value = obs.aa
}
function reset() {
obs.aa = 11
rawValue.value = 11
normalValue.value = 11
untrackedValue.value = 11
normalRuns.value = 0
untrackedRuns.value = 0
logs.value = []
}
onBeforeUnmount(() => {
disposeNormal()
disposeUntracked()
})
</script>
<template>
<div class="playground">
<p class="hint">
左边是普通读取,右边是 <code>untracked(() => obs.aa)</code>。修改 <code>aa</code>
后,只有普通读取的 autorun 会继续被依赖追踪。
</p>
<div class="toolbar">
<button class="btn" @click="increment">
obs.aa++
</button>
<button class="btn secondary" @click="reset">
reset display
</button>
</div>
<div class="metrics">
<div class="metric">
<div class="label">
当前 aa
</div>
<div class="value">
{{ rawValue }}
</div>
</div>
<div class="metric">
<div class="label">
normal runs
</div>
<div class="value">
{{ normalRuns }}
</div>
</div>
<div class="metric">
<div class="label">
untracked runs
</div>
<div class="value">
{{ untrackedRuns }}
</div>
</div>
</div>
<div class="panels">
<div class="panel">
<div class="panelTitle">
normal read
</div>
<pre>value: {{ normalValue }}</pre>
</div>
<div class="panel">
<div class="panelTitle">
untracked read
</div>
<pre>value: {{ untrackedValue }}</pre>
</div>
</div>
<div>
<div class="sectionTitle">
运行日志
</div>
<ul class="logs">
<li v-for="(log, index) in logs" :key="`${index}-${log}`">
{{ log }}
</li>
</ul>
</div>
</div>
</template>
<style scoped src="../observable/shared.css"></style> 左边是普通读取,右边是 untracked(() => obs.aa)。修改 aa 后,只有普通读取的 autorun 会继续被依赖追踪。
当前 aa
11
normal runs
1
untracked runs
1
normal read
value: 11
untracked read
value: 11
运行日志
- untracked autorun #1: aa = 11
- normal autorun #1: aa = 11
查看源码
示例代码
ts
import { autorun, observable, untracked } from '@formily/reactive'
const obs = observable({
aa: 11,
})
autorun(() => {
console.log(untracked(() => obs.aa)) // 变化时不会触发
})
obs.aa = 22