Vue3_11(Composition API) computed | watchEffect | Watch
响应式计算和侦听 | Vue.js https://v3.cn.vuejs.org/guide/reactivity-computed-watchers.html#%E8%AE%A1%E7%AE%97%E5%80%BC
computed
方式一:接收一个getter函数,并为 getter 函数返回的值,返回一个不变的 ref 对象;
方式二:接收一个具有 get 和 set 的对象,返回一个可变的(可读写)ref 对象;
// 1.用法一: 传入一个getter函数 // computed的返回值是一个ref对象 const fullName = computed(() => firstName.value + " " + lastName.value); // 2.用法二: 传入一个对象, 对象包含getter/setter const fullName = computed({ get: () => firstName.value + " " + lastName.value, set(newValue) { const names = newValue.split(" "); firstName.value = names[0]; lastName.value = names[1]; } });
watchEffect 自动收集响应式数据的依赖
首先,watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;其次,只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行
获取watchEffect的返回值函数,调用该函数即可停止侦听
const stop = watchEffect(() => { console.log("name:", name.value, "age:", age.value); }); const changeAge = () => { age.value++; if (age.value > 25) { stop(); } }
给watchEffect传入的函数被回调时,其实可以获取到一个参数:onInvalidate
当副作用即将重新执行 或者 侦听器被停止(如果在 setup()
或生命周期钩子函数中使用了 watchEffect
,则在组件卸载时)时会执行该函数传入的回调函数
我们可以在传入的回调函数中,执行一些清除工作
const stop = watchEffect((onInvalidate) => { const timer = setTimeout(() => { console.log("网络请求成功~"); }, 2000) // 根据name和age两个变量发送网络请求 onInvalidate(() => { // 在这个函数中清除额外的副作用 // request.cancel() clearTimeout(timer); console.log("onInvalidate"); }) console.log("name:", name.value, "age:", age.value); });
调整watchEffect的执行时机
默认值是pre,它会在元素 挂载 或者 更新 之前执行;
post,将推迟副作用的初始运行,直到组件的首次渲染完成
sync
,这将强制效果始终同步触发。然而,这是低效的,应该很少需要
watchEffect(() => { console.log(title.value); }, { flush: "post" })
Watch
懒执行副作用(第一次不会直接执行);
更具体的说明当哪些状态发生变化时,触发侦听器的执行;
访问侦听状态变化前后的值;
侦听单个数据源
一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref);
直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);
const info = reactive({name: "why", age: 18}); // 1.侦听watch时,传入一个getter函数 watch(() => info.name, (newValue, oldValue) => { console.log("newValue:", newValue, "oldValue:", oldValue); }) // 2.传入一个可响应式对象: reactive对象/ref对象 // 情况一: reactive对象获取到的newValue和oldValue本身都是reactive对象 watch(info, (newValue, oldValue) => { console.log("newValue:", newValue, "oldValue:", oldValue); }) // 情况二: ref对象获取newValue和oldValue是value值的本身 const name = ref("why"); watch(name, (newValue, oldValue) => { console.log("newValue:", newValue, "oldValue:", oldValue); }) // 如果希望newValue和oldValue是一个普通的对象 watch(() => { return {...info} }, (newValue, oldValue) => { console.log("newValue:", newValue, "oldValue:", oldValue); }) //上面简便写法 watch(() => ({...info}), (newValue, oldValue) => { console.log("newValue:", newValue, "oldValue:", oldValue); })
侦听多个数据源
// 1.定义可响应式的对象 const info = reactive({name: "why", age: 18}); const name = ref("why"); // 2.侦听器watch watch([() => ({...info}), name], ([newInfo, newName], [oldInfo, oldName]) => { console.log(newInfo, newName, oldInfo, oldName); })
Watch 参数
深层的侦听 设置 deep 为true
立即执行 设置 immediate 为true