Vue中實(shí)現(xiàn)路由跳轉(zhuǎn)傳參的4種方式
前言
本文詳盡的講了在Vue項(xiàng)目中,如何實(shí)現(xiàn)路由跳轉(zhuǎn)傳參的4四種方式(2大路由跳轉(zhuǎn)方式,每種方式包括4種路由傳參實(shí)現(xiàn)形式),以及每種方式中實(shí)現(xiàn)路由跳轉(zhuǎn)包括路由傳參的方法的各種寫法,說實(shí)話,不能再詳細(xì)了!
一、使用vue-router構(gòu)造函數(shù)
vue-router 本質(zhì)是一個(gè)第三方的包,用的時(shí)候需要下載。
步驟 (7步法 ):
1. 下載 vue-router 模塊到當(dāng)前工程
yarn add vue-router
2. 在src/main.js中引入VueRouter函數(shù)
// 引入路由 import VueRouter from "vue-router";
3. 在src/main.js中使用Vue.use()方法注冊全局VueRouter
添加VueRouter到Vue.use()身上,注冊全局RouterLink和RouterView組件
// 注冊全局 Vue.use(VueRouter)
4. 在src/main.js中創(chuàng)建路由規(guī)則數(shù)組:路由字典 – 路徑和組件名對應(yīng)關(guān)系
什么是路由字典: 專門保存地址欄中相對路徑與組件對象之間對應(yīng)關(guān)系的一個(gè)數(shù)組。
創(chuàng)建路由字典(需要準(zhǔn)備切換的頁面組件)把準(zhǔn)備好的頁面組件導(dǎo)入到main.js中
const routes = [ { path: "/", redirect: "find", //默認(rèn)顯示推薦組件(路由的重定向) }, { path: "/find", name: "Find", component: Find, //二級路由 children: [ { path: "/", redirect: "recom", //默認(rèn)顯示推薦組件 }, { path: "ranking", //注意二級路由的路徑千萬不要加/ component: Ranking, }, { path: "songlist", component: SongList, }, ], }, { path: "/my", name: "My", component: My, }, { path: "/part", name: "Part", component: Part, }, { path: "*", //也可以寫為"/*" component: NotFound, //定義找不到已有組件時(shí)顯示404 }, ];
5. 在main.js中使用VueRouter構(gòu)造函數(shù)生成路由對象
什么是路由(器)對象: 專門負(fù)責(zé)監(jiān)控地址欄變化,并根據(jù)地址欄變化查找對應(yīng)組件,替換頁面中router-view的 核心對象
// 使用new調(diào)用VueRouter構(gòu)造函數(shù)創(chuàng)建路由對象并且傳入規(guī)則 const router = new VueRouter({ // routes, mode: "history", //路由模式(默認(rèn)為hash模式) });
番外:路由模式
(1) hash —— 即地址欄 URL 中的 # 符號
hash 模式下,僅 hash 符號之前的內(nèi)容會(huì)被包含在請求中,如 http://www.abc.com,因此對于后端來說,即使沒有做到對路由的全覆蓋,也不會(huì)返回 404 錯(cuò)誤。(2) history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState()方法
history 模式下,前端的 URL 必須和實(shí)際向后端發(fā)起請求的 URL 一致,如http://www.abc.com/book/id。如果后端缺少對 /book/id 的路由處理,將返回 404 錯(cuò)誤。
6. 在main.js中把路由對象注入到new Vue實(shí)例中
new Vue({ router, //導(dǎo)入路由對象 render: (h) => h(App), }).$mount("#app");
7. 用router-view作為掛載點(diǎn), 切換不同的路由頁面
當(dāng)?shù)刂窓谥衭rl的相對路徑切換時(shí),router對象會(huì)自動(dòng)獲得新的相對地址。自動(dòng)去routes中查找對應(yīng)的組件對象。最后用找到的組件對象代替<router-view>的位置。
router-view 實(shí)現(xiàn)路由內(nèi)容的地方,引入組件時(shí)寫到需要引入的地方。需要注意的是,使用vue-router控制路由則必須以router-view標(biāo)簽作為容器。(可以先引入根組件App.vue中進(jìn)行自測)
項(xiàng)目入口文件:main.js
// 導(dǎo)入Vue構(gòu)造函數(shù) import Vue from 'vue' import App from './App.vue'; // 導(dǎo)入路由VueRouter構(gòu)造函數(shù) import VueRouter from 'vue-router'; import Details from "../components/Details.vue"; import HellWold from "../components/HelloWorld.vue"; import Find from "../components/Find.vue"; import My from "../components/My.vue"; import Part from "../components/Part.vue"; import NotFound from "../components/NotFound.vue"; import Recom from "../components/two/Recom.vue"; import Ranking from "../components/two/Ranking.vue"; import SongList from "../components/two/SongList.vue"; // 生產(chǎn)提示 // 改成false是用來關(guān)閉開發(fā)者提示 Vue.config.productionTip = false //調(diào)用構(gòu)造函數(shù)Vue的use方法 傳入VueRouter構(gòu)造函數(shù) //作用是把VueRouter作為一個(gè)插件 全局插入到Vue中 Vue.use(VueRouter) // 創(chuàng)建路由規(guī)則:定義一個(gè)路由數(shù)組對象 var routes = [ /** *一個(gè)對象就對應(yīng)了一個(gè)路由 *path 就是路由的地址 *name 給路由起的名字 *component 具體跳轉(zhuǎn)的是哪個(gè)組件頁面 */ { // path: '/' 根頁面,表示已進(jìn)入就顯示的頁面 path: "/", // 路由重定向:redirect意味著重定向,當(dāng)瀏覽器訪問'/'根路徑時(shí),將會(huì)自動(dòng)重定向到'/find' redirect: "find", //默認(rèn)顯示推薦組件(路由的重定向) }, { path: "/find", name: "find", component: Find, children: [ { // Vue中如何實(shí)現(xiàn)路由跳轉(zhuǎn)時(shí)單頁面只含子路由的內(nèi)容? // 子路由的組件必定在上一級路由中的 router-view 中顯示,可以通過條件判斷,將父組件的內(nèi)容隱藏,或者導(dǎo)向新的頁面 path: "/", redirect: "recom", //默認(rèn)顯示推薦組件 }, { path: "recom", component: Recom, }, { path: "ranking", //注意二級路由的路徑千萬不要加斜杠/ component: Ranking, }, { path: "songlist", component: SongList, }, ], }, { path: "/my", name: "my", component: My, }, { path: "/part", name: "part", component: Part, }, { path: "/helloworld", name: "helloworld", component: HellWold, }, { path: "/details", name: "details", component: Details, }, { // path:'*' 必須要放最后 // path:'*' 表示上面的路由沒有匹配到,則進(jìn)入下面的頁面 path: "*", //也可以寫為"/*" name: "NotFound", component: NotFound, //定義找不到已有組件時(shí)顯示404 }, ]; // 實(shí)例化構(gòu)造函數(shù) VueRouter 產(chǎn)生一個(gè)實(shí)例化對象 // 并把上面的路由數(shù)組對象routes當(dāng)作參數(shù),以對象的方式傳給構(gòu)造函數(shù) VueRouter const router = new VueRouter({ routes, // 引入路由規(guī)則routes mode: "history", //路由模式(默認(rèn)為hash模式) }); // 掛載 /** * 在Vue的對象參數(shù)里面配置 el:"#app" 等于 .$mount('#app') * 都是用來掛載到id為#app的div上的 * 把路由實(shí)例化對象router配置在Vue中,作用是保證項(xiàng)目中 * 所有的vue文件都可以使用router路由的屬性和方法 */ new Vue({ router, // 注入路由對象 // render函數(shù)渲染DOM結(jié)構(gòu),創(chuàng)建虛擬節(jié)點(diǎn)VNode。會(huì)把所有vue文件渲染到App組件上件上 render: h => h(App), }).$mount('#app') // 若沒有配置el屬性,就需要使用$mount()函數(shù)手動(dòng)掛載,等同于el:"#app""#app"
番外:當(dāng)然,我們也可以在一個(gè)單獨(dú)的index.js文件里面創(chuàng)建路由字典以及路由器對象并將路由字典傳入路由器對象中中,比如,我們在src文件夾下,新建一個(gè)router文件夾,里面存放index.js。然后把index.js文件導(dǎo)入main.js即可。把路由文件項(xiàng)目入口文件main.js分開,是推薦的比較規(guī)范的做法。附:各個(gè)頁面文件代碼如下:
注意!在index.js文件中,不要忘記導(dǎo)入與路由字典對應(yīng)的各個(gè)頁面組件以及vue-router ,并且最后要加一句導(dǎo)出路由對象的代碼:export default router
vue腳手架項(xiàng)目結(jié)構(gòu),如下:
vue版本及安裝各依賴的版本情況,如下:
頁面組件之間的跳轉(zhuǎn)演示,如下:
路由文件——src/router/index.js
// 導(dǎo)入路由VueRouter構(gòu)造函數(shù) // 因?yàn)樯婕奥酚梢?guī)則以及路由器對象,所以需要引入VueRouter import VueRouter from "vue-router"; // 以下是各個(gè)頁面組件的引入 import Details from "../components/Details.vue"; import HellWold from "../components/HelloWorld.vue"; import Find from "../components/Find.vue"; import My from "../components/My.vue"; import Part from "../components/Part.vue"; import NotFound from "../components/NotFound.vue"; // 創(chuàng)建路由規(guī)則:定義一個(gè)路由數(shù)組對象 var routes = [ /** *一個(gè)對象就對應(yīng)了一個(gè)路由 *path 就是路由的地址 *name 給路由起的名字 *component 具體跳轉(zhuǎn)的是哪個(gè)組件頁面 */ { // path: '/' 根頁面,表示已進(jìn)入就顯示的頁面 path: "/", // 路由重定向:redirect意味著重定向,當(dāng)瀏覽器訪問'/'根路徑時(shí),將會(huì)自動(dòng)重定向到'/find' redirect: "find", //默認(rèn)顯示推薦組件(路由的重定向) }, { path: "/find", name: "find", component: Find, children: [ { // Vue中如何實(shí)現(xiàn)路由跳轉(zhuǎn)時(shí)單頁面只含子路由的內(nèi)容? // 子路由的組件必定在上一級路由中的 router-view 中顯示,可以通過條件判斷,將父組件的內(nèi)容隱藏,或者導(dǎo)向新的頁面 path: "/", redirect: "recom", //默認(rèn)顯示推薦組件 }, { path: "recom", component: Recom, }, { path: "ranking", //注意二級路由的路徑千萬不要加斜杠/ component: Ranking, }, { path: "songlist", component: SongList, }, ], }, { path: "/my", name: "my", component: My, }, { path: "/part", name: "part", component: Part, }, { path: "/helloworld", name: "helloworld", component: HellWold, }, { path: "/details", name: "details", component: Details, }, { // path:'*' 必須要放最后 // path:'*' 表示上面的路由沒有匹配到,則進(jìn)入下面的頁面 path: "*", //也可以寫為"/*" name: "NotFound", component: NotFound, //定義找不到已有組件時(shí)顯示404 }, ]; // 創(chuàng)建路由器對象 // 實(shí)例化構(gòu)造函數(shù) VueRouter 產(chǎn)生一個(gè)實(shí)例化對象 // 并把上面的路由數(shù)組對象routes當(dāng)作參數(shù),以對象的方式傳給構(gòu)造函數(shù) VueRouter const router = new VueRouter({ routes, mode: "history", //路由模式(默認(rèn)為hash模式) }); // 導(dǎo)出路由器對象 // 把實(shí)例化路由對象 router 默認(rèn)導(dǎo)出 export default router;
項(xiàng)目入口文件——src/main.js
// 導(dǎo)入vue構(gòu)造函數(shù) import Vue from 'vue' // 導(dǎo)入根組件——項(xiàng)目主組件,頁面入口文件,vue頁面資源的首加載項(xiàng) import App from './App.vue'; // 導(dǎo)入路由VueRouter構(gòu)造函數(shù) // 需要注冊全局VueRouter,所以引入VueRouter import VueRouter from 'vue-router'; // 導(dǎo)入路由文件 //導(dǎo)入router文件夾中的index.js中的router實(shí)例化對象 //一個(gè)文件夾里面只有一個(gè)index.js文件在腳手架中可以把./router/index.js簡寫為./router import router from './router' // 生產(chǎn)提示 // 改成false是用來關(guān)閉開發(fā)者提示 Vue.config.productionTip = false // 注冊全局VueRouter // 調(diào)用構(gòu)造函數(shù)Vue的use方法 傳入VueRouter構(gòu)造函數(shù) // 作用是把VueRouter作為一個(gè)插件 全局插入到Vue中 Vue.use(VueRouter) // 掛載div#app /** * 在Vue的對象參數(shù)里面配置 el:"#app" 等于 .$mount('#app') * 都是用來掛載到id為#app的div上的 * 把路由實(shí)例化對象router配置在Vue中,作用是保證項(xiàng)目中 * 所有的vue文件都可以使用router路由的屬性和方法 */ new Vue({ router, // 注入路由對象 // render函數(shù)渲染DOM結(jié)構(gòu),創(chuàng)建虛擬節(jié)點(diǎn)VNode。會(huì)把所有vue文件渲染到App組件上 render: h => h(App), }).$mount('#app') // 若沒有配置el屬性,就需要使用$mount()函數(shù)手動(dòng)掛載,等同于el:"#app"
項(xiàng)目根組件——src/App.vue
<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png" /> <HellWold></HellWold> <hr> <div id="nav"> <!--使用 router-link 組件進(jìn)行導(dǎo)航 --> <!--通過傳遞 `to` 來指定鏈接 --> <!--`<router-link>` 將呈現(xiàn)一個(gè)帶有正確 `href` 屬性的 `<a>` 標(biāo)簽--> <router-link to="/find">發(fā)現(xiàn)音樂</router-link> <router-link to="/my">我的音樂</router-link> <router-link to="/part">我的朋友</router-link> </div> <hr> <!-- 路由出口 --> <!-- 路由匹配到的組件將渲染在這里 --> <router-view></router-view> </div> </template> <script> import HellWold from "./components/HelloWorld.vue"; export default { name: "App", components: { HellWold, }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } #nav { display: flex; justify-content: space-around; } a { text-decoration: none; } </style>
頁面組件——Find.vue
<template> <div class="find">我是發(fā)現(xiàn)頁 <!-- 用于展示二級路由默認(rèn)路由Recom --> <!-- 進(jìn)入根路徑,自動(dòng)重定向到Find組件頁面,然后有重定向到二級默認(rèn)路由組件Recom --> <router-view></router-view> </div> </template> <script> export default{ name:"Find" }; </script> <style scoped> .find{ color: blue; font: italic 700 25px Arial; } </style>
頁面組件Find的二級默認(rèn)組件——Recom.vue
<template> <div class="recom"> <router-link to="/details">recom...</router-link> </div> </template> <script> export default { name: "Recom", }; </script> <style scoped> </style>
頁面組件Find的二級組件——Ranking.vue
<template> <div class="ranking"> <router-link to="/details">ranking...</router-link> </div> </template> <script> export default { name: "Ranking", }; </script> <style scoped></style>
頁面組件Find的二級組件——SongList.vue
<template> <div class="songList"> <router-link to="/details">songlist...</router-link> </div> </template> <script> export default { name: "SongList", }; </script> <style scoped> </style>
頁面組件——Details.vue
<template> <div class="details">我是詳情頁</div> </template> <script> export default { name: "Details", }; </script> <style scoped> .details { color: rgb(20, 220, 40); font: italic 700 25px Arial; } </style>
頁面組件——My.vue
<template> <div class="my">我是音樂頁 </div> </template> <script> export default{ name:"My" }; </script> <style scoped> .my{ color:rgb(20, 159, 113); font: italic 700 25px Arial; } </style>
頁面組件——Part.vue
<template> <div class="part">我是朋友頁 </div> </template> <script> export default{ name:"part" }; </script> <style scoped> .part{ color: crimson; font: italic 700 25px Arial; } </style>
頁面組件——HelloWorld.vue
<template> <div class="hello">如果我被App.vue導(dǎo)入,那么我就是App.vue的子組件</div> </template> <script> export default { name: "HelloWorld", created() {}, }; </script> <style scoped> .hello{ color:cornflowerblue; font: 700 25px Arial; } </style>
頁面組件——NotPage.vue
<template> <div class="NotFound">我是404頁</div> </template> <script> export default { name: "NotFound", }; </script> <style scoped> .NotFound{ color: crimson; font: normal 900 40px Arial; } </style>
二、實(shí)現(xiàn)路由跳轉(zhuǎn)2種方式:聲明式導(dǎo)航和編程式導(dǎo)航
?? 聲明式導(dǎo)航
在瀏覽器中,點(diǎn)擊鏈接實(shí)現(xiàn)導(dǎo)航的方式,叫做聲明式導(dǎo)航。例如:普通網(wǎng)頁中點(diǎn)擊 a標(biāo)簽鏈接。vue項(xiàng)目中點(diǎn)擊router-link標(biāo)簽鏈接都屬于聲明式導(dǎo)航。
聲明式路由導(dǎo)航,直接寫在html中,結(jié)構(gòu)簡單使用方便,但是只能放在<router-link>標(biāo)簽中使用,<router-link>標(biāo)簽會(huì)將路由轉(zhuǎn)成<a>標(biāo)簽,通過點(diǎn)擊跳轉(zhuǎn)路由,因此局限性也非常大。?? 編程式導(dǎo)航
在瀏覽器中,調(diào)用API方法實(shí)現(xiàn)導(dǎo)航的方式,叫做編程式導(dǎo)航。例如:普通網(wǎng)頁中調(diào)用location.href跳轉(zhuǎn)到新頁面的方式,屬于編程式導(dǎo)航。vue項(xiàng)目中編程式導(dǎo)航有this.$router.push(),this.$router.replace(),this.$router.go()。 參考資料:Vue路由跳轉(zhuǎn)方式
編程式路由導(dǎo)航,需要寫在js中,結(jié)構(gòu)也不算復(fù)雜,優(yōu)勢在于非常靈活,不受固定標(biāo)簽限制,可以在任意情景下轉(zhuǎn)跳路由。
實(shí)際應(yīng)用時(shí)可根據(jù)自身喜好決定使用哪種路由導(dǎo)航方式。
1、聲明式導(dǎo)航—router-link
router-link —聲明式路由,在頁面中調(diào)用—實(shí)現(xiàn)跳轉(zhuǎn)最簡單的方法
利用組件router-link創(chuàng)建a標(biāo)簽來定義導(dǎo)航鏈接,它是用來替代a標(biāo)簽的;
? router-link 是vue-router提供的一個(gè)全局組件;
? router-link實(shí)質(zhì)上最終會(huì)渲染成a鏈接,to屬性指定目標(biāo)地址等價(jià)于href屬性;
? router-link提供了聲明式導(dǎo)航高亮的功能(自帶類名);
1) 不帶參數(shù)
// 注意:router-link中鏈接如果是'/'開始就是從根路由開始,如果開始不帶'/',則從當(dāng)前路由開始。 // 1. 字符串屬性 to ————經(jīng)測試,以下2種寫法都是可以的 <router-link to='/find'> // 字符串 <router-link to='find'> // 字符串 // 2. 動(dòng)態(tài)屬性綁定 :to或v-bind:to ————————經(jīng)測試,以下4種寫法都是可以的 // :to="變量或js表達(dá)式" <router-link :to="'find'"> // 不要忘記加引號,字符串也是一個(gè)js表達(dá)式 // 對象格式,name,path都行, 建議用name <router-link :to="{name:'find'}"> <router-link :to="{path:'find'}"> <router-link :to="{path:'/find'}"> // 經(jīng)測試:有component參數(shù)時(shí)優(yōu)先router-link中配置的component,沒有時(shí)從js中配置取 <router-link :to="{path:'/find',component: Find}">
舉個(gè)栗子:
在控制臺開發(fā)者工具里檢查元素時(shí)會(huì)發(fā)現(xiàn)激活的類名,在樣式style中有定義高亮樣式,點(diǎn)擊時(shí)就會(huì)實(shí)現(xiàn)高亮效果
<template> <div> <div class="footer_wrap"> // router-link好處 : 自帶激活時(shí)的類名, 可以做高亮 <router-link to="/find">發(fā)現(xiàn)音樂</router-link> <router-link to="my">我的音樂</router-link> <router-link :to="'part'">我的朋友</router-link> </div> <div class="top"> <router-view></router-view> </div> </div> </template>
<router-link>組件支持用戶在具有路由功能的應(yīng)用中點(diǎn)擊導(dǎo)航。通過to屬性指定目標(biāo)地址,默認(rèn)渲染為帶有正確連接的<a>標(biāo)簽,可以通過配 置tag屬性生成別的標(biāo)簽。另外,當(dāng)目標(biāo)路由成功激活時(shí),鏈接元素自動(dòng)設(shè)置一個(gè)表示激活的css類名。
組件的屬性有:
to 、replace、 append、 tag、 active-class、 exact 、 event、 exact-active-class
<router-view> 是與router-link配合,用來渲染通過路由router-link映射過來的組件,當(dāng)路徑更改時(shí),<router-view> 中的內(nèi)容也會(huì)發(fā)生更改。
2) 攜帶參數(shù)
在跳轉(zhuǎn)路由時(shí), 可以給路由對應(yīng)的組件內(nèi)傳值 ——動(dòng)態(tài)路由傳參
在router-link上的to屬性傳參數(shù)值,有以下3種方式 :
方式一:路由屬性配置傳參,需進(jìn)行組件的路由規(guī)則配置
開啟 props=true 傳值
(1). 修改路由文件index.js中路由字典中的路由地址,允許傳參
{path:"/details/:變量名", component:Details, props:true},
(2) 跳轉(zhuǎn)時(shí),路徑: /details/變量值
<router-link to="/相對路徑/參數(shù)值" // 需要?jiǎng)討B(tài)獲取參數(shù)值時(shí),使用:to
(3). 下個(gè)頁面中如何獲得地址欄中的參數(shù)值:
a. 路由文件index.js中的props:true,意為讓地址欄中的參數(shù)值自動(dòng)變成當(dāng)前頁面組件的props中的一個(gè)屬性值
在 Details.vue 組件中通過 props 接收
export default { name:"details", props:['id'] //模板中便可以使用 {{id}} }
b. 下一個(gè)頁面中就可以用: props:[ "變量名" ]
(4). 坑: 一旦一個(gè)路徑配置/:變量名,則必須攜帶參數(shù)才能進(jìn)入該路徑。如果不帶參數(shù),將被禁止進(jìn)入!
方式二:query方式傳參,可以由name和path引入,無需配置組件的路由規(guī)則
配置路由格式:/path
,也就是普通配置。
傳遞的方式:對象中使用query的key作為傳遞方式。
傳遞后形成的路徑:/path?參數(shù)名=參數(shù)值
。
// query傳參數(shù) ————類似get,瀏覽器地址欄中顯示參數(shù) <router-link to="/find?id=1"> // 路由可不配置 <router-link :to="{name:'find', query: {id:1}}"> // 路由可不配置 <router-link :to="{path:'/find', query: {id:1}}"> // 路由可不配置 // html 取參 $route.query.id // script 取參 this.$route.query.id
新頁面參數(shù)獲取:通過$route.query.參數(shù)名
獲取傳遞的值
使用用 query 來傳參,這種方式是可以解決頁面刷新參數(shù)消失問題的,query這種方式可以理解為是 ajax 中的 get 方法,參數(shù)是直接在 url 后面添加的,參數(shù)是可見的,所以解決頁面刷新參數(shù)消失問題建議使用此方法來解決
方式三:params方式傳參,只能由name引入,需進(jìn)行組件的路由規(guī)則配置
- 配置路由格式:
/path/:參數(shù)變量
- 傳遞的方式:在path后面跟上對應(yīng)的值
- 傳遞后形成的路徑:
/path/參數(shù)值
// params傳參數(shù)————類似post,瀏覽器地址欄中不顯示參數(shù) <router-link to="/find/1"> // 字符串格式傳參 <router-link :to="{name:'find', params: {id:1}}"> // 只能用name // 路由配置 path: "/find/:id" 或者 path: "/find:id" // 不配置path ,第一次可請求,刷新頁面id會(huì)消失 // 配置path,刷新頁面id會(huì)保留 // html 取參 $route.params.id // script 取參 this.$route.params.id
新頁面參數(shù)獲取:通過 $route.params.參數(shù)名
獲取傳遞的值。
番外:vue-router中route-link的樣式
<router-link>是 vue-router 中的一個(gè)組件,在vue2.0中,替代了原來的v-link指令,它的作用就是相當(dāng)于 a 標(biāo)簽一樣的給路由做導(dǎo)航,事實(shí)上它也確實(shí)是默認(rèn)被渲染為 a 標(biāo)簽。關(guān)于它的詳細(xì)信息請看官方文檔:API 參考 | Vue Router
<router-link>這個(gè)組件接受以下屬性參數(shù),在這里我們說一說在使用中要注意的一些問題:
1. replace
添加這個(gè)屬性的路由在導(dǎo)航后不會(huì)留下 history 記錄,目測這是一個(gè)非常好用的屬性,可以解決以前煩死人的 history 問題,大幅提高用戶體驗(yàn)。
2. tag
route-link 會(huì)被默認(rèn)渲染為 a 標(biāo)簽,如果你想讓它渲染成其它的標(biāo)簽就可以使用 tag 屬性,這樣可以解決一些 a 標(biāo)簽的默認(rèn)樣式問題。
3. exact
設(shè)置了這個(gè)屬性的路由會(huì)被認(rèn)為是處于激活狀態(tài),最典型的應(yīng)用就是導(dǎo)航欄了,比如說一組5個(gè) tab,給第一個(gè) tab 設(shè)置這個(gè)屬性,那么它就是處于選中狀態(tài)。
4. active-class
鏈接激活時(shí)的類名,其實(shí)這個(gè)也是為了方便導(dǎo)航欄切換狀態(tài)的,設(shè)置這個(gè)屬性就可以讓鏈接在激活時(shí)自動(dòng)切換相應(yīng)的樣式。
5. router-link-active
這是一個(gè)類名,也是上面第四條屬性的默認(rèn)值,就是說鏈接在被激活時(shí)會(huì)自動(dòng)給加上這個(gè) class,所以就可以把這個(gè) class 寫在 style 里面,里面寫上導(dǎo)航在激活時(shí)的一些公共樣式,比如字體顏色,大小等。參考資料:vue.js學(xué)習(xí)之router-link
2、編程式導(dǎo)航
$router.push() ——函數(shù)里面調(diào)用:用JS代碼來進(jìn)行跳轉(zhuǎn)
跳轉(zhuǎn)到指定url路徑,并想history棧中添加一個(gè)記錄,點(diǎn)擊后退會(huì)返回到上一個(gè)頁面
1) 不帶參數(shù)
// 字符串格式 this.$router.push('/find') this.$router.push('find') // 對象格式 this.$router.push({name:'find'}) // name屬性不能斜杠/,因?yàn)樗皇潜硎疽粋€(gè)名字 // path屬性斜杠/可帶可不帶 this.$router.push({path:'/find'}) this.$router.push({path:'find'})
2) 攜帶參數(shù)
方式一:路由屬性配置傳參,需進(jìn)行組件的路由規(guī)則配置
(1). 修改路由文件index.js中路由字典中的路由地址,允許傳參
{path:"/details/:變量名", component:Details, props:true},
(2) 跳轉(zhuǎn)時(shí),路徑: /details/變量值
this.$router.push("/相對路徑/參數(shù)值")
(3). 下個(gè)頁面中如何獲得地址欄中的參數(shù)值:
a. 路由文件index.js中的props:true,意為讓地址欄中的參數(shù)值自動(dòng)變成當(dāng)前頁面組件的props中的一個(gè)屬性值
b. 下一個(gè)頁面中就可以用: props:[ "變量名" ]
(4). 坑: 一旦一個(gè)路徑配置/:變量名,則必須攜帶參數(shù)才能進(jìn)入該路徑。如果不帶參數(shù),將被禁止進(jìn)入!
方式二:query方式傳參,可以由name和path引入,無需配置組件的路由規(guī)則
配置路由格式:/path
,也就是普通配置。
傳遞的方式:對象中使用query的key作為傳遞方式。
傳遞后形成的路徑:/path?參數(shù)名=參數(shù)值
。
// query傳參數(shù) ————類似get,瀏覽器地址欄中顯示參數(shù) this.$router.push({name:'find',query: {id:'1'}}) // 不用路由配置 this.$router.push({path:'/find',query: {id:'1'}})// 不用路由配置 // html 取參 $route.query.id // script 取參 this.$route.query.id
新頁面參數(shù)獲取:通過$route.query.參數(shù)名
獲取傳遞的值
方式三:params傳參,只能由name引入,需進(jìn)行組件的路由規(guī)則配置
- 配置路由格式:
/path/:參數(shù)變量
- 傳遞的方式:在path后面跟上對應(yīng)的值
- 傳遞后形成的路徑:
/path/參數(shù)值
// params傳參數(shù)————類似post,瀏覽器地址欄中不顯示參數(shù) this.$router.push({name:'find',params: {id:'1'}}) // 只能用 name // 路由配置 path: "/find/:id" 或者 path: "/find:id" , // 不配置path ,第一次可請求,刷新頁面id會(huì)消失 // 配置path,刷新頁面id會(huì)保留 // html 取參 $route.params.id // script 取參 this.$route.params.id
params傳參時(shí),如果沒有在路由規(guī)則中定義參數(shù),也是可以傳過去的,同時(shí)也能接收到,但是一旦刷新頁面,這個(gè)參數(shù)就不存在了
新頁面參數(shù)獲取:通過 $route.params.參數(shù)名
獲取傳遞的值。
$router.replace()——用法同$router.push()
1) 跳轉(zhuǎn)到指定的URL,替換history棧中最后一個(gè)記錄,點(diǎn)擊后退會(huì)返回至上一個(gè)頁面。(A----->B----->C 結(jié)果B被C替換 A----->C)
2) 設(shè)置replace屬性(默認(rèn)值:false)的話,當(dāng)點(diǎn)擊時(shí),會(huì)調(diào)用router.replace(),而不是router.push(),于是導(dǎo)航后不會(huì)留下history記錄。
3) 即使點(diǎn)擊返回按鈕也不會(huì)回到這個(gè)頁面。加上replace: true時(shí),它不會(huì)向 history 添加新紀(jì)錄,而是跟它的方法名一樣——替換當(dāng)前的history記錄。
// 聲明式 <reouter-link :to="..." replace></router-link> // 編程式: router.replace(...) // push方法也可以傳replace this.$router.push({path: '/homo', replace: true}) this.$router.replace({ name: this.pageFrom, params: this.formData }) onConfirm: () => { this.$router.replace('/TravelManage') }
this.$router.go(n)
向前或者向后跳轉(zhuǎn)n個(gè)頁面,n可為正整數(shù)或負(fù)整數(shù)
該方法的參數(shù)n是一個(gè)整數(shù),意思是在 history 記錄中向前或者后退多少步,類似 window.history.go(n)
this.$router.go(1) // 類似history.forward() this.$router.go(-1) // 類似history.back()
編程式導(dǎo)航3種方式的區(qū)別
this.$router.push
跳轉(zhuǎn)到指定url路徑,并向history棧中添加一個(gè)記錄,點(diǎn)擊后退會(huì)返回到上一個(gè)頁面
this.$router.replace
跳轉(zhuǎn)到指定url路徑,但是history棧中不會(huì)有記錄,點(diǎn)擊返回會(huì)跳轉(zhuǎn)到上上個(gè)頁面 (就是直接替換了當(dāng)前頁面)
this.$router.go(n)
向前或者向后跳轉(zhuǎn)n個(gè)頁面,n可為正整數(shù)或負(fù)整數(shù)
三、query和params區(qū)別
用法上的區(qū)別:
query傳參方式可以配合path或是name來引入路由,而params只能用name來引入(如果使用path,接收參數(shù)頁面會(huì)是undefined!?。。邮諈?shù)都是類似的,分別是 this.$route.query.參數(shù)名和 this.$route.params.參數(shù)名 。
用 path 的時(shí)候,提供的 path 值必須是相對于根路徑的相對路徑,而不是相對于父路由的相對路徑,否則無法成功訪問。
url地址顯示與否:
query更加類似于我們ajax中的get傳參,頁面跳轉(zhuǎn)之后頁面 url后面會(huì)拼接參數(shù),類似?id=1,刷新頁面后參數(shù)id還在,會(huì)一直保留,也就是說,query傳參刷新頁面后可以保存。另外,非重要性的可以這樣傳, 密碼之類等重要數(shù)據(jù)還是要使用params,這樣數(shù)據(jù)安全。
query傳參,比較靈活,沒有條件約束隨時(shí)可以追加參數(shù),參數(shù)顯示在了參數(shù)(search)的位置,參數(shù)的辨識度更高,例如:/name,/name?username=tom。
params類似post,跳轉(zhuǎn)之后頁面 url后面不會(huì)拼接參數(shù),也就是說地址欄不顯示參數(shù)名稱id,但是有參數(shù)的值,如果刷新頁面后id會(huì)消失,也就是說,params傳參刷新后不會(huì)保存(除非在路由規(guī)則里配置對應(yīng)參數(shù):/path/:參數(shù)變量)
params傳參,正確使用時(shí)相對嚴(yán)謹(jǐn),對于沒有在動(dòng)態(tài)路由上定義的參數(shù)如果隨意增刪,會(huì)有數(shù)據(jù)丟失的風(fēng)險(xiǎn)。定義路由時(shí)就要考慮好路由參數(shù)定義。參數(shù)如果為字符串時(shí),辨識度會(huì)低于query的方式,例如:/name/:username,/name/tom。
需要特別注意的點(diǎn)
1. params是路由的一部分,必須要在路由后面添加參數(shù)名,也就是占位符。
2. query是拼接在url后面的參數(shù),沒有也沒關(guān)系。
3. params一旦設(shè)置在路由,params就是路由的一部分,如果這個(gè)路由有params傳參,但是在跳轉(zhuǎn)的時(shí)候沒有傳這個(gè)參數(shù),會(huì)導(dǎo)致跳轉(zhuǎn)失敗或者頁面會(huì)沒有內(nèi)容。
小結(jié):
query傳參:
直白的來說query相當(dāng)于get請求,name和path都行,通過this.$route.query獲取,頁面跳轉(zhuǎn)的時(shí)候,可以在地址欄看到請求的參數(shù)名以及參數(shù)值,刷新頁面,參數(shù)會(huì)一直保留。
params傳參:
params相當(dāng)于post請求,只能name,通過this.$route.params獲取,頁面跳轉(zhuǎn)的時(shí)候,參數(shù)名不會(huì)在地址欄中顯示,但是參數(shù)值會(huì)顯示,刷新頁面參數(shù)值丟失。(如果想要參數(shù)值即使刷新也會(huì)一直保留顯示在地址欄里,必須在路由字典中對應(yīng)的路由里使用冒號" : "來匹配對應(yīng)參數(shù),否則第一次可請求,雖然可以傳參,但刷新頁面參數(shù)值會(huì)消失)。
params傳參不適于需要刷新頁面,又要取值的情形。因此,解決頁面刷新導(dǎo)致數(shù)據(jù)丟失的問題,建議使用 query傳參,除此之外,也可以考慮使用 localStorage,sessionStorage來保存參數(shù),也可以使用vuex的store來保存。
番外:帶參數(shù)的動(dòng)態(tài)路由匹配
動(dòng)態(tài)路徑參數(shù),使用冒號 : 標(biāo)記。比如,當(dāng)一個(gè)路由被匹配時(shí),它的 params 的值將在每個(gè)組件中以 this.$route.params
的形式暴露出來, 你可以在同一個(gè)路由中設(shè)置有多個(gè) 路徑參數(shù),它們會(huì)映射到 $route.params
上的相應(yīng)字段。例如:
匹配模式 | 匹配路徑 | $route.params |
---|---|---|
/users/:username | /users/eduardo | { username: 'eduardo' } |
/users/:username/posts/:postId | /users/eduardo/posts/123 | { username: 'eduardo', postId: '123' } |
除了 $route.params
之外,$route
對象還公開了其他有用的信息,如 $route.query
(如果 URL 中存在參數(shù))、$route.hash
等。你可以在 API 參考中查看完整的細(xì)節(jié)。這個(gè)例子的 demo 可以在這里找到。
動(dòng)態(tài)路由很適合用于類似商品詳情頁的需求,商品詳情頁的頁面結(jié)構(gòu)都一樣,只是商品id的不同,然而id不同,詳情頁渲染出的結(jié)果不一樣,所以這個(gè)時(shí)候就可以用動(dòng)態(tài)路由。
vue官方參考資料:帶參數(shù)的動(dòng)態(tài)路由匹配 | Vue Router
四、router、routes、route的區(qū)別
1. router:指的是路由實(shí)例。如:路由編程式導(dǎo)航的this.$ router.push( )也能進(jìn)行跳轉(zhuǎn),這個(gè)方法則會(huì)向history里面添加一條記錄,當(dāng)點(diǎn)擊瀏覽器回退按鈕或者this.$ router.back()就會(huì)回退之前的url。而this.$router.back(-1)就是返回上一個(gè)路由。
2. routes:指創(chuàng)建路由實(shí)例的配置項(xiàng)。用來配置多個(gè)route路由對象。routes出現(xiàn)在router文件夾下的index.js文件里,如下圖:
就是我們在routes里進(jìn)行路由配置,我們發(fā)現(xiàn)routes里對象里的component屬性值既可以寫成組件名,也可以直接( )=>import(路徑)寫入,這兩種寫法都是可以的,只不過后一種方法就不用再在上面單獨(dú)import…from…引入了。 一般是在懶加載時(shí)采用該方式,也就是說暫時(shí)不要把該組件import進(jìn)程序中,在路由字典routes中定義,只有當(dāng)用戶訪問到某個(gè)組件時(shí),才動(dòng)態(tài)引入這個(gè)組件。
3. route:路由對象。如:this.$route指的就是當(dāng)前路由對象,可以從對象里面獲取name,path,params,query,hash等。
小結(jié):route, routes, router
?1. router: 用new VueRouter()創(chuàng)建出的路由器對象
a. 監(jiān)視地址欄變化 ;b. 還可以執(zhí)行跳轉(zhuǎn)動(dòng)作!
$router 是“路由實(shí)例”對象包括了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等。——如$router.push( )
2. routes: 一個(gè)路由字典數(shù)組,包含當(dāng)前網(wǎng)站中所有路徑與組件的對應(yīng)關(guān)系列表。
routes會(huì)被裝入new VueRouter()即路由器對象router中,和router對象一起發(fā)揮作用!
3. route: 一個(gè)路由地址,代表當(dāng)前地址欄中的url信息,像BOM中的location。如地址欄:http://127.0.0.1:5500/index.html#/details ?
$route 是“路由信息對象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息參數(shù) ——如$route. Params. Userid 獲取參數(shù)傳遞的值
番外:Vue-router跳轉(zhuǎn)和location.href有什么區(qū)別
使用 location.href= /url 來跳轉(zhuǎn),簡單方便,但是刷新了頁面;
使用 history.pushState( /url ) ,無刷新頁面,靜態(tài)跳轉(zhuǎn);
引進(jìn) router ,然后使用 router.push( /url )來跳轉(zhuǎn),使用了diff 算法,實(shí)現(xiàn)了按需加載,減少了 dom 的消耗。其實(shí)使用 router 跳轉(zhuǎn)和使用 history.pushState() 沒什么差別的,因?yàn)関ue-router就是用了 history.pushState() ,尤其是在history模式下
番外:vue項(xiàng)目中跳轉(zhuǎn)到外部鏈接方法
在項(xiàng)目文件中,如果是vue頁面中的內(nèi)部跳轉(zhuǎn),在js中用this.$router.push(“/相對地址”)或是this.$router.resolve(“/相對地址”)可以實(shí)現(xiàn)
例如:
this.$router.push({path:'/channeldetailview',query: {channelid:this.data.id}});
或是 在html中使用
<router-link to="/相對地址">內(nèi)容</router-link>
在vue中使用this.$router.push(“/相對地址”) 或 this.$router.resolve(“/相對地址”),都可實(shí)現(xiàn)跳轉(zhuǎn)新頁面,那vue中這兩種打開新頁面的方式之間有什么區(qū)別呢?
實(shí)際上,這兩種方式的區(qū)別如下:
$router.push()方法是一個(gè)可以直接實(shí)現(xiàn)鏈接跳轉(zhuǎn)的方法,即在vue中它可以直接在當(dāng)前頁面打開新的路由(僅能在當(dāng)前頁面打開)并加載組件。返回一個(gè)Promise對象
$router.resolve()方法本身不能直接實(shí)現(xiàn)鏈接跳轉(zhuǎn),需要借助直接window全局對象中的打開鏈接的方法,例如open()方法才能實(shí)現(xiàn),然后根據(jù)open方法的name屬性的屬性值_self或是_blank來選擇是當(dāng)前頁面打開鏈接并加載組件還是打開新的標(biāo)簽頁并加載組件。返回的對象,如下圖:
舉個(gè)梨子:this.$router.resolve() 打開新窗口跳轉(zhuǎn)
通過path形式跳轉(zhuǎn)
goTo() { let routeData = this.$router.resolve({ path: "/details", }); window.open(routeData.href, "_blank"); }
? 通過name形式跳轉(zhuǎn)
goTo() { let routeData = this.$router.resolve({ name: "details", }); window.open(routeData.href, "_blank"); }
<template> <div class="recom"> <router-link to="/details">recom...</router-link> <button @click="goTo">我是一個(gè)按鈕</button> </div> </template> <script> export default { name: "Recom", methods: { goTo() { // 1、$router.push()可直接實(shí)現(xiàn)從當(dāng)前頁面打開鏈接,不能實(shí)現(xiàn)新標(biāo)簽頁面打開鏈接 // this.$router.push({ path: "/details"}) // 2.$router.resolve()配合window全局對象中的打開鏈接的方法,實(shí)現(xiàn)鏈接跳轉(zhuǎn) let routeData = this.$router.resolve({ path: "/details" // name: "details" }); console.log(routeData) window.open(routeData.href, "_blank"); }, }, }; </script> <style scoped> </style>
跳到外部鏈接,不能用這個(gè)。不然就會(huì)報(bào)錯(cuò),看一下鏈接的路徑,原來外部鏈接前面加上了http://localhost:8080/#/這一串導(dǎo)致跳轉(zhuǎn)出現(xiàn)問題,那么我們?nèi)绾翁D(zhuǎn)到外部鏈接呢?
① 我們只需用 window.location.href = url 來實(shí)現(xiàn)——直接在方法里面寫
window.location.
② 綁定事件處理函數(shù)
view界面中
<button @click="search">我的個(gè)人主頁</button>
methods對象中
methods: { search() { window.location. } }
在當(dāng)前窗口打開新連接
可后退:以下3個(gè)方法等價(jià)
① window.location.assign("新url") ;② window.location.href="新url";③ window.open("url", "_self"禁止后退:
js: location.replace("新url")
在新窗口打開,可打開多個(gè):
window.open("url", "_blank");在新窗口打開,只能打開一個(gè):
window.open("url", "自定義的窗口名");
以上就是Vue中實(shí)現(xiàn)路由跳轉(zhuǎn)傳參的4種方式的詳細(xì)內(nèi)容,更多關(guān)于Vue路由跳轉(zhuǎn)傳參的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
element基于el-form智能的FormSmart表單組件
本文主要介紹了element基于el-form智能的FormSmart表單組件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04vue-router實(shí)現(xiàn)簡單vue多頁切換、嵌套路由、路由跳轉(zhuǎn)的步驟和報(bào)錯(cuò)
最近學(xué)習(xí)到VUE路由這塊,發(fā)現(xiàn)這塊知識點(diǎn)有點(diǎn)多,好容易混亂,這篇文章主要介紹了vue-router實(shí)現(xiàn)簡單vue多頁切換、嵌套路由、路由跳轉(zhuǎn)的步驟和報(bào)錯(cuò)的相關(guān)資料,需要的朋友可以參考下2024-05-05Vue動(dòng)態(tài)引用json數(shù)據(jù)的兩種方式
在 Vue 項(xiàng)目中引用 JSON 文件非常簡單,尤其是當(dāng)文件內(nèi)容是一個(gè)數(shù)組時(shí),本文給大家介紹了Vue動(dòng)態(tài)引用json數(shù)據(jù)的兩種方式,并有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2025-04-04解決vue的router組件component在import時(shí)不能使用變量問題
這篇文章主要介紹了解決vue的router組件component在import時(shí)不能使用變量問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Vue報(bào)錯(cuò)ERR_OSSL_EVP_UNSUPPORTED解決方法
Vue項(xiàng)目啟動(dòng)時(shí)報(bào)錯(cuò)ERR_OSSL_EVP_UNSUPPORTED,本文主要介紹了Vue報(bào)錯(cuò)ERR_OSSL_EVP_UNSUPPORTED解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08Vue?Echarts實(shí)現(xiàn)多功能圖表繪制的示例詳解
作為前端人員,日常圖表、報(bào)表、地圖的接觸可謂相當(dāng)頻繁,今天小編隆重退出前端框架之VUE結(jié)合百度echart實(shí)現(xiàn)中國地圖+各種圖表的展示與使用;作為“你值得擁有”專欄階段性末篇,值得一看2023-02-02