路由可向路由匹配的組件傳遞參數,不一樣狀況
向組件傳遞不一樣的參數,從而實現組件的複用。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
同樣的。函數
不須要先在路徑中先定義,可經過path
、path
+query
或者 name
+ query
傳遞參數。flex
<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>
複製代碼
函數傳遞 queryui
// 主要是 $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 %}
See the Pen route 的 params 傳遞組件 by JackZhouMine (@JackZhouMine) on CodePen.
{% 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)
},
}
複製代碼