[TOC]
computed 计算
与 Options API 基本一致
const count = ref(1);
// 返回 get 的只需要用一个回调函数
const myCount = computed(() => count.value * 2);
// getter / setter, 使用一个带有 get 和 set 方法的对象
const yourCount = computed({
get(){
return count.value * 2;
},
set(val){
count.value = val + 1;
}
});
watchEffect
根据响应式状态自动就用和重新应用副作用。(和 React Hooks 的 useEffect 相似)
会立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数
停止侦听
返回一个停止侦听的函数,可以显式停止侦听。
而在组件卸载时自动停止侦听
const count = ref(1);
const name = ref('Mr.Lee');
// 第一次运行会先执行一次
watchEffect(() => {
console.log("effect~");
});
// 响应式追踪依赖
const stop = watchEffect(() => {
// 输出响应式数据 count,会自动收集其依赖,监控依赖变更
// 如果依赖进行变更,会再一次执行一次回调函数
console.log(count.value);
});
name.value = "Ms.Wang"; // 这里不会收集,因为 watchEffect 没用到这个响应式数据
const id = setInterval(() => {
// 会被 watchEffect 当作依赖收集,并监控变更
count.value++;
if (count.value > 20) {
stop(); // 手动停止侦听
}
if (count.value > 30) clearInterval(id);
}, 100);
onInvalidate 清除副作用
在使用 watchEffect 异步操作时,会产生一些副作用,需要一些清理手段
而清理这些需要在失效时清理,即完成之前状态清理掉
watchEffect 提供侦听副作用的参数 onInvalidate
- onInvalidate 当副作用失效时回调
- 当依赖变更执行 watchEffect 时,最先执行这个副作用回调
当第二执行时,会先执行 onInvalidate 回调,再执行上面的输出 ```vue
<a name="szRhv"></a>
## watchEffect 的 options
<a name="BcDV3"></a>
### 侦听的时机
- 默认 flush: 'pre' <br />清除副作用 -> 侦听内容 -> onBeforeUpdate
- flush: 'post'<br />onBeforeUpdate -> 清除副作用 -> 侦听内容
<a name="ryvRY"></a>
### 侦听器调试
在开发模式时使用
- onTrack(e) 将在响应式 property 或 ref 作为依赖项被追踪时被调用
- onTrigger(e) { debugger; } 将在依赖项变更导致副作用被触发时被调用
<a name="bn4CH"></a>
# watch
与 Options API 对象配置一样
1. 侦听特定的数据源(watchEffect 是收集依赖式)
2. 副作用在第二参数回调执行,并且是懒执行
3. 可以访问当前改变的值和改变前的值
```javascript
const count = ref(0);
const name = ref('Mr.Lee');
// ref 对象,会自动 unwrap
watch(count, (count, prevCount) => {
console.log('count:', count, 'prevCount:', prevCount);
});
// 回调函数,ref 对象要手动 unwrap
watch(() => count.value, (count, prevCount) => {
console.log('count:', count, 'prevCount:', prevCount);
});
// 侦听多个,使用数组
watch([count, name], ([count, prevCount], [name, prevName]) => {
console.log('count:', count, 'prevCount:', prevCount);
console.log('name:', name, 'prevName:', prevName);
});
// 尝试检查深度嵌套对象或数组中的 property 变化, 第三个参数 options 对象的 deep 设置为 true
const state = reactive({
id: 1,
attributes: {
name: "",
},
});
watch(
() => state,
(state, prevState) => {
console.log(
"deep ",
state.attributes.name,
prevState.attributes.name
);
},
{ deep: true }
);