您好,登錄后才能下訂單哦!
本篇內容主要講解“vue獲取參數的方式有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“vue獲取參數的方式有哪些”吧!
1.1.1 什么是SPA?
SPA(single-page application),只有一個HTML頁面,通過路由實現頁面內的局部切換,公共資源部分只加載一次。
我們熟知的JS框架如react,vue,angular,ember都屬于SPA。
1.1.2 什么是MPA(多頁面應用)
平常寫的普通頁面就是MPA,通過a標簽實現頁面切換,每次切換頁面都要重新加載公共資源部分。
1.1.3 SPA和MPA的區別
區別 | SPA | MPA |
---|---|---|
組成 | 一個外殼頁面和多個頁面片段組成 | 多個完整的頁面組成 |
公用資源(js,css,img) | 公用,只加載一次 | 每個頁面都需要加載 |
刷新方式 | 局部刷新 | 整體刷新 |
URL模式 | 哈希模式(a.com/#/page1)/歷史模式(a.com/page1) | 歷史模式 |
用戶體驗 | 用戶體驗好,頁面切換快 | 用戶體驗不好,頁面切換慢 |
轉場動畫 | 容易實現 | 無法實現 |
數據傳遞 | 容易 | 依賴URL或本地存儲 |
SEO | 實現比較困難 | 簡單 |
開發成本 | 難度高,需要借助專業的框架 | 難度低,但是重復代碼比較多 |
維護成本 | 相對比較低 | 相對比較高 |
1.1.4 SPA的優缺點
優點:
1,用戶體驗好,快,內容的改變不需要重新加載整個頁面,基于這一點spa對服務器壓力較小
2,前后端分離
3,頁面效果會比較炫酷(比如切換頁面內容時的專場動畫)
缺點:
1,不利于seo(搜索引擎優化(Search Engine Optimization,SEO)是一種通過了解搜索引擎的運行規則來調整網站,以提高目標網站在有關搜索引擎內排名的方式);
2,導航不可用,如果一定要導航需要自行實現前進、后退。(由于是單頁面不能用瀏覽器的前進后退功能,所以需要自己建立堆棧管理)
3,不支持低版本的瀏覽器,最低只支持到IE9
4,初次加載時耗時多
5,頁面復雜度提高很多
簡單舉例說明,假如我們有一臺提供 Web 服務的服務器的網絡地址是:10.0.0.1,而該 Web 服務又提供了三個可供用戶訪問的頁面,其頁面 URI 分別是:
http://10.0.0.1/ http://10.0.0.1/about http://10.0.0.1/concat
那么其路徑就分別是 /,/about,/concat。
當用戶使用 http://10.0.0.1/about 來訪問該頁面時,Web 服務會接收到這個請求,然后會解析 URL 中的路徑 /about,在 Web 服務的程序中,該路徑對應著相應的處理邏輯,程序會把請求交給路徑所對應的處理邏輯,這樣就完成了一次「路由分發」,這個分發就是通過「路由」來完成的。
簡單的說,路由是根據不同的 url 地址展示不同的內容或頁面。
路由的概念在軟件工程中出現,最早是在后端路由中實現的。服務器直接生產渲染好對應的HTML頁面, 返回給客戶端進行展示。
前端路由是如何做到URL和內容進行映射呢?監聽URL的改變。
1.3.1 URL的hash
URL的hash也就是錨點(#), 本質上是改變window.location的href屬性;我們可以通過直接賦值location.hash來改變href, 但是頁面不發生刷新;另外每次 hash 值的變化,還會觸發hashchange 這個事件,通過這個事件我們就可以知道 hash 值發生了哪些變化。然后我們便可以監聽hashchange來實現更新頁面部分內容的操作。
<div id="app"> <a href="#/home" rel="external nofollow" >home</a> <a href="#/about" rel="external nofollow" >about</a> <div id="router-view"></div> </div>
<script> const routerView = document.querySelector('#router-view'); // url的hash // URL的hash也就是錨點,本質上就是改變window.location 的 href 屬性 // 我們可以通過直接賦值location.hash 來改變 href 但是頁面不會刷新 window.addEventListener('hashchange',()=>{ console.log(location.hash); if(location.hash==="#/home"){ routerView.innerHTML = "home"; }else if(location.hash==="#/about"){ routerView.innerHTML = "about"; } }) </script>
hash的優勢就是兼容性更好,在老版IE中都可以運行,但是缺陷是有一個#,顯得不像一個真實的路徑。
1.3.2 HTML5的History
14年后,因為HTML5標準發布。多了兩個 API,pushState 和 replaceState,通過這兩個 API 可以改變 url 地址且不會發送請求。
通過這些就能用另一種方式來實現前端路由了,但原理都是跟 hash 實現相同的。用了 HTML5 的實現,單頁路由的 url 就不會多出一個#,變得更加美觀。但因為沒有 # 號,所以當用戶刷新頁面之類的操作時,瀏覽器還是會給服務器發送請求。
為了避免出現這種情況,所以這個實現需要服務器的支持,需要把所有路由都重定向到根頁面;
<div class="nav"> <a onclick="linkTo(1)">link1</a> <a onclick="linkTo(2)">link2</a> </div> <div id="router-view"> </div>
<script> var view = document.getElementById('router-view'); function linkTo(link){ switch(link) { case 1: { window.history.pushState({a:1}, 'mylink1', '/link1'); view.innerHTML = 'link1 content'; break; } case 2: { window.history.pushState({a:1}, 'mylink2', '/link2'); view.innerHTML = 'link2 conetnt'; break; } default: return; } return false; } </script>
通過vue的路由可實現多視圖的單頁面Web應用。VueRouter文檔
我們之前使用過is特性來實現動態組件,vue-router的實現原理與之類似。vue-router展示不同的頁面事實上就是動態加載不同的組件。
當我們的地址欄發生了變化,vue-router就會監聽到。根據它里面配置的匹配規則,展示不同的組件。
2.1.1 直接下載
VueRouter下載地址 : https://unpkg.com/vue-router/dist/vue-router.js
2.1.2 使用CDN地址
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
2.1.3 腳手架
在使用腳手架搭建項目時,選擇 Vue-router,項目創建好之后默認安裝vue-router。如果創建項目時,沒有選擇,也可以使用模塊化開發的方式。執行如下的命令來安裝Vue Router。
npm i vue-router
2.2.1 使用router-link組件來定義導航
在app.vue的template中修改成如下代碼
<template> <div> <!-- router-link相應于a標簽,to相當于href,指要單擊跳轉到顯示那個組件的內容 ,最終瀏覽器還是會把router-link解析為a標簽--> <router-link to="/about">關于我們</router-link> <router-link to="/news">新聞</router-link> </div> </template>
2.2.2 指定組件的渲染位置
通過router-view組件指定組件的渲染位置。
<template> <!-- ... --> <div class="container"> <!-- router-view指定顯示路由導航內容的位置,也就是單擊【關于我們】或【新聞】連接的內容都在router-view組件指定位置顯示 --> <router-view></router-view> </div> </template>
當單擊鏈接router-link的時候,會在router-view所在的位置渲染組件的模板內容。可以把router-view理解為占位符。
再準備好樣式
<style> .container { background-color:blanchedalmond; margin-top: 10px; width: 600px; height: 300px; } </style>
2.2.3 定義路由組件
也就是每個鏈接顯示的內容,這里只是演示前端路由的基本用法,所以組件定義很簡單。新建兩個文件 About.vue和News.vue
<template> <h4>關于我們</h4> </template>
<template> <h4>最熱新聞</h4> </template>
2.2.4 定義路由,創建路由實例
src目錄下新建一個router文件夾,如果創建項目時,已經選擇了Vue-router則會自動創建。創建index.js文件,代碼如下:
import Vue from 'vue' import VueRouter from 'vue-router' import Films from '@/components/About' import Cinemas from '@/components/News' // 注冊路由插件, 兩個全局 router-view router-link Vue.use(VueRouter) // 配置表,有多條路由時,通常定義為一個常量數組,里面每個對象就是一個路由 const routes = [ // 定義路由格式:path指定路由的url,component指定當單擊path指定的url時顯示哪個組件內容。 { path: '/about', component: About }, { path: '/news', component: News } ] //能new VueRouter就是因為引入了vue-router.js。 export default new VueRouter({ // routes:routes//左邊routes為要設置的路由選項routes,右邊routes為選項值,名字當然可以不同,但是一般設置為相同。第2步不單獨定義,直接寫在routes里也可以 routes, mode:'history', linkActiveClass:'active' });
2.2.5 掛載路由實例對象
在main的js中,掛在路由實例對象.
import router from './router' //創建vue根實例,并將上面的路由實例掛載到vue實例上,也稱為注入路由,就是告訴vue實例有這么一個路由了。 //怎么告訴呢?通過router選項 var vm = new Vue({ el: "#app", // router:router//同樣:左右兩邊名稱相同,可以簡寫 router//注入路由 })
上面的案例中,當我們切換路由時發現地址欄后面會自動再加一個“#”。為什么是這種顯示模式呢?因為在使用Vue Router創建路由實例時,默認采用的是hash路由配置模式。這種模式的優點是各種瀏覽器的兼容性比較好。
但是hash模式下url需要帶“#”符號,不僅看起來不舒服,而且有些場景下是會破壞路由中的"#"(微信分享頁面就會把"#"后邊的內容處理掉),所以我們可以將路由實例修改為history路由模式。只需要在創建路由實例時,設置mode選項為history即可。
const router = new VueRouter({ routes, mode:'history' })
這種history路由模式的缺點是URL兼容性不好,并且懼怕刷新。
觀察生成的HTML代碼,會發現在當前導航中多了兩個class類名。
<a class="router-link-exact-active rotuer-link-active">關于我們</a>
但是此類名并沒有設置樣式,需要自己手動設置具體樣式。
.rotuer-link-active{ font-size:20px; color:red; text-decoration: none; }
需要注意的是,樣式名取最后一個即可,這兩者的區別在后面學習嵌套路由時再說明。
另外,如果覺得系統默認樣式名太長,不好記憶可以進行修改。
在創建路由實例時,可通過linkActiveClass選項,設置樣式名。
const router = new VueRouter({ routes, mode:'history', linkActiveClass:'active' })
還有一個問題,不論哪種路由模式,剛打開頁面既沒有顯示【關于我們】的內容,也沒顯示【新聞】鏈接的內容。我們可以在配置路由時,在增加一個路由,作用是:找不到路由時,重定向到about。 可以理解為備胎,最后實在沒招了,就匹配備胎了。
const routes = [ { path: '/about', component: About }, { path: '/news', component: News }, {path:'*',redirect:'/about'}//*表示找不到路由時,重定向到about ]
【router-link】默認會轉為【a標簽】,實際上可以添加tag屬性來轉為指定的標簽,比如轉為【buttton標簽】或【li標簽】等。
<router-link to="/account/login" tag="button">登錄</router-link>
不過vue-router4.x 之后廢棄了 tag 而使用(v-solt)插槽來實現
<router-link custom to="/account/login" custom v-slot="{ isActive,navigate-}"> <buttton @click="navigate">我是路由自定義標簽</buttton> </router-link> <!-- custom 屬性的意思,就是允許自定義標簽,如果不寫就會定義成 a 標簽 navigate 導航的觸發函數 isActive 是否匹配的狀態 -->
如果全是用一級路由時,路由管理就變得很臃腫,有點亂,路由有父子關系的話,嵌套路由會更好。嵌套路由也就是路由中的路由的意思,組件中可以有自己的路由導航和路由容器(router-link、router-view),通過配置children可實現多層嵌套,在vue組件中使用<router-view>就可以了。
舉例:我們上面的例子中,添加一個books路由,單擊“圖書”鏈接,以列表的形式顯示所有圖書的書名,進一步單擊單個書名鏈接,在Books視圖中顯示圖書的詳細信息。
在asssets目錄下新建一個books.js文件,里面是圖書數據
export default [ {id: 1, title: '三體', desc: '三個天體在互相引力的作用下互相圍繞運行,其運行軌跡將產生不可預測的混沌。'}, {id: 2, title: '蛤蟆先生去看心理醫生', desc: '蛤蟆先生一向愛笑愛鬧,如今卻一反常態地郁郁寡歡。'}, {id: 3, title: '活著', desc: '人是為了活著本身而活著的,而不是為了活著之外的任何事物而活著。'} ]
這里只是為了演示需要,真實場景中,圖書數據應該是通過ajax請求從服務器端加載而來。
3.1.1. 在父組件中添加導航
修改Books.vue,以列表方式顯示圖書數據,添加導航鏈接,并使用【router-view】來指定book組件渲染的位置
<template> <div> <h4>圖書列表</h4> <ul> <li v-for="book in books" :key="book.id"> <router-link to="/books/book/">{{book.title}}</router-link> </li> </ul> <!--Book組件在這里渲染--> <router-view></router-view> </div> </template>
<script> import Books from '@/assets/books' export default { data(){ return {books:Books} } } </script>
3.1.2.添加子路由顯示的組件
新建Book.vue,代碼如下。
<template> <div> 圖書詳情頁面 </div> </template>
<script> export default { data(){ return { } } } </script>
3.1.3.配置父路由的children屬性
在router目錄下的index.js中修改代碼如下:
import Book from '@/components/Book' //... const routes = [ //... { path: '/books', component: Books, children: [ {path: 'book', component: Book} ] }, ]
(1)要在嵌套的出口(即Books組件中的router-view)中渲染組件,需要在routes選項的配置中使用children選項。children選項只是路由配置對象的另一個數組,如同routes本身一樣,因為,可以根據需要繼續嵌套配置。
(2)以‘/’開頭的嵌套路徑被視為根路徑。上面的子路由導航中,如果path是“/book”則會出錯。
完成以上步驟后,我們點擊圖書就可以看到進入圖書詳情頁面了,但是我們還需要在該頁面中看到點擊圖書的詳情信息,這就意味這我們需要將父組件Books.vue中的被點擊圖書的ID傳遞給Book.vue組件。
在進行表單提交、組件跳轉等操作時需要使用到上一個表單、組件中的一些數據。此時就需要將參數在路由間進行傳遞。
將需要的參數以 【key = value】的方式放在URL地址中。
book?id=1
這里的參數值“id”可以通過當前組件的表單輸入來獲取。
那么進入book組件后如何獲取傳入的參數呢?
當將實例化的VueRouter對象掛載到Vue實例后,Vue Router在Vue實例上創建了兩個屬性對象。即 r o u t e r ( r o u t e r 實 例 ) 和 router(router實例)和 router(router實例)和route(當前頁面的路由信息)。通過【this.$route.query】可以獲取query查詢參數。
<!-- book.vue --> <template> <h5>這里是Book頁面內容,獲取參數:{{this.$route.query}},圖書ID :{{this.$route.query.id}}</h5> </template> <script> export default { } </script>
我們也可以使用動態參數的方式傳遞參數,比如 【book/1】。那【1】分別代表什么?這個需要在路由中指明。
<router-link to="/books/book/1">注冊</router-link>
與query查詢參數不同的是,在定義路由信息時,需要以占位符【:參數名】的方式將需要傳遞的參數指定到路由地址中,否則系統不能識別傳遞的參數。
在路由中指定參數的含義,代碼如下:
children: [{ //books下的子路由 path: 'book/:id', component: Book }]
進入Book.vue組件時如何獲取傳遞過來的參數?這與獲取query參數的方式相同,可以通過【 r o u t e 】 獲 取 當 前 路 由 信 息 , 通 過 【 route】獲取當前路由信息,通過【 route】獲取當前路由信息,通過【route.params.參數名】的方式獲取動態參數。參數名也就是在路由中設置的參數名(/:后面的)
<!-- book.vue --> <template> <h5>這里是Book頁面內容,獲取參數:{{this.$route.params}},圖書ID :{{this.$route.params.id}}</h5> </template> <script> export default { } </script>
路由對象還有其他屬性,如【$route.path】,可以獲取當前路由的路徑。
<!-- book.vue --> <template> <h5>這里是Book頁面內容,獲取參數:{{this.$route.params}},圖書ID :{{this.$route.params.id}},路由路徑{{$route.path}}</h5> </template> <script> export default { } </script>
接下來實現在Book.vue組件中顯示點擊書籍的詳細信息。
修改Books.vue代碼如下:
<!-- 注意 to屬性使用了數據綁定,才可以使用動態的book.id --> <router-link :to="'/books/book/'+book.id">{{book.title}}</router-link>
修改book.vue代碼如下:
<template> <div> <p>圖書ID:{{ book.id }}</p> <p>書名:{{ book.title }}</p> <p>說明:{{ book.desc }}</p> </div> </template>
<script> import Books from '@/assets/books' export default { data(){ return { book: {} } }, //寫在created中是為了模擬ajax請求。 created(){ this.book = Books.find((item) => item.id == this.$route.params.id); } } </script>
實際場景中,當單擊某本圖書鏈接時,應該向服務器端發起Ajax請求來獲取圖書詳細數據,于是我們想到在Book組件中通過生命周期鉤子函數來實現,然而,這行不通。這是因為當兩個路由都渲染同一個組件時,例如,從book/1導航到book/2時,vue會復用先前的Book實例,比起銷毀舊實例再創建新實例,復用會更加高效。但是這就意味著組件的生命周期鉤子不會再被調用,所以也就無法在生命周期鉤子中根據路由參數的變化來實現更新數據。
要對同一組件中的路由參數更改作出響應,只需監聽$route對象。當路由參數變化時,更新圖書詳細數據。
Book.vue代碼修改如下:
created(){ this.book = Books.find((item) => item.id == this.$route.params.id); }, watch: { '$route' (to) { this.book = Books.find((item) => item.id == to.params.id); } }
(1)只有路由參數發生變化時, route 對象的監聽器才會被調用 ,這意味著第一次渲染Book組件時 ,通過 route對象的監聽器才會被調用,這意味著第一次渲染Book組件時,通過 route對象的監聽器才會被調用,這意味著第一次渲染Book組件時,通過route對象的監聽器是得不到數據的,因此利用created鉤子來獲取第一次渲染時的數據,當然,也可以利用immediate選項,將其值設為true,讓監聽器在監聽開始后立即執行,這樣就不需要created鉤子了。
watch: { '$route': { handler: function(to) { this.book = Books.find((item) => item.id == to.params.id); }, immediate: true } }
(2)$route對象的監聽器函數中的to參數表示即將進入的目標路由對象,該函數還可以帶一個from參數,表示當前導航正要離開的路有對象。
除了監聽$route對象,還可以用到后面要學習的導航守衛。這個以后再說。
Vue-router路由分為兩種:
聲明式路由編程式路由
聲明式導航是寫在template標簽里,通過標簽來觸發
編程式導航寫在js里,通過this.$router.push(xxx)來觸發路徑
前面例子中通過在頁面上設置【router-link】標簽進行路由地址間的跳轉,就等同于執行push方法。
push方法會將一條心的路由記錄添加到瀏覽器的history棧中,通過history的自身特性,驅使瀏覽器進行頁面的跳轉。同時,因為在history會話歷史中會一直保留這個路由信息,所以當后退時還是可以返回到當前的頁面。
在push方法中,參數可以使一個字符串路徑,或者是一個描述地址的對象。
this.$router.push('/account/register') this.$router.push({path:'/account/register'})
如果帶參數的話,對象方式可以通過query屬性來指定參數。
this.$router.push({ //想跳到哪里就設置相應的路由,并傳遞參數信息。比如跳到注冊頁面/account/register也行 path:'/account/login',query:{name:this.name,pwd:this.pwd} })
需求:在登錄頁面中提供用戶名和密碼輸入框以及【提交】按鈕,點擊【提交】按鈕在注冊頁面中顯示出用戶名和密碼信息。
1.添加tmplogin模板
<template id="tmplogin"> <form action=""> <div> <h5>歡迎來到登錄頁面,請輸入登錄信息</h5> 用戶名:<input type="text" name="name" v-model="name" /><br> 密碼:<input type="password" name="pwd" v-model="pwd" /><br> <input type="submit" value="提交" @click="submit"> </div> </form> </template>
2.定義組件對象
const login = { template: '#tmplogin', data: { return: { name: '', pwd: '' } }, methods: { submit() { this.$router.push({ //想跳到哪里就設置相應的路由,并傳遞參數信息。比如跳到注冊頁面/account/register也行 path:'/account/register',query:{name:this.name,pwd:this.pwd} }) } }, } const register = { template: '<h5>這里是注冊頁面內容,獲取傳遞的參數:{{$route.params}},用戶名:{{$route.params.name}},密碼:{{$route.params.pwd}},路由路徑{{$route.path}}</h5>' }
3.在路由中進行配置
children: [{ //account下的子路由 path: 'login', component: login }]
replace方法同樣可以實現路由跳轉的目的。不過,從名字上也可以看出,與使用push方法跳轉不同的是,當使用replace方法時,并不會往history棧中新增一條新的記錄,而是會替換當前的記錄,因此無法通過后退按鈕返回被替換前的頁面。
需求:在賬戶頁面下添加一個【替換路由】按鈕,點擊后跳轉到新聞頁面。
1.tempaccount模板添加button按鈕。
<button @click="replace">替換路由</button>
2.在Account組件下,綁定對應方法。
var Account = { template: '#tmpaccount', //這里模板內容變復雜了,所以單獨定義 methods:{ replace(){ this.$router.replace({ path:'/news' }) } } }
從【關于我們】到【賬戶】,點擊按鈕跳轉,進入【新聞】,此時點擊瀏覽器的后退,發現并不會回到【賬戶】,而是回到【關于我們】。
當使用go方法時,可以在history記錄中向前或向后跳轉。也就是說,通過go方法可以在已經存儲的history路由歷史中前進后退。
//在歷史記錄中前進一步,等同于 history.forward() this.$router.go(1); //后退一步,等同于history.back() this.$router.go(-1); //前進兩步記錄 this.$router.go(2);
1.$router對象是全局路由的實例,是VueRouter構造方法的實例。是路由操作對象,可以添加或跳轉路由,替換路由等。
2.$route對象表示當前的路由信息,包含了當前 URL 解析得到的信息。包含當前的路徑,參數,query對象等。
在某些時候,生成的路由URL地址可能會很長,在使用中可能會顯得有些不便。這個時候通過一個名稱來標識路由會更方便一些。
const routes = [ { path: '/about',name:'aa', component: About } ]
使用命名路由之后,在使用router-link的to屬性跳轉路由的時候傳一個對象,跳轉到指定的路由地址上。
<router-link :to="{name:'aa'}">關于我們</router-link>
當打開一個頁面時,整個頁面可能是由多個Vue組件構成的。例如,一般后端管理首頁可能是由sidebar(側導航),header(頂部導航)和main(主內容)這三個Vue組件構成的。此時,通過Vue Router構建路由信息時,如果一個URL只能對應一個Vue組件,整個頁面將無法正確顯示。
通過router-view標簽,就可以指定組件渲染顯示到什么位置。因此,當需要在一個頁面上顯示多個組件的時候,就需要在頁面中添加多個router-view標簽。
那么,是不是可以通過一個路由對應多個組件,然后按需渲染到不同的【router-view】標簽上呢?默認情況下不能,當我們將一個路由對象對應到多個組件時,不管有多少個【router-view】標簽,程序都會將第一個組件渲染到所有的【router-view】標簽上。
那怎么辦呢?需要實現的是一個路由信息可以通過設計者的需求去渲染到頁面中指定的router-view標簽,這可以通過Vue Router命名視圖的方式來實現。
命名視圖與命名路由的實現方式相似。命名視圖通過在【router-view】標簽上設定name屬性,然后再構建路由與組件的對應關系時,以一種【name:component】的形式構造出一個組件對象,從而指明在哪個【router-view】標簽上加載什么組件。
1.三個組件的樣式布局
.container{ height: 500px; } .top { background-color:beige; width: 100%; height: 80px; } .left{ float: left; width: 20%; height: 100%; background-color: burlywood; } .right{ float: left; width: 80%; height: 100%; background-color: aquamarine; }
2.html代碼部分
const header = { template: '<div class="header"> header </div>' } const sidebar = { template: '<div class="sidebar">sidebar</div>' } const main = { template: '<div class="main"> main </div>' }
3.定義路由跳轉的組件模板
const header = { template: '<div class="header"> header </div>' } const sidebar = { template: '<div class="sidebar">sidebar</div>' } const main = { template: '<div class="main"> main </div>' }
4.定義路由信息
const routes = [{ path: '/', //一個路由對應多個組件 components: { default: header,//指定什么router-view顯示對應的組件,即指明是在哪個 router-view 標簽上加載什么組件。 sidebar: sidebar,//格式name:component,name為router-view的name main: main } }]
完整代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="js/vue.js"></script> <script src="js/vue-router.js"></script> <style> .container{ height: 500px; } .top { background-color:beige; width: 100%; height: 80px; } .left{ float: left; width: 20%; height: 100%; background-color: burlywood; } .right{ float: left; width: 80%; height: 100%; background-color: aquamarine; } </style> <body> <div id="app"> <div class="top"> <!-- 在 router-view 中,默認的 name 屬性值為 default --> <router-view></router-view> </div> <div class="container"> <div class="left"> <router-view name="sidebar"></router-view> </div> <div class="right"> <router-view name="main"></router-view> </div> </div> </div> <template id="sidebar"> <div class="sidebar"> sidebar </div> </template> <script> // 1、定義路由跳轉的組件模板 const header = { template: '<div class="header"> header </div>' } const sidebar = { template: '#sidebar' } const main = { template: '<div class="main"> main </div>' } // 2、定義路由信息 const routes = [{ path: '/', //一個路由對應多個組件 components: { default: header,//指定什么router-view顯示對應的組件,即指明是在哪個 router-view 標簽上加載什么組件。 sidebar: sidebar,//格式name:component,name為router-view的name main: main } }] const router = new VueRouter({ routes }) // 3、掛載到當前 Vue 實例上 const vm = new Vue({ el: '#app', data: {}, methods: {}, router: router }); </script> </body> </html>
在前面所講路由傳遞參數的辦法中,不管是query傳參還是param傳參,最終都是通過this.$route屬性獲取參數信息,如$route.query.name或$route.params.name
這意味著組件和路由耦合到了一塊,所有需要獲取參數值的地方都需要加載VueRouter。那么如何實現組件與路由的解耦呢?
在之前學習組件相關知識時,我們知道可以通過組件的props選項來實現子組件接受父組件傳遞的值。在Vue Router中,可以通過使用組件的props選項來進行組件與路由之間的解耦。
1.在定義路由規則時,指定props的屬性為true。
```bash //定義路由 const router = new VueRouter({ routes: [{ //定義路由 path: '/myRouter/:id', //路由規則通過占位符指明傳遞的參數為id,同時id要為上面組件props選項中有的值 component: mycomp, props: true //此處props要設置為true,即可以實現組件與Vue Router之間的解耦 }] })
2.在定義組件時,指定props接受的參數
//定義組件 const mycomp = { props: ['id'], //此處沒有通過$route.params.id方式獲取參數id,也就不需要router實例 template: '<h4>組件獲取到了路由傳遞的參數:{{id}},但此處并沒有通過$route去獲取。 </h4>' / }
完整核心代碼如下:
<style> .container { background-color:blanchedalmond; margin-top: 10px; width: 600px; height: 300px; } </style> <body> <div id="app"> <button type="button" @click="goMethod">路由與組件解綁示例1</button> <div class="container"> <router-view></router-view> </div> </div> <script> //定義組件 const mycomp = { props: ['id'], template: '<h4>組件獲取到了路由傳遞的參數:{{id}},但此處并沒有通過$route去獲取。 </h4>' //此處沒有通過$route.params.id方式獲取參數id,也就不需要router實例 } //定義路由 const router = new VueRouter({ routes: [{ //定義路由 path: '/myRouter/:id', //路由規則通過占位符指明傳遞的參數為id,同時id要為上面組件props選項中有的值 component: mycomp, props: true //此處props要設置為true,即可以實現組件與Vue Router之間的解耦 }] }) const vm = new Vue({ el: '#app', data: {}, methods: { goMethod() { //該方法實現路由跳轉,跳轉到myRouter,并傳入參數123 this.$router.push({ path: '/myRouter/123' //param方式傳參 }) } }, router }) </script> </body>
需要注意的是,該方法要求路由傳遞參數方式一定為param方式。
在將路由規則的props屬性定義為對象后,不管路由參數中傳遞的是什么值,最終獲取的都是對象中的值。同時,需要注意的是,props中的屬性值必須是靜態的,固定的。
上述案例修改下定義路由部分的代碼
//定義路由 const router = new VueRouter({ routes: [{ //定義路由 path: '/myRouter/:id', //路由規則通過占位符指明傳遞的參數為id,同時id要為上面組件props選項中有的值 component: mycomp, props:{ id:'123' //組件獲取到的是這里的值 } }] })
與上面案例相比,html與js沒有變化,只需要修改下js部分
//定義組件 const mycomp = { props: ['id'], template: '<h4>組件獲取到了路由傳遞的參數:{{id}},但此處并沒有通過$route去獲取。 </h4>' } //定義路由 const router = new VueRouter({ routes: [{ //定義路由 path: '/myRouter/:id', //路由規則通過占位符指明傳遞的參數為id,同時id要為上面組件props選項中有的值 component: mycomp, props:{ id:'123' //組件獲取到的是這里的值 } }] }) const vm = new Vue({ el: '#app', data: {}, methods: { goMethod() { //該方法實現路由跳轉,跳轉到myRouter this.$router.push({ path: '/myRouter/123456'//param方式傳參,隨便寫參數,但是必須有 }) } }, router })
在對象模式中,只能接受靜態的props屬性值。而使用函數模式之后,就可以對靜態值做數據的進一步交工,或者是與路由傳遞參數的值進行結合。
js部分代碼修改如下
//定義組件 const mycomp = { props: ['id', 'name'], template: '<h4>組件獲取到了路由傳遞的參數:{{id}}——{{name}},但此處并沒有通過$route去獲取。 </h4>' } //定義路由 const router = new VueRouter({ routes: [{ //定義路由 path: '/myRouter', component: mycomp, props: route => ({ id: route.query.id,//獲取到通過路由傳遞的參數,這個就可以是動態的 name: 'zhangsan'//這個是靜態的 }) }] }) const vm = new Vue({ el: '#app', data: {}, methods: { goMethod() { //該方法實現路由跳轉,跳轉到myRouter this.$router.push({ path: '/myRouter?id=123'//query方式傳參 }) } }, router })
到此,相信大家對“vue獲取參數的方式有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。