Vue?Router解決多路由復(fù)用同一組件頁面不刷新問題(場景分析)
簡介
說明
本文介紹如何解決Vue的多路由復(fù)用同一組件頁面不刷新問題。
多路由復(fù)用同一組件的場景
- 多路由使用同一組件
比如:添加博客(path為:/addBlog)和編輯博客(path為:/editBlog)都對應(yīng)同一個組件(EditBlog.vue)
- 動態(tài)路由
比如:用戶詳情頁采用動態(tài)路由,其path為:/user/:id,組件都是UserDetail.vue
原因分析
Vue中,相同的組件實例將被重復(fù)使用。如果兩個路由都渲染同個組件,復(fù)用比銷毀再創(chuàng)建更高效。不過,復(fù)用會導(dǎo)致組件的生命周期函數(shù)不會被調(diào)用。而我們通常會將調(diào)后端接口放到created或mounted等生命周期函數(shù)中,生命周期函數(shù)沒被調(diào)用,也就無法獲取后端數(shù)據(jù)。
官網(wǎng)網(wǎng)址
https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html#響應(yīng)路由參數(shù)的變化
問題復(fù)現(xiàn)
本處以博客為例。添加博客(path為:/addBlog)和編輯博客(path為:/editBlog)都對應(yīng)同一個組件(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'}">創(chuàng)建博客</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)
我把生命周期的鉤子函數(shù)單獨(dú)拿了出來。
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次進(jìn)入,之后的進(jìn)入和退出沒有觸發(fā)相關(guān)的生命周期函數(shù),比如:created等。
解決方案
方案1:導(dǎo)航守衛(wèi)
方法:在beforeRouteEnter中請求后端數(shù)據(jù)。
導(dǎo)航衛(wèi)士鉤子(mixins/NavigationGuard.js)
為便于管理,我把導(dǎo)航衛(wèi)士單獨(dú)拿出來,作為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/#/

可以發(fā)現(xiàn):離開路由時會調(diào)用beforeRouteLeave,進(jìn)入路由時會調(diào)用beforeRouteEnter。所以可以將調(diào)后端接口的方法放到beforeRouteEnter里邊去。
方案2:watch監(jiān)聽$route
方法:使用watch監(jiān)聽$route的變化,變化時根據(jù)情況請求后端數(shù)據(jù)。
修改博客編輯組件(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/#/

可以發(fā)現(xiàn):路由變化時會觸發(fā)對$route的watch。所以可以將調(diào)后端接口的方法放到里邊去。
方案3:父組件router-view指定key
方法:在父組件的router-view中指定key,這個key必須是唯一的,比如:"$route.fullPath"。這樣vue就會認(rèn)為每個內(nèi)部路由都是不同的,在跳轉(zhuǎn)時便會強(qiáng)制刷新組件。
比如:
<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'}">創(chuàng)建博客</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/#/

可以發(fā)現(xiàn):可以正常觸發(fā)組件的生命周期(created、destroyed)。
其他網(wǎng)址
Vue keepAlive實現(xiàn)不同的路由共用一個組件component的緩存問題
到此這篇關(guān)于VueRouter解決多路由復(fù)用同一組件頁面不刷新問題的文章就介紹到這了,更多相關(guān)VueRouter復(fù)用同一組件頁面不刷新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+flv.js+SpringBoot+websocket實現(xiàn)視頻監(jiān)控與回放功能
vue+springboot的項目,需要在頁面展示出??档挠脖P錄像機(jī)連接的攝像頭的實時監(jiān)控畫面以及回放功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2022-02-02
vue實現(xiàn)登錄數(shù)據(jù)的持久化的使用示例
在Vue.js中,實現(xiàn)登錄數(shù)據(jù)的持久化需要使用瀏覽器提供的本地存儲功能,Vue.js支持使用localStorage和sessionStorage來實現(xiàn)本地存儲,本文就來介紹一下如何實現(xiàn),感興趣的可以了解一下2023-10-10

