路由可向路由匹配的組件傳遞參數,不一樣狀況
向組件傳遞不一樣的參數,從而實現組件的複用。css
和路由匹配的組件能夠在組件中使用 $route
獲取路由上的參數:html
:
、params
和query
vue
:
在路徑傳遞參數{ path: "/argu/:id/book", name: "argu", component: () => import("@/views/ArguPage") }
路徑
中的一部分是參數,必須
傳遞該參數:web
<!--路徑跳轉--> <router-link to="/argu/123/book">path跳轉</router-link> <!--路由名跳轉--> <router-link :to="{name:'argu',params:{id:'test'}}" tag="button">name+params跳轉</router-link> <!--獲取參數--> <h1>{{$route.params.id}}</h1><!--params的名字路徑中的的參數名一致-->
此時 path
+ parmas
傳遞參數,params
會被忽略。vue-router
params
+name
傳遞參數路由:服務器
{ path: "/argu", name: "argu", component: () => import("@/views/ArguPage") }
跳轉方式是 name
+params
+(query),經過path
跳轉,params 會被忽略。異步
<router-link :to="{name:'argu', params:{name:'hangge'}}"> 跳轉到 hello </router-link> // path + params ,params 會被忽略,由於路徑中沒有定義參數 <router-link :to="{path:'/argu', params:{name:'hangge'}}"> 跳轉到 hello </router-link>
query 參數參數,表現爲查詢字符串,和localtion.serach
同樣的。async
不須要先在路徑中先定義,可經過path
、path
+query
或者 name
+ query
傳遞參數。函數
<router-link to="/argu?queryName=value">跳轉到 hello</router-link> <router-link :to="{path:'/argu',query:{queryName:value}}">跳轉到 argu</router-link> <router-link :to="{name:'argu',query:{queryName:value}}">跳轉到 argu</router-link> <h1>{{ $route.query.queryName }}</h1>
函數傳遞 queryflex
// 主要是 $router 不是 $route go() { this.$router.push({ name: 'argu', query: { queryName: "你好" } }) } }
可是這樣使得 $route
和組件耦合在一塊兒,不方便組件的複用,若是能將路由中的參數傳遞到 組件的props
就行了,偏偏是能夠這樣設置的。
params
路由傳參數的三種方式:
{ path: '/user/:id', component: User, props: true //代表 將 id 做爲 proos 傳遞到匹配的組件 User 中。 }
User 中定義 props 接收 id:
export default { props:{ id:{ type:String, default:'jackzhou'//默認值 } } }
將路由的 props
屬性設置一個對象,也可在組件中獲取到該值,這種方式每每用於傳遞靜態值,即 name 值不會變化。
路由對象:
{ name: 'home', alias:'/home_page', path: '/', props:{name:'jack jack'}, component: Home }
Home 組件:
props:{ name:{ type:String, } }
以上兩種方式,params 參數的名字必須和組件中的props 屬性名字相同,若是想對 params 進行改造後傳遞到組件,就可將 props
設置成函數,在函數內獲取路由中的 params 或者 query,或者其餘屬性值,對其進行處理後再傳遞給組件。
注意:這種方式函數必須返回一個對象。
路由:
{ name: 'about', path: '/about/:years', //params 有一個參數 years props:(route) { const now = new Date() return { // 將 years 改形成 name name: (now.getFullYear() + parseInt(route.params.years)) + '!' } }, component: () => import('@/views/AboutPage'), }
組件中的 props:
props: { name: { type: String } }
命名視圖的路由,要爲每一個命名視圖添加 props
:
{ path:'/name/:view', name:'name_view', components:{ default:()=>import('@/views/ChildPage'), sister:()=>import('@/views/SisterPage'), brother:()=>import('@/views/BrotherPage'), }, props:{ default:true, sister:false, brother:(route)=>({view:route.params.view.toUpperCase()}) } }
{% raw %}
<p class="codepen" data-height="573" data-theme-id="0" data-default-tab="js,result" data-user="JackZhouMine" data-slug-hash="JqBzWE" style="height: 573px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="route 的 params 傳遞組件">
<span>See the Pen
route 的 params 傳遞組件 by JackZhouMine (@JackZhouMine)
on CodePen.</span>
</p>
<script async src="https://static.codepen.io/ass...;></script>
{% endraw %}
路由配置裏有一個屬性 mode
,默認值是 hash
,以hash來模擬一個url,url改變時,頁面不會從新加載。
先使用普通模式,可將 mode
設置成 history
,這種模式會使用 history.pushSate
來完成url跳轉而頁面不會從新加載。這種模式須要服務器設置一下。
使用 history 模式,由於web應用每每是單頁應用,當用戶訪問一個不存在的路徑時,須要提供一個後備頁面。
在路由配置的最後增長一個404路由:
{ path:'*', component:NotFoundPage// 前面沒有匹配的路由,最後會匹配該路由。 }
可在路由對象中配置 meta
屬性,meta 是一個對象。
好比,根據不一樣頁面顯示不一樣的 title。
{ name: "about", path: "/about", meta: { title: "關於" }, component: () => import("@/views/AboutPage") }
在路由配置文件中,設置各個頁面的 title:
const router= new Router({ routes }) router.beforeEach((to,from,next)=>{ //setTitle 函數用於設置頁面標題 to.meta&&setTitle(to.meta.title) //這是簡化if語句的簡寫 console.table(to) console.table(from) next() }) export default router
const router = new Router({ { path:"/", name:"heom_page" component:Home, //路由獨享守衛 beforeEnter:(to,from,next)=>{ //處理邏輯 next() } } }) //每次路由進入都會調用 router.beforeEach((to,from,next)=>{ //處理邏輯,好比登陸判斷,可跳轉到任意頁面 //不要忘記調用 next,不調用 next,頁面不會跳轉 })
//路由跳轉以後作一些操做,好比去掉登陸樣式 router.afterEach((to,form)=>{ //邏輯處理 })
只在匹配某個路由時執行。
beforeRouteEnter
, 組件建立以前調用,組件不具有this
;beforeRouteUpdate
,路由更新,而組件被複用時調用,可以使用this
;beforeRouteLeave
,離開路由時調用,可以使用this
。
export default{ name:'Home', data(){ return {} }, /** * 組件內路由守衛 * 1. 該函數在路由進入時執行 * 2. 此時 組件還未渲染,不可用 this,當可在 next 中用 vm * 3. next 晚於 mounted 執行,next 以前的代碼,早於beforeCreate * 執行 * 4. 最後須要調用 next 使得路由跳轉 */ beforeRouteEnter(to, from, next) { console.log("①,home 組件內路由守衛,beforeRouteEnter"); // next 晚於 mounted 執行,next 以前的代碼,早於beforeCreate 執行 next((vm)=>{ console.log('vm') console.log(vm)//有值 console.log('this') console.log(this)// undefined console.log('②,home 組件內路由守衛,beforeRouteEnter'); }); }, /** * 組件內路由守衛 * 1. 該函數在路由離開時執行,最早調用,而後在調用全局守衛,再調用 * beforeDestroy * 2. 此時,該路由守衛所在組件已渲染,可用 this * 3. 最後須要調用 next 使得路由跳轉 */ beforeRouteLeave(to, from, next) { console.log("①,home 組件內路由守衛,beforeRouteLeave"); let leave = confirm("你肯定要離開 home 頁嗎?"); if (leave) { // console.log(to.name, from.name); // console.log(this); next(() => { console.log('②,home 組件內路由守衛,beforeRouteLeave'); }); //給 next 傳遞 false ,路由不會跳轉 } else { next(false); } }, /* * 當路由發生變化,而組件被複用時調用 * 1. 此時該複用組件已被渲染,可用 this * 2. 須要調用 next,組件才能渲染 */ beforeRouteUpdate(to, from, next) { console.log('①,argu,組件內路由守衛,beforeRouteUpdate'); next(() => { console.log('next,argu,組件內路由守衛,beforeRouteUpdate'); }); }, beforeCreate() { console.log('beforeCreate') }, created() { console.log('created') }, beforeMount() { console.log('beforeMount') }, mounted() { console.log('mounted') }, beforeUpdate() { console.log('beforeUpdate') }, updated() { console.log('updated') }, beforeDestroy() { console.log('beforeDestroy') }, destroyed() { console.log('destroyed') } }
路由全過程:
全局前置守衛
beforeEach全局解析守衛
beforeResolve (導航被確認以前,組件內守衛和異步路由組件被解析以後,調用 beforeResolve)全局後置守衛
afterEachnext
在mounted
以後被調用。能夠給路由匹配的組件設置過渡效果,讓頁面平滑地顯示,提高用戶體驗。
須要用到 transition
標籤,若是有多個視圖須要過渡,則用 transition-group
。
<transition-group name='router-view'> <!-- 視圖渲染組件,該組件內不須要房子任何內容,可寫成只閉合標籤--> <router-view key='default'/> <!-- 有多個路由視圖須要匹配,則用命名視圖 --> <router-view key='sister' name="sister"></router-view> <router-view key='brother' name="brother"></router-view> </transition-group>
css 過渡效果:
.router-view-enter{ opacity: 0; } .router-view-enter-active{ transition: opacity 1s ease; } .router-view-enter-to{ opacity: 1; } .router-view-leave{ opacity: 1; } .router-view-leave-active{ transition: opacity 1s ease; } .router-view-leave-to{ opacity: 0; }
這些設置,每一個頁面的效果都是同樣的,要爲不一樣的頁面設置不一樣的效果,可用路由傳遞相應的參數來,讓動態綁定到 transition 的 name 屬性上。
或者監聽路由變化:
watch: { '$route'(to){ console.log(to); to.params&&to.params.view&&(this.effect = to.params.view) }, }