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