vue-router详尽:编程式导航、路由重定向、动态路由匹配、路由别名、嵌套路由、命名视图
vue-router編程式導航
?
在vue項目中經常用到this.$router.push() 和 this.$router.replace() 方法進行路由跳轉就是編程式導航。。。
通俗理解編程式導航:通過操作$router實例的JavaScript代碼實現路由跳轉。點擊?<router-link :to="...">?等同于調用?router.push(...)。$router實例的方法有push()、replace()、go()方法,也可以進行路由傳參。
先上代碼簡單入手看效果:
?
demo基于vue-cli創建的,項目結構如圖:
第一步:定義路由文件 router >index.js如下
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld'import home from '@/components/Home' //引入組件Vue.use(Router)export default new Router({routes: [{path: '/',name: 'HelloWorld',component: HelloWorld},{path: '/home', //可以定義路由路徑、命名、組件、參數、別名、重定向name: 'home',component: home}, ] })第二步:helloWorld頁面使用聲明式和編程式導航到home組件的按鈕,helloWorld組件如下
<template><div class="hello"><h1>{{ msg }} 頁面</h1><router-link to="/home">聲明式使用router-link路由導航到home頁面</router-link><br><button @click="pushToHome()">js編程式push方法導航到home頁面</button><button @click="replaceToHome()">js編程式replace方法導航到home頁面</button><br><button @click="goNext()">js編程式go方法導航到history記錄的下一個頁面</button><router-view></router-view></div> </template><script> export default {name: 'HelloWorld',data () {return {msg: 'Welcome to HelloWorld' }},methods:{pushToHome:function(){this.$router.push("/home",function(){ //push()方法的使用,包括導航成功或失敗的回調函數console.log("導航成功的回調函數");},function(){console.log("導航中止的回調函數");}); },replaceToHome:function(){ //replace()方法的使用this.$router.replace("/home"); },goNext:function(){ //go()方法的使用this.$router.go(1); }} } </script><!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> button {margin:10px; } </style>第三步驟頁面:home組件中可以使用router.go(-1) 返回到上一個歷史記錄中的頁面;無記錄時點擊無效。home組件如下
<template><div class="hello"><h1>{{ msg }}</h1><button @click="goBack()">js編程式go方法返回history頁面</button></div> </template><script> export default {name: 'Home',data () {return {msg: 'Welcome to Home 主頁!!!!' }},methods:{goBack:function(){this.$router.go(-1); }} } </script><style scoped> h1, h2 {color:red; } </style>?
router.push(location, onComplete, onAbort)方法
1、router.push() 方法,參數分別指的是導航到?新的url、導骯完成的回調函數、導航中止的回調函數?;
2、router.push() 方法?會向history棧添加一個新的記錄?,所以當用戶點擊瀏覽器后退按鈕時,則回到之前的 URL。
3、router.push(location)方法使用
//使用路由的path值 this.$router.push("/router1");//使用包含路由path鍵值的對象 this.$router.push({path:'/router1'});//使用包含路由name鍵值的對象 this.$router.push({name:'routerNum1'});//使用包含name鍵值和params參數對象的對象, //注意:該方式params傳參瀏覽器頁面不在url中顯示參數,但是會頁面刷新的時候丟失參數 this.$router.push({name:'routerNum1',params:{userId:123}}); //path鍵值結合params的形式傳參無效 this.$router.push({path:'/router1',params:{userId:123}});//可以使用path鍵值結合query的形式傳參 this.$router.push({path:'/router1',query:{userId:123}});//使用path值拼接參數來傳參,注意這里使用的不是單引號!!! const userId=123; this.$router.push({path:`/router1/${userId}`});?4、 push()編程式導航注意點:
const userId = 1231、router.push({ path: `/router1/${userId}` }) // 注意使用反引號2、router.push({ path: '/router1', params: { userId }}) // 注意path鍵值結合params傳參無效3、router.push({ name: '/routerNum1', params: { userId }}) // 注意該方式在瀏覽器url不顯示參數,但是頁面刷新會導致參數丟失?
4、小demo使用驗證如下:
第一步:定義路由文件 router >index.js如下
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld'import home from '@/components/Home' import router1 from '@/components/Router1' import router2 from '@/components/Router2'Vue.use(Router)export default new Router({routes: [{path: '/',name: 'HelloWorld',component: HelloWorld},{path: '/home', name: 'home',component: home},{path: '/router1',name: 'routerNum1',component: router1},{path: '/router2',name: 'routerNum2',component: router2}, ] })第二步:home.vue組件文件代碼如下。
<template><div class="hello"><h3>{{ msg }}</h3><button @click="goBack()">js編程式go方法返回history頁面</button><hr><h3>js編程式導航中push方法的使用:</h3><button @click="pathTo()">push方法的url參數使用path值導航</button><button @click="pathObjectTo()">push方法的url參數使用path對象導航</button><br><button @click="nameObjectTo()">push方法,包含路由命名name鍵值的對象導航</button><br><button @click="nameParamTo()">push方法,包含路由命名name鍵值的對象結合params傳參</button><br><button @click="pathParamTo()">push方法,path鍵值對象導航結合params傳參,參數傳遞失敗</button><button @click="pathQueryTo()">push方法,path鍵值對象導航結合query傳參</button><br><button @click="pathandTo()">push方法,path值拼接參數來傳參</button></div> </template><script> export default {name: 'Home',data () {return {msg: 'Welcome to Home 主頁!!!!' }},methods:{goBack:function(){this.$router.go(-1); },pathTo:function(){ //使用路由的path值this.$router.push("/router1");},pathObjectTo:function(){ //使用包含路由path鍵值的對象this.$router.push({path:'/router1'});},nameObjectTo:function(){ //使用包含路由name鍵值的對象this.$router.push({name:'routerNum1'});},nameParamTo:function(){ //使用包含name鍵值和params參數對象的對象this.$router.push({name:'routerNum1',params:{userId:123}}); },pathParamTo:function(){ //path鍵值結合params的形式傳參無效this.$router.push({path:'/router1',params:{userId:123}}); },pathQueryTo:function(){ //可以使用path鍵值結合query的形式傳參this.$router.push({path:'/router1',query:{userId:123}}); },pathandTo:function(){const userId=123;this.$router.push({path:`/router1/${userId}`}); }} } </script><style scoped> h1, h2 {color:red; } </style>第三步:router1.vue組件代碼如下,使用this.$route.params.paramName或query.queryName接收路由傳的參數。
<template><div class="hello"><h3>{{ msg }}</h3><button @click="goBack()">js編程式go方法上一個路由頁面</button><p>{{fromRouterParams}}</p><p>{{fromRouterQuery}}</p></div> </template><script> export default {name: 'Router1',data () {return {msg: 'Welcome to Router1' ,fromRouterParams:this.$route.params.userId,fromRouterQuery:this.$route.query.userId,}},methods:{goBack:function(){this.$router.go(-1); },} } </script><style scoped> h1, h2 {color:red; } </style>
router.replace(location, onComplete, onAbort)方法
跟?router.push?很像,唯一的不同就是,它不會向 history 添加新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄;
?
router.go(n)方法
1、參數是一個整數,意思是在 history 記錄中向前或者后退多少步,類似?window.history.go(n)。?Browser History APIs點擊了解更多
2、使用:
// 在瀏覽器記錄中前進一步,等同于 history.forward() router.go(1)// 后退一步記錄,等同于 history.back() router.go(-1)// 前進 3 步記錄 router.go(3)// 如果 history 記錄不夠用,那就默默地失敗唄 router.go(-100) router.go(100)Vue Router 的導航方法 (push、?replace、?go) 在各類路由模式 (history、?hash?和?abstract) 下表現一致。
?
路由重定向:
路由配置{ path: '/a', redirect: '/b' },路由重定向是指當用戶訪問?/a時,路由跳轉到b路由,URL 將會被替換成?/b
1、在路由配置文件 router >index.js上使用:
const router = new VueRouter({routes: [{ path: '/router1', redirect: '/router2' }, //是從 /route1 重定向到 /router2{ path: '/b', redirect: {name:'foo'} }, //重定向的目標也可以是一個命名的路由{ path: '/c', redirect:(to)=>{// 方法接收 目標路由 作為參數// return 重定向的 字符串路徑/路徑對象//注意:導航守衛應用在導航跳轉目標to上}},] })2、注意在給路由設置有路由重定向時,再使用的路由導航會應用在跳轉to指向的路由上,如下路由router1上的導航守衛無效
{path: '/router1',redirect: '/router2',name: 'routerNum1',component: router1,beforeEnter:(from,to,next)=>{ //導航守衛無效console.log("在路由1上進行重定向"); next();}},{path: '/router2',name: 'routerNum2',component: router2,beforeEnter:(from,to,next)=>{console.log("進入到了路由2");next();}},3、重定向指向自身會報錯:[Vue warn]: Error in beforeCreate hook: "RangeError: Maximum call stack size exceeded,使用動態路徑參數傳參除外
?
路由別名
路由別名可以理解為路由的 '小名',可以使用路由別名進行路由導航
路由 /router2 的別名 alias 為 /secondRouter ,那么使用別名訪問 /secondRouter 時,url是/secondRouter,導航跳轉到路由 /router2 ,如下
{path: '/router2', name: 'routerNum2', alias:'/secondRouter',component: router2 },?
動態路由匹配:
使用情況:
1、如果導航目的地和當前路由相同,只有參數發生了改變 (比如從一個用戶資料到另一個?/users/1?->?/users/2),需要組件復用,組件復用意味著組件的生命周期鉤子函數不會被調用!
2、或者所有路由映射到同一個組件模式渲染,只是參數不同時。那么,我們可以在?vue-router?的路由路徑中使用“動態路徑參數”(dynamic segment) 來達到這個效果:
動態路徑參數的使用
第一步:動態路徑參數的使用需要在路由配置文件上使用冒號開頭的形式
{//動態路徑參數的使用 冒號開頭//那么像/router1/1 和/router1/2都將跳轉到該路由頁面path: '/router1/:userNum', name: 'routerNum1',component: router1,},第二步:使用this.$router.push({path:? `/router1/${userNum1}` }); 形式進行動態路徑傳參,注意反引號,url中的參數不會刷新丟失
<template><div class="hello"><h3>{{ msg }}</h3><button @click="goBack()">js編程式go方法返回history頁面</button><hr><h3>js動態路由匹配的使用:</h3><button @click="pathParam1To()">動態路徑參數1導航</button><button @click="pathParam2To()">動態路徑參數2導航</button><hr><button @click="diffParamsTo()">導航到當前組件(組件復用),但傳遞的參數不同</button></div> </template><script> export default {name: 'Home',data () {return {msg: 'Welcome to Home 主頁!!!!' }},watch: {'$route' (to, from) {// 對路由變化作出響應...console.log('路由發生變化');console.log(this.$route.params.userNum);}},methods:{goBack:function(){this.$router.go(-1); },pathParam1To:function(){let userNum1=111111;this.$router.push({path:`/router1/${userNum1}`}); },pathParam2To:function(){let userNum2=222222;this.$router.push({path:`/router1/${userNum2}`}); },diffParamsTo:function(){let userNum2=666;this.$router.push({path:`/router1/${userNum2}`}); },} } </script><style scoped> h1, h2 {color:red; } </style>第三步:可以在路由組件中使用this.$route.params獲取動態路徑參數,如下
<p>{{this.$route.params.userNum}}</p>?
組件復用
復用組件時,想對路由參數的變化作出響應的話,你可以簡單地 watch (監測變化)?$route?對象:
watch: {'$route' (to, from) {// 對路由變化作出響應...console.log('路由發生變化');console.log(this.$route.params.userNum);}},也可以使用2.2中引入的 beforeRouteUpdate導航守衛來響應這個變化 (比如抓取用戶信息)。組件內導航守衛可以點擊了解
const User = {template: '...',beforeRouteUpdate (to, from, next) {// react to route changes...// don't forget to call next()} }?
嵌套路由
?嵌套路由指的是在渲染的路由組件頁面中包含了下級路由渲染出口(<router-view>),瀏覽器的URL 中各段動態路徑也按某種結構對應嵌套的各層組件,
在項目的app.vue 文件中<router-view>是最頂層的出口,渲染最高級路由匹配到的組件。
<div id="app"><router-view></router-view> </div>第一步:定義路由配置文件router >index.js,在路由上使用children屬性定義下級路由
import Vue from 'vue' import Router from 'vue-router' import helloWorld from '@/components/HelloWorld' import home from '@/components/Home' import book from '@/components/Book' import water from '@/components/Water'Vue.use(Router) export default new Router({routes: [{path: '/',component:helloWorld},{path: '/home',component: home,children:[{path:'', //當訪問的子路由路徑無匹配時會指向到該空的子路由component:water,},{path:'book',component:book,},{path:'water',component:water,},]},] })第二步:路由組件home.vue的內容,子路由導航包括了聲明式和編程式導航
<template><div class="hello"><h3>{{msg}}</h3><button @click="showBookRouter()">點擊按鈕顯示子路由頁面book</button><button @click="showWaterRouter()">點擊按鈕顯示子路由頁面water</button><br><router-link to="/home/book">book</router-link><router-link to="/home/water">water</router-link><router-link to="/home/">foo</router-link><router-view></router-view></div> </template><script> export default {name: 'Home',data () {return {msg: 'Welcome to Home !!!'}},methods:{showBookRouter:function(){this.$router.push('/home/book'); //編程式路由導航},showWaterRouter:function(){this.$router.push('/home/water');},} } </script><!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h3 {color:red; } </style>第三步:子組件book.vue 和water.book這里就不寫了
?
命名視圖
同時 (同級) 展示多個視圖,而不是嵌套展示,例如創建一個布局,有?sidebar?(側導航) 和?main?(主內容) 兩個視圖,這個時候命名視圖就派上用場了。你可以在界面中擁有多個單獨命名的視圖,而不是只有一個單獨的出口。如果?router-view?沒有設置名字,那么默認為?default。
<router-view class="view one"></router-view> <router-view class="view two" name="a"></router-view> <router-view class="view three" name="b"></router-view>一個視圖使用一個組件渲染,因此對于同個路由,多個視圖就需要多個組件。確保正確使用?components配置 (帶上 s):
{path: '/',components: {default: water,a: book,b: water}}?
參考網址:官網API?https://router.vuejs.org/zh/guide/essentials/navigation.html
總結
以上是生活随笔為你收集整理的vue-router详尽:编程式导航、路由重定向、动态路由匹配、路由别名、嵌套路由、命名视图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ATen(A TENsor librar
- 下一篇: html5倒计时秒杀怎么做,vue 设