vue3学习记录-watch
- 1.watch
- 2.watchEffect
1.watch
直接总结下。。。
<script setup>
import { ref, reactive, computed, watch } from 'vue'const input = ref('小邱')
const input1 = ref('小小邱')
const input3 = ref('3')
const input4 = ref('4')
const x = ref('1')
const y = ref('2')
const obj = reactive({a: {b: {c: 1}}
})
const obj2 = reactive({a: {b: {c: 1}}
})
const obj3 = reactive({a: {b: {c: 1}}
})
//单个监听
watch(input, (newval, oldval) => {console.log(newval, oldval)
})
watch(input1, (newval, oldval) => {console.log(newval, oldval)
})//深度监听
//深度监听对象 监听前后的值都是新值
watch(obj3, (newval, oldval) => {console.log('深层监听', newval, oldval)
})
//不能直接侦听响应式对象的属性值 !
watch(obj.a.b.c, (newval, oldval) => {console.log('深层监听obj.a.b.c', newval, oldval)
})
watch(() => obj.a.b.c, (newval, oldval) => {console.log('深层监听obj.a.b.c', newval, oldval)
})//一次监听多个
watch([input3, input4], (newval, oldval) => {console.log(newval, oldval)
})
watch([input3, () => input4.value], (newval, oldval) => {console.log('多个input监听箭头函数写法', newval, oldval)
})
watch([input3,() => obj2.a.b.c], (newval, oldval) => {console.log('多个input监听带深层属性', newval, oldval)
})
//多个input监听带深层对象 监听前后的值都是新值
watch([input3,obj2], (newval, oldval) => {console.log('多个input监听带深层对象', newval, oldval)
})// getter 函数
watch(() => x.value + y.value,(sum, oldsum) => {console.log(`sum of x + y is: ${sum},oldsum:${oldsum}`)}
)
//这样写算是错误写法 监听不到 因为x+y不是一个响应式对象
watch(() => x + y,(sum, oldsum) => {console.log(`sum111 of x + y is: ${sum},oldsum:${oldsum}`)}
)
</script><template><div class="app"><div class="content"><p>单个监听</p><el-input v-model="input"></el-input><el-input v-model="input1"></el-input><p>深度监听</p><el-input v-model="obj3.a.b.c"></el-input><el-input v-model="obj.a.b.c"></el-input><p>一次监听多个</p><el-input v-model="input3"></el-input><el-input v-model="input4"></el-input><el-input v-model="obj2.a.b.c"></el-input><p>getter 函数</p><el-input-number v-model="x"></el-input-number><el-input-number v-model="y"></el-input-number></div></div></template><style scoped>
.app {display: flex;align-items: center;justify-content: center;
}
</style>
2.watchEffect
侦听器的回调使用与源完全相同的响应式状态是很常见的。例如下面的代码,在每当 todoId 的引用发生变化时使用侦听器来加载一个远程资源:
const todoId = ref(1)
const data = ref(null)watch(todoId,async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()},{ immediate: true }
)
特别是注意侦听器是如何两次使用 todoId 的,一次是作为源,另一次是在回调中。其实,这样写也是可以的。
watch(todoId,async (newVal) => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${newVal}`)data.value = await response.json()},{ immediate: true }
)
我们可以用 watchEffect 函数 来简化上面的代码。watchEffect() 允许我们自动跟踪回调的响应式依赖。上面的侦听器可以重写为:
watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})
对于这种只有一个依赖项的例子来说,watchEffect() 的好处相对较小。但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。
import { ref, watchEffect } from 'vue';setup() {const x = ref(1);const y = ref(2);const z = ref(3);watchEffect(() => {console.log(`x + y + z = ${x.value + y.value + z.value}`);});// 后续对 x, y, z 的任何修改都会触发 watchEffect 中的函数
}
在这个例子中,我们创建了三个响应式引用 x、y 和 z。然后我们使用 watchEffect 来观察它们的和。由于我们没有指定依赖项,watchEffect 会自动追踪 x.value、y.value 和 z.value。无论 x、y 还是 z 发生变化,watchEffect 中的函数都会被重新执行,并打印出新的和。
如果你使用 watch 来实现同样的功能,你需要手动指定依赖项:
import { ref, watch } from 'vue';setup() {const x = ref(1);const y = ref(2);const z = ref(3);watch(() => x.value + y.value + z.value,(newSum) => {console.log(`x + y + z = ${newSum}`);});// 这需要你手动维护依赖项列表,当依赖项增加时,你需要更新 watch 的第一个参数
}
使用 watchEffect 可以简化这个过程,因为你不需要手动维护依赖项列表。当项目中的状态变化比较复杂或者依赖项很多时,watchEffect 可以大大简化代码。
学习ing,后续随缘再更新