一、beforeRouteLeave指定路由后死循环
应用场景:
当希望某页面点击左上角返回时,不按原路径返回,而是跳转到某一指定页面。
1.踩坑写法:
beforeRouteLeave(to, from, next) {
if (this.isBack) {
console.log('to指定路由');
next('/stock/inventoryLog');
} else {
next();
}
},
2.解决办法:
beforeRouteLeave(to,from,next){
if(this.isBack){
const timer = setTimeout(()=>{
this.flag = true;
clearTimeout(timer);
},100)
}else{
next()
}
},
watch:{
flag(newval){
if(newval){
this.isBack = false;
this.$router.push('/stock/inventoryLog');
}
}
}
3.分析原因:
导航守卫方法接收的三个参数:
-
to:即将进入的目标路由;
-
from:当前导航正要离开的路由;
-
next:
-
-
next():进入管道中的下一个钩子;
-
next(false):中断当前导航,如果路由改变了,那么ur地址会重置到from路由对应的地址;
-
next('/')或者next({path:'/'}):跳转到一个不同的路由地址,当前的导航被中断,然后开始一个新的导航。
-
4.正确写法:
beforeRouteLeave(to,from,next){
if(this.isBack){
console.log('1,离开当前页面',to,from);
if(to.path == '/stock/inventoryLog'){
console.log('2,去到指定路由');
next()
}else{
console.log('3,手动重定向路由');
next('/stock/inventoryLog')
}
}else{
next()
}
},
分析一下上面代码中的打印顺序呢?
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
二、vue3中reactive定义的引用类型(对象object、数组array)直接赋值的话,会导致数据失去响应式。
1.踩坑写法:
<template>
<div>数组:{{myArr}}</div>
</template>
<script setup>
import { reactive } from "vue";
// 测试数组
let myArr = reactive([]);
setTimeout(()=>{
let res = [1,2,3];
myArr = res; // 直接赋值
},2000)
</script>
2.正确写法:
<template>
<div>数组1:{{myArr}}</div>
<div>数组2:{{myObj.arr}}</div>
</template>
<script setup>
import { reactive } from "vue";
let myArr = reactive([]);
let myObj = reactive({arr:[]});
setTimeout(()=>{
let res = [1,2,3];
myArr.push(...res); // 方法一
myObj.arr = res; // 方法二
},2000)
</script>
3.分析原因:
reactive返回的是一个proxy代理的对象(Vue3通过proxy代理实现数据的响应式),直接赋值会导致该对象被覆盖,失去响应式。
测试代码:
<script>
const { reactive, isReactive, ref, isRef } = Vue
Vue.createApp({
setup() {
let arr1 = reactive([]);
let arr2 = reactive([]);
let arr3 = ref([]);
console.log('初始化打印arr1',arr1,isReactive(arr1)); // 初始化打印arr1 Proxy{} true
console.log('初始化打印arr2',arr2,isReactive(arr2)); // 初始化打印arr2 Proxy{} true
console.log('初始化打印arr3',arr3,isRef(arr3)); // 初始化打印arr3 RefImpl{..., _value:Proxy{}, ...} true
setTimeout(()=>{
let res = [1,2,3];
arr1 = res;
arr2.push(...res);
arr3.value = res;
console.log('改变值后打印arr1',arr1,isReactive(arr1)); // 改变值后打印arr1 [1, 2, 3] false
console.log('改变值后打印arr2',arr2,isReactive(arr2)); // 改变值后打印arr2 Proxy{0: 1, 1: 2, 2: 3} true
console.log('改变值后打印arr3',arr3,isRef(arr3)); // 改变值后打印arr3 RefImpl{..., _value:Proxy{0: 1, 1: 2, 2: 3}, ...} true
},1000)
return {
arr1,
arr2,
arr3
}
}
}).mount('#app')
</script>
vue3 reactive源码如下:
补充:ref去初始化申明一个引用类型的数据,再通过.value去赋值和使用,仍然具有响应式。
疑问:为什么直接对ref.value赋值,数据仍具有响应式?
分析:在class RefImpl中,每一次的set操作,在符合条件的情况下,都会调用toReactive方法,如果是引用类型的数据,就会调用reactive方法,从而使ref.value数据具有响应式。
vue3 ref源码如下: