beforeRouteEnter中的this和与created的执行顺序
通过beforeRouteEnter获取前一个路由信息,如何在beforeRouteEnter中获取vue实例this,beforeRouteEnter的执行顺序
需求:从page1页进入page2页,page2页需要是一种样式,从其他页面进入page2页需要是另一种样式。
最常见的是从列表页点击详情进入详情页后返回列表页时,列表页需要保持原来的页码,而从其他页进入列表页时页码应为初始值1。
此时我们就需要获取到跳转路由的前一个路由信息来进行分辨页面该展示什么信息,可以使用beforeRouteEnter来进行判断。
一. 如何在beforeRouteEnter中获取vue实例this
从页面A跳转到页面B
to就是页面B,即当前路由信息,跳转后的路由信息
from就是页面A,即跳转前的路由信息
beforeRouteEnter中可以通过next中的vm获取到vue实例信息,vm可以当做this使用,this在beforeRouteEnter中值为null
beforeRouteEnter(to, from, next) {
next((vm) => {
console.log(to, to.name, "to", from, from.name, "from");
// 这里的vm指的就是vue实例,可以用来当做this使用
console.log(vm, "vm", this, "this");
vm.fromName = from.name; //获取跳转前路由的name并赋值给this.fromName
});
},
可以看到上方vm(也就是vue实例this)的 fromName值已经是跳转前路由的name属性值了。
二. beforeRouteEnter的执行顺序
beforeRouteEnter(to, from, next) {
console.log("next beforeRouteEnter");
next((vm) => {
vm.fromName = from.name; //获取跳转前路由的name并赋值给this.fromName
console.log(vm.fromName, "nexted beforeRouteEnter");
});
},
created() {
console.log(this.fromName, "created");
},
mounted() {
console.log(this.fromName, "mounted");
},
在同一个项目中beforeRouteEnter出现了两种执行顺序,一种是从菜单点进列表页,执行顺序是
beforeRouteEnter---->created---->mounted----->beforeRouterEnter的next()
另一种是点击列表页的详情按钮进入详情页后通过 this.$router.back(-1) 方法返回列表页,执行顺序是
beforeRouteEnter---->created---->beforeRouterEnter的next()----->mounted
由此,建议根据路由信息不同而执行不同操作的代码应写到beforeRouteEnter的next()中,不要写到created或mounted里。
三. 为解决需求举个栗子,例子使用的是vue框架和AntdVue前端UI框架(例子仅提供思路,不可直接复制运行)
<template>
<a-layout class="listcontent-container">
<div class="table">
<a-table :columns="columns" :data-source="caseData" :pagination="false"
><template #configureDetail="{ text }">
<span class="color" @click="handlerToConfigDetail(text)">详情</span>
</template>
</a-table>
</div>
<div class="pagination">
<a-pagination
:total="total"
:show-total="(total) => `共 ${total} 条`"
:page-size="pageSize"
v-model:current="current"
/>
</div>
</a-layout>
</template>
<script>
export default {
name: "ListContent",
data() {
return {
caseData: [],
columns: [],
current: 1, //当前页码
pageSize: 10, //当前一页容量
total: 0, //当前总数
};
},
beforeRouteEnter(to, from, next) {
next((vm) => {
// 这里的vm指的就是vue实例,可以用来当做this使用
vm.fromName = from.name; //获取上一级路由的name
//判断缓存的列表页的信息是否能正确解析并返回缓存的值
let config = vm.getCaseListConfig();
//如果是从详情页跳转回此列表页的,scene-detail为详情页路由名
if (vm.fromName === "scene-detail") {
//获取的缓存是否有值,有值根据缓存的值赋值当前页及页容量,无值设置为初始页1,页容量10
if (Object.keys(config).length > 0) {
vm.current = config.current;
vm.pageSize = config.pageSize;
} else {
vm.current = 1;
vm.pageSize = 10;
}
} else {
//非详情页跳转到列表页,设置为初始页1,页容量10
vm.current = 1;
vm.pageSize = 10;
}
//发送请求获取列表数据
vm.sendGetCaseExecution();
});
},
methods: {
//判断缓存的列表页的信息是否能正确解析并返回缓存的值
getCaseListConfig() {
try {
return JSON.parse(localStorage.getItem("caseListConfig")) || {};
} catch (error) {
return {};
}
},
//发送请求获取列表数据
sendGetCaseExecution() {
//...根据当前的页码信息和页容量信息向后端发送请求获取数据
},
//点击列表中的详情按钮
handlerToConfigDetail(text) {
//保留列表页当前页的信息
let obj = {};
obj.current = this.current;
obj.pageSize = this.pageSize;
localStorage.setItem("caseListConfig", JSON.stringify(obj));
},
},
};
</script>
注意:某些情况下可能会出现当前页码current明明已经是点击进详情页保存好的非1页,发送请求获取的数据也是非1页的值,但页面上的页码组件样式还是显示的是第1页。这种情况可以给页码组件加个v-if来控制页码组件的显示。
先默认给v-if设置pageShow值为false,然后在发送请求有返回内容的时候设置pageShow值为true来显示页码组件。
<template>
<a-layout class="listcontent-container">
<!-- ......... -->
<div class="pagination">
<a-pagination
v-if="pageShow"
:total="total"
:show-total="(total) => `共 ${total} 条`"
:page-size="pageSize"
v-model:current="current"
/>
</div>
</a-layout>
</template>
<script>
export default {
name: "ListContent",
data() {
return {
current: 1, //当前页码
pageSize: 10, //当前页容量
total: 0, //当前总数
pageShow: false, //page组件是否显示
};
},
beforeRouteEnter(to, from, next) {
next((vm) => {
vm.sendGetCaseExecution();
});
},
methods: {
//请求列表数据
sendGetCaseExecution() {
//发送请求
getCaseExecutionRecords(this.current - 1, this.pageSize).then((res) => {
console.log(res);
this.pageShow = true; //设置页码组件显示
});
},
},
};
</script>
更多推荐
所有评论(0)