watch / watchEffect 的区别与用法,getCurrentInstance proxy 获取路由列表
watch 监听 ref 及 reactive 的区别,二者具体用法如下。
watch(state, (newValue, oldValue) => {
console.log(`原值为${oldValue}`)
console.log(`新值为${newValue}`)
})
const state = reactive({ count: 0 })
watch(() => state.count, (newValue, oldValue) => {
console.log(`原值为${oldValue}`)
console.log(`新值为${newValue}`)
})
() => state.count)才能正确拿到 newValue / oldValue。const state = reactive({ count: 0, name: 'zs' })
watchEffect(() => {
console.log(state.count)
console.log(state.name)
})
| API | 特点 | 适用场景 |
|---|---|---|
| watch | 可监听 ref 及 reactive 的值,可自由配置(deep / immediate),默认第一次不触发 | 需要监听变化前及变化后的值,用法相对繁琐 |
| watchEffect | 初始化时自动查找内部依赖的变量,内部任何一值更改都会触发回调,但不会返回修改前及修改后的数据 | 只需在依赖变化时执行副作用,无需拿新旧值 |
// watch 典型用法:deep + immediate 配置
watch(
symbolDataList,
newVal => {
if (!newVal.length) return;
symbolDataListObjData.symbolDataList = [...newVal];
},
{
deep: true,
immediate: true
}
);
// watchEffect 典型用法:自动收集依赖
watchEffect(() => {
console.log(state.count)
console.log(state.name)
})
由于 vue3 不会提供 this 选项,在处理路由时会获取当前的路由列表,可如下操作:
import { defineComponent, onMounted, ref, watch, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance()!;
const routeList = proxy?.$router.getRoutes() || [];
routeList.forEach(item => {
if (item.meta.menu && item.children && item.children.length > 0) {
item.children = item.children.filter(sonItem => {
return !sonItem.meta?.hidden;
});
menuList.value.push(item);
}
});
getCurrentInstance() 只能在 setup 或生命周期钩子中调用;通过 proxy 可以访问 $router、$route 等全局实例属性,弥补 vue3 无 this 的写法差异。