路由可向路由匹配的组件传递参数,不一样状况
向组件传递不一样的参数,从而实现组件的复用。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) }, }