首页IT科技vue路由重复(Vue–Router–解决多路由复用同一组件页面不刷新问题)

vue路由重复(Vue–Router–解决多路由复用同一组件页面不刷新问题)

时间2025-08-02 14:44:43分类IT科技浏览5995
导读:原文网址:Vue--Router--解决多路由复用同一组件页面不刷新问题_IT利刃出鞘的博客-CSDN博客...

原文网址:Vue--Router--解决多路由复用同一组件页面不刷新问题_IT利刃出鞘的博客-CSDN博客

简介

说明

        本文介绍如何解决Vue的多路由复用同一组件页面不刷新问题                 。

多路由复用同一组件的场景

多路由使用同一组件 比如:添加博客(path为:/addBlog)和编辑博客(path为:/editBlog)都对应同一个组件(EditBlog.vue) 动态路由 比如:用户详情页采用动态路由                 ,其path为:/user/:id                         ,组件都是UserDetail.vue

原因分析

        Vue中        ,相同的组件实例将被重复使用                         。如果两个路由都渲染同个组件                 ,复用比销毁再创建更高效        。不过                         ,复用会导致组件的生命周期函数不会被调用                 。而我们通常会将调后端接口放到created或mounted等生命周期函数中        ,生命周期函数没被调用         ,也就无法获取后端数据                         。

官网网址

https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html#响应路由参数的变化

问题复现

        本处以博客为例        。添加博客(path为:/addBlog)和编辑博客(path为:/editBlog)都对应同一个组件(EditBlog.vue)

代码

路由配置(router/index.js)

import Vue from vue import VueRouter from vue-router import BlogEdit from ../components/BlogEdit Vue.use(VueRouter) const routes = [ { path: /addBlog, name: AddBlog, component: BlogEdit }, { path: /editBlog, name: EditBlog, component: BlogEdit } ] const router = new VueRouter({ routes }) export default router

主页面(App.vue) 

<template> <div id="app"> <div id="nav"> <!--<router-link to="/">Home</router-link> |--> <!--<router-link to="/about">About</router-link>--> <router-link :to="{name: AddBlog}">创建博客</router-link> | <router-link :to="{name: EditBlog}">修改博客</router-link> </div> <router-view/> </div> </template> <style> <!-- 省略 --> </style>

博客编辑页(components/BlogEdit.vue)

<template> <div class="outer"> <div> 这是BlogEdit </div> </div> </template> <script> import LifeCycle from ../mixins/LifeCycle export default { name: BlogEdit, mixins: [LifeCycle] } </script> <style scoped> .outer { margin: 20px; border: 2px solid blue; padding: 20px; } </style>

混入生命周期(mixins/LifeCycle.js) 

我把生命周期的钩子函数单独拿了出来         。

export default { computed: { name () { return this.$options.name } }, created () { console.log(created ==> + this.name) }, activated () { console.log(activated ==> + this.name) }, deactivated () { console.log(deactivated ==> + this.name) }, destroyed () { console.log(destroyed ==> + this.name) } }

测试

访问:http://localhost:8080/#/

可见                         ,除了第1次进入                 ,之后的进入和退出没有触发相关的生命周期函数         ,比如:created等                         。 

解决方案

方案1:导航守卫

方法:在beforeRouteEnter中请求后端数据                 。

导航卫士钩子(mixins/NavigationGuard.js)

为便于管理                         ,我把导航卫士单独拿出来                 ,作为mixin给组件使用         。

export default { beforeRouteEnter (to, from, next) { // 无法访问this console.log(beforeRouteEnter ==> 来自: + from.path) console.log(beforeRouteEnter ==> 去往: + to.path) next(true) }, beforeRouteUpdate (to, from, next) { console.log(this.$options.name + :beforeRouteUpdate ==> 来自: + from.path) console.log(this.$options.name + :beforeRouteUpdate ==> 去往: + to.path) next(true) }, beforeRouteLeave (to, from, next) { console.log(this.$options.name + :beforeRouteLeave ==> 来自: + from.path) console.log(this.$options.name + :beforeRouteLeave ==> 去往: + to.path) next(true) } }

博客编辑组件(components/BlogEdit.vue)

<template> <div class="outer"> <div> 这是BlogEdit </div> </div> </template> <script> import LifeCycle from ../mixins/LifeCycle import NavigationGuard from ../mixins/NavigationGuard export default { name: BlogEdit, mixins: [LifeCycle, NavigationGuard] } </script> <style scoped> .outer { margin: 20px; border: 2px solid blue; padding: 20px; } </style>

测试

访问: http://localhost:8080/#/

可以发现:离开路由时会调用beforeRouteLeave,进入路由时会调用beforeRouteEnter                         。所以可以将调后端接口的方法放到beforeRouteEnter里边去                 。

方案2:watch监听$route

方法:使用watch监听$route的变化                         ,变化时根据情况请求后端数据。

修改博客编辑组件(components/BlogEdit.vue)

<template> <div class="outer"> <div> 这是BlogEdit </div> </div> </template> <script> import LifeCycle from ../mixins/LifeCycle export default { name: BlogEdit, mixins: [LifeCycle], watch: { $route (to, from) { console.log(组件: + this.$options.name) console.log(来自: + from.name) console.log(去往: + to.name) } } } </script> <style scoped> .outer { margin: 20px; border: 2px solid blue; padding: 20px; } </style>

测试

访问:http://localhost:8080/#/

可以发现:路由变化时会触发对$route的watch                         。所以可以将调后端接口的方法放到里边去                         。

方案3:父组件router-view指定key

        方法:在父组件的router-view中指定key                         ,这个key必须是唯一的,比如:"$route.fullPath"。这样vue就会认为每个内部路由都是不同的                 ,在跳转时便会强制刷新组件                 。

比如:

<router-view :key="$route.fullPath"></router-view>

修改App.vue

<router-view :key="$route.fullPath"></router-view><template> <div id="app"> <div id="nav"> <!--<router-link to="/">Home</router-link> |--> <!--<router-link to="/about">About</router-link>--> <router-link :to="{name: AddBlog}">创建博客</router-link> | <router-link :to="{name: EditBlog}">修改博客</router-link> </div> <!-- 原来代码 --> <-- <router-view/> --> <router-view :key="$route.fullPath"></router-view> </div> </template> <style> <!-- 省略 --> </style>

测试

访问:http://localhost:8080/#/

可以发现:可以正常触发组件的生命周期(created                 、destroyed)                         。

其他网址

Vue keepAlive实现不同的路由共用一个组件component的缓存问题_代码修整工的博客-CSDN博客

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
云和seo优化攻略(云和seo关键字技术) 数据软件开发就业方向(软件工具、数据挖掘、数据分析)