vue 路由進階

vue 路由進階

路由可向路由匹配的組件傳遞參數,不一樣狀況向組件傳遞不一樣的參數,從而實現組件的複用。css

路由向組件傳遞參數

和路由匹配的組件能夠在組件中使用 $route 獲取路由上的參數:html

傳參方式

:paramsqueryvue

:在路徑傳遞參數

{
	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 參數

query 參數參數,表現爲查詢字符串,和localtion.serach同樣的。函數

不須要先在路徑中先定義,可經過pathpath+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 就行了,偏偏是能夠這樣設置的。

props 接收路由的 params

路由傳參數的三種方式:

  1. 布爾模式
{
    path: '/user/:id', 
    component: User, 
    props: true //代表 將 id 做爲 proos 傳遞到匹配的組件 User 中。
}
複製代碼

User 中定義 props 接收 id:

export default {
	props:{
		id:{
			type:String,
			default:'jackzhou'//默認值
		}
	}
}
複製代碼
  1. 對象模式

將路由的 props 屬性設置一個對象,也可在組件中獲取到該值,這種方式每每用於傳遞靜態值,即 name 值不會變化。

路由對象:

{
	name: 'home',
	alias:'/home_page',
	path: '/',
	props:{name:'jack jack'},
	component: Home
}
複製代碼

Home 組件:

props:{
	name:{
		type:String,
	}
}
複製代碼
  1. 函數模式

以上兩種方式,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 %}

HTML5 History 模式

路由配置裏有一個屬性 mode ,默認值是 hash,以hash來模擬一個url,url改變時,頁面不會從新加載。

先使用普通模式,可將 mode 設置成 history,這種模式會使用 history.pushSate 來完成url跳轉而頁面不會從新加載。這種模式須要服務器設置一下

使用 history 模式,由於web應用每每是單頁應用,當用戶訪問一個不存在的路徑時,須要提供一個後備頁面。

在路由配置的最後增長一個404路由:

{
	path:'*',
	component:NotFoundPage// 前面沒有匹配的路由,最後會匹配該路由。
}
複製代碼

meta 元信息

可在路由對象中配置 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
複製代碼

導航守衛

全局守衛

  1. 全局前置守衛
const router = new Router({
    {
        path:"/",
        name:"heom_page"
        component:Home,
        //路由獨享守衛
        beforeEnter:(to,from,next)=>{
            //處理邏輯
            next()
        }
    }
})
//每次路由進入都會調用
router.beforeEach((to,from,next)=>{
    //處理邏輯,好比登陸判斷,可跳轉到任意頁面
    //不要忘記調用 next,不調用 next,頁面不會跳轉
})
複製代碼
  1. 後置鉤子
//路由跳轉以後作一些操做,好比去掉登陸樣式
router.afterEach((to,form)=>{
    //邏輯處理
})
複製代碼
  1. 路由獨享守衛 只在匹配某個路由時執行。

  2. 組件內守衛

beforeRouteEnter, 組件建立以前調用,組件不具有thisbeforeRouteUpdate,路由更新,而組件被複用時調用,可以使用thisbeforeRouteLeave,離開路由時調用,可以使用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')
	}
}
複製代碼

路由全過程:

  1. 導航被觸發
  2. 離開頁面(失活的組件)裏調用離開守衛 beforeRouteLeave
  3. 調用全局前置守衛 beforeEach
  4. 在重用的組件裏調用 beforeRouteUpdate (非重用組件,沒有這個步驟)
  5. 調用路由獨享守衛 beforeEnter
  6. 解析異步路由組件
  7. 在進入頁面(激活組件)調用 beforeRouteEnter
  8. 調用全局解析守衛 beforeResolve (導航被確認以前,組件內守衛和異步路由組件被解析以後,調用 beforeResolve)
  9. 導航被確認(何時被確認,所有鉤子執行完了,是被確認的)
  10. 調用全局後置守衛 afterEach
  11. 觸發 DOM 更新
  12. 在 vue 實例中(此時頁面解析完畢了嗎?是的)調用 beforeRouterEnter 守衛裏傳給 next 的回調。nextmounted以後被調用。

過渡效果

能夠給路由匹配的組件設置過渡效果,讓頁面平滑地顯示,提高用戶體驗。 須要用到 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)
	},
}
複製代碼

參考

Vue.js - 路由 vue-router 的使用詳解2(參數傳遞)

相關文章
相關標籤/搜索